From c39465dfad6bc4aa2252b7638efa9b1a67717033 Mon Sep 17 00:00:00 2001 From: Frank Stellmacher <171614930+Psychotoxical@users.noreply.github.com> Date: Fri, 5 Jun 2026 12:35:39 +0200 Subject: [PATCH] feat(sidebar): toggle to pin Now Playing to the top (#1000) * feat(sidebar): add toggle to pin Now Playing to the top The fixed Now Playing entry can now be pinned to the very top of the sidebar (above the Library label) instead of sitting above the bottom spacer. Adds a persisted `nowPlayingAtTop` setting (default off, so existing layouts are unchanged) and a toggle in the sidebar customizer next to the Mix-navigation split. The entry stays non-hideable and keeps its playing indicator in both positions. * i18n(settings): Now Playing-at-top toggle strings (9 locales) * docs(changelog): note Now Playing top toggle (#1000) --- CHANGELOG.md | 10 ++++++ src/components/Sidebar.tsx | 2 ++ src/components/settings/SidebarCustomizer.tsx | 16 +++++++++ src/components/sidebar/SidebarNavBody.tsx | 36 +++++++++++-------- src/locales/de/settings.ts | 2 ++ src/locales/en/settings.ts | 2 ++ src/locales/es/settings.ts | 2 ++ src/locales/fr/settings.ts | 2 ++ src/locales/nb/settings.ts | 2 ++ src/locales/nl/settings.ts | 2 ++ src/locales/ro/settings.ts | 2 ++ src/locales/ru/settings.ts | 2 ++ src/locales/zh/settings.ts | 2 ++ src/store/authDiscoveryActions.ts | 2 ++ src/store/authStore.ts | 1 + src/store/authStoreTypes.ts | 4 +++ 16 files changed, 75 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5654e296..586580e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.48.0] +## Added + +### Sidebar — pin Now Playing to the top + +**By [@Psychotoxical](https://github.com/Psychotoxical), PR [#1000](https://github.com/Psychotoxical/psysonic/pull/1000), suggested by [@PHLAK](https://github.com/PHLAK)** + +* New **Settings → Sidebar** toggle moves the "Now Playing" entry to the top of the sidebar instead of the bottom (off by default). + + + ## Changed ### Dependencies — npm and Rust refresh diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index bfa3e42d..da36c8c1 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -65,6 +65,7 @@ export default function Sidebar({ const sidebarItems = useSidebarStore(s => s.items); const setSidebarItems = useSidebarStore(s => s.setItems); const randomNavMode = useAuthStore(s => s.randomNavMode); + const nowPlayingAtTop = useAuthStore(s => s.nowPlayingAtTop); const luckyMixBase = useLuckyMixAvailable(); // Sidebar surfaces Lucky Mix as its own entry only in "separate" nav mode — // in hub mode it lives inside the Build-a-Mix landing page instead. @@ -227,6 +228,7 @@ export default function Sidebar({ handleNavRowPointerDown={handleNavRowPointerDown} isPlaying={isPlaying} hasNowPlayingTrack={!!currentTrack} + nowPlayingAtTop={nowPlayingAtTop} hasOfflineContent={hasOfflineContent} activeJobsCount={activeJobs.length} cancelAllDownloads={cancelAllDownloads} diff --git a/src/components/settings/SidebarCustomizer.tsx b/src/components/settings/SidebarCustomizer.tsx index b0ae97bb..17da0292 100644 --- a/src/components/settings/SidebarCustomizer.tsx +++ b/src/components/settings/SidebarCustomizer.tsx @@ -39,6 +39,8 @@ export function SidebarCustomizer() { itemsRef.current = items; const randomNavMode = useAuthStore(s => s.randomNavMode); const setRandomNavMode = useAuthStore(s => s.setRandomNavMode); + const nowPlayingAtTop = useAuthStore(s => s.nowPlayingAtTop); + const setNowPlayingAtTop = useAuthStore(s => s.setNowPlayingAtTop); const luckyMixBase = useLuckyMixAvailable(); const luckyMixAvailable = luckyMixBase && randomNavMode === 'separate'; @@ -138,6 +140,20 @@ export function SidebarCustomizer() { +