fix(tracklist): split multi-artist tracks and fix reset button style

- Use OpenSubsonic `artists[]` array to render each artist separately
  with · separator; artists with an ID are clickable, others plain text
- Fall back to single artist (artistId/artist) on non-OpenSubsonic servers
- Settings reset-to-defaults buttons changed from btn-ghost to btn-danger

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-04-10 14:37:29 +02:00
parent b0081e3d7a
commit 084543e59b
2 changed files with 19 additions and 10 deletions
+17 -8
View File
@@ -227,18 +227,27 @@ export default function AlbumTrackList({
<span className="track-title">{song.title}</span> <span className="track-title">{song.title}</span>
</div> </div>
); );
case 'artist': case 'artist': {
const artistRefs = song.artists && song.artists.length > 0
? song.artists
: [{ id: song.artistId, name: song.artist }];
return ( return (
<div key="artist" className="track-artist-cell"> <div key="artist" className="track-artist-cell">
<span {artistRefs.map((a, i) => (
className={`track-artist${song.artistId ? ' track-artist-link' : ''}`} <React.Fragment key={a.id ?? a.name ?? i}>
style={{ cursor: song.artistId ? 'pointer' : 'default' }} {i > 0 && <span className="track-artist-sep">&nbsp;·&nbsp;</span>}
onClick={e => { if (song.artistId) { e.stopPropagation(); navigate(`/artist/${song.artistId}`); } }} <span
> className={`track-artist${a.id ? ' track-artist-link' : ''}`}
{song.artist} style={{ cursor: a.id ? 'pointer' : 'default' }}
</span> onClick={e => { if (a.id) { e.stopPropagation(); navigate(`/artist/${a.id}`); } }}
>
{a.name ?? song.artist}
</span>
</React.Fragment>
))}
</div> </div>
); );
}
case 'favorite': case 'favorite':
return ( return (
<div key="favorite" className="track-star-cell"> <div key="favorite" className="track-star-cell">
+2 -2
View File
@@ -1437,7 +1437,7 @@ export default function Settings() {
</div> </div>
<div className="settings-card"> <div className="settings-card">
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '12px' }}> <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '12px' }}>
<button className="btn btn-ghost" style={{ fontSize: 12 }} onClick={() => { kb.resetToDefaults(); setListeningFor(null); }}> <button className="btn btn-danger" style={{ fontSize: 12 }} onClick={() => { kb.resetToDefaults(); setListeningFor(null); }}>
{t('settings.shortcutsReset')} {t('settings.shortcutsReset')}
</button> </button>
</div> </div>
@@ -1523,7 +1523,7 @@ export default function Settings() {
</p> </p>
<div className="settings-card"> <div className="settings-card">
<div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '12px' }}> <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '12px' }}>
<button className="btn btn-ghost" style={{ fontSize: 12 }} onClick={() => { gs.resetAll(); setListeningForGlobal(null); }}> <button className="btn btn-danger" style={{ fontSize: 12 }} onClick={() => { gs.resetAll(); setListeningForGlobal(null); }}>
{t('settings.shortcutsReset')} {t('settings.shortcutsReset')}
</button> </button>
</div> </div>