From 6b3e809d12cce3375758aea850fb122db8756ed8 Mon Sep 17 00:00:00 2001 From: Psychotoxical Date: Sat, 18 Apr 2026 22:58:51 +0200 Subject: [PATCH] feat(device-sync): show album artist in both panels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds optional artist field to DeviceSyncSource and renders it inline next to the album name ("Album · Artist") in the on-device list. BrowserRow (left panel) uses the same inline format so albums in search, random picks and under expanded artists all read consistently. Playlists unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/pages/DeviceSync.tsx | 15 ++++++++++----- src/store/deviceSyncStore.ts | 2 ++ src/styles/components.css | 10 ++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/pages/DeviceSync.tsx b/src/pages/DeviceSync.tsx index 6ba610c2..3d368900 100644 --- a/src/pages/DeviceSync.tsx +++ b/src/pages/DeviceSync.tsx @@ -872,7 +872,7 @@ export default function DeviceSync() { {activeTab === 'albums' && (search.trim() ? albumSearchResults : randomAlbums).map(al => ( s.id === al.id) && !pendingDeletion.includes(al.id)} - onToggle={() => handleToggleSource({ type: 'album', id: al.id, name: al.name })} /> + onToggle={() => handleToggleSource({ type: 'album', id: al.id, name: al.name, artist: al.artist })} /> ))} {activeTab === 'artists' && filteredArtists.map(ar => ( @@ -896,7 +896,7 @@ export default function DeviceSync() { s.id === al.id) && !pendingDeletion.includes(al.id)} indent - onToggle={() => handleToggleSource({ type: 'album', id: al.id, name: al.name })} /> + onToggle={() => handleToggleSource({ type: 'album', id: al.id, name: al.name, artist: al.artist || ar.name })} /> )) } @@ -990,7 +990,10 @@ export default function DeviceSync() { onChange={() => toggleChecked(s.id)} disabled={status === 'deletion'} /> - {s.name} + + {s.name} + {s.artist && · {s.artist}} + {s.type} {status === 'synced' && } @@ -1272,8 +1275,10 @@ function BrowserRow({ name, meta, selected, onToggle, indent }: { {selected ? : } - {name} - {meta && {meta}} + + {name} + {meta && · {meta}} + ); } diff --git a/src/store/deviceSyncStore.ts b/src/store/deviceSyncStore.ts index 0b819b42..83b2dbae 100644 --- a/src/store/deviceSyncStore.ts +++ b/src/store/deviceSyncStore.ts @@ -5,6 +5,8 @@ export interface DeviceSyncSource { type: 'album' | 'playlist' | 'artist'; id: string; name: string; + /** Album artist — only set when type === 'album'. Shown as a subtitle in the device list. */ + artist?: string; } interface DeviceSyncState { diff --git a/src/styles/components.css b/src/styles/components.css index 696938e3..c5948f0d 100644 --- a/src/styles/components.css +++ b/src/styles/components.css @@ -8478,6 +8478,16 @@ html.no-compositing .fsr-lyric-line.fsrl-active .fsr-lyric-word.active { .device-sync-row-name { flex: 1; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.device-sync-row-artist { + color: var(--text-muted); + font-weight: 400; + margin-left: 0.2em; } .device-sync-device-row.checked { background: var(--accent-dim); }