diff --git a/CHANGELOG.md b/CHANGELOG.md index 34024b84..9a6e3128 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -142,6 +142,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * While a Navidrome public share queue is active, **Save Playlist** is hidden in the queue toolbar (share tracks cannot be saved to the server). **Load Playlist** stays available. * The queue **Share** button copies the original Navidrome `/share/{id}` page URL instead of a Psysonic magic-string queue payload. +### Player bar — build your own + +**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#1287](https://github.com/Psychotoxical/psysonic/pull/1287)** + +* **Settings → Personalisation → Player bar** now also hides the **stop button** and shows the **album name** under the artist (off by default; clicking it opens the album). The right-hand buttons — star rating, favorite, love, playback speed, equalizer, mini player — can be **dragged into any order** you like. +* The section is no longer behind **Advanced**. + ## Fixed ### Per-track covers when playing from a playlist diff --git a/src/config/settingsCredits.ts b/src/config/settingsCredits.ts index 1e4b7cf6..1bb41076 100644 --- a/src/config/settingsCredits.ts +++ b/src/config/settingsCredits.ts @@ -202,6 +202,7 @@ const CONTRIBUTOR_ENTRIES = [ 'Windows MSI bundle on dev/RC versions — numeric WiX mapping; album easter-egg import chunk (PR #1278)', 'Track lists — optional album cover thumbnails via standard cover pipeline; queue rows use playback scope (PR #1280)', 'Internet Radio — Web Audio EQ on HTML5 streams; presets apply without reconnect (PR #1284)', + 'Player bar — hideable stop button, optional album line, drag-reorderable action buttons (request: mikmik on Psysonic Discord, PR #1287)', ], }, { diff --git a/src/features/playback/components/playerBar/PlayerTrackInfo.tsx b/src/features/playback/components/playerBar/PlayerTrackInfo.tsx index 947671dd..ab31be43 100644 --- a/src/features/playback/components/playerBar/PlayerTrackInfo.tsx +++ b/src/features/playback/components/playerBar/PlayerTrackInfo.tsx @@ -73,6 +73,11 @@ export function PlayerTrackInfo({ const layoutItems = usePlayerBarLayoutStore(s => s.items); const isLayoutVisible = (id: PlayerBarLayoutItemId) => layoutItems.find(i => i.id === id)?.visible !== false; + const trackInfoMode = usePlayerBarLayoutStore(s => s.trackInfoMode); + // Radio has no album, and a preview shows the previewed track's own meta. + const albumLine = trackInfoMode === 'titleAlbum' && !isRadio && !showPreviewMeta + ? currentTrack?.album + : undefined; const offlineBrowseActive = useOfflineBrowseContext().active; const playerPolicy = offlineActionPolicy('playerBar', offlineBrowseActive); @@ -177,6 +182,14 @@ export function PlayerTrackInfo({ onClick={() => !isRadio && !showPreviewMeta && currentTrack?.artistId && navigate(`/artist/${currentTrack.artistId}`)} /> )} + {albumLine && ( + currentTrack?.albumId && navigate(`/album/${currentTrack.albumId}`)} + /> + )} {currentTrack && !isRadio && !showPreviewMeta && isLayoutVisible('starRating') && playerPolicy.canRate && ( ['playPauseBind']; @@ -36,24 +37,31 @@ export function PlayerTransportControls({ const autodjPhase = useAutodjTransitionUi(s => s.phase); const showAutodjTransition = isPlaying && !isPreviewing && scheduleRemaining == null && autodjPhase === 'mixing'; + // Hiding Stop leaves no dead end: while previewing, the primary button already + // renders as a stop control and ends the preview. + const showStop = usePlayerBarLayoutStore( + s => s.items.find(i => i.id === 'stop')?.visible !== false, + ); return (
- + {showStop && ( + + )}