mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-22 14:35:41 +00:00
feat(albums): add 'Enqueue' option to album cover, context menu and multi-select toolbar (closes #253) (#256)
Per bcorporaal's request in #253: making a queue from multiple albums required either replacing the queue (Play) or going into each album detail page first. Three new entry points cover the common workflows: 1. Hover button on the album cover next to Play. Both buttons share the same accent style and size so the secondary action is just as readable as the primary — first attempt with a darker pill was hard to see and unbalanced the hover. 2. Context-menu entry "Enqueue Album" between "Open Album" and "Go to Artist". The i18n key already existed (was used by the album-song sub-context); just wiring up the action. 3. Multi-select toolbar in Albums.tsx: new "Enqueue (N)" button placed before "Add Offline" so power users selecting several albums no longer have to right-click. Plus a context-menu entry "Enqueue N Albums" for the same flow when a multi-album right-click happens anywhere else. All multi-album fetches use Promise.all(getAlbum(...)) — Navidrome handles parallel requests instantly (per memory note from PR #246). i18n: 4 new keys per locale (3 with pluralisation: contextMenu.enqueueAlbums, albums.enqueueSelected, albums.enqueueQueued). Co-authored-by: Psychotoxical <dev@psysonic.app> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
GitHub
parent
f7a721b7b1
commit
2318f9e07a
@@ -1649,6 +1649,12 @@ export default function ContextMenu() {
|
||||
<div className="context-menu-item" onClick={() => handleAction(() => navigate(`/album/${album.id}`))}>
|
||||
<Play size={14} /> {t('contextMenu.openAlbum')}
|
||||
</div>
|
||||
<div className="context-menu-item" onClick={() => handleAction(async () => {
|
||||
const albumData = await getAlbum(album.id);
|
||||
enqueue(albumData.songs.map(songToTrack));
|
||||
})}>
|
||||
<ListPlus size={14} /> {t('contextMenu.enqueueAlbum')}
|
||||
</div>
|
||||
<div className="context-menu-divider" />
|
||||
<div className="context-menu-item" onClick={() => handleAction(() => navigate(`/artist/${album.artistId}`))}>
|
||||
<User size={14} /> {t('contextMenu.goToArtist')}
|
||||
@@ -1751,6 +1757,14 @@ export default function ContextMenu() {
|
||||
{t('contextMenu.selectedAlbums', { count: albums.length })}
|
||||
</div>
|
||||
<div className="context-menu-divider" />
|
||||
<div className="context-menu-item" onClick={() => handleAction(async () => {
|
||||
// Parallel — Navidrome handles concurrent getAlbum requests fine.
|
||||
const results = await Promise.all(albums.map(a => getAlbum(a.id)));
|
||||
const allTracks = results.flatMap(r => r.songs.map(songToTrack));
|
||||
enqueue(allTracks);
|
||||
})}>
|
||||
<ListPlus size={14} /> {t('contextMenu.enqueueAlbums', { count: albums.length })}
|
||||
</div>
|
||||
<div
|
||||
className={`context-menu-item context-menu-item--submenu ${playlistSubmenuOpen && playlistSongIds[0] === `multi-album:${albumIds.join(',')}` ? 'active' : ''}`}
|
||||
data-playlist-trigger-id={`multi-album:${albumIds.join(',')}`}
|
||||
|
||||
Reference in New Issue
Block a user