mirror of
https://github.com/kilyabin/psysonic.git
synced 2026-07-21 22:15:40 +00:00
fix(pr-review): address review findings for music folder filter
- Sidebar.tsx: title={} → data-tooltip + data-tooltip-pos="right" on
scope subtitle (CLAUDE.md rule: never use native title= for tooltips)
- authStore.ts: merge two set() calls in setMusicFolders into one atomic
update — avoids double render on folder list arrival
- locales (all 7): remove dead libraryScopeHint key (defined but never
rendered in any component)
- Genres.tsx: remove musicLibraryFilterVersion from effect deps —
getGenres is intentionally not folder-scoped, re-fetching on filter
change was a no-op waste
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -159,7 +159,7 @@ export default function Sidebar({
|
|||||||
<div className="nav-library-scope-text">
|
<div className="nav-library-scope-text">
|
||||||
<span className="nav-library-scope-title">{t('sidebar.library')}</span>
|
<span className="nav-library-scope-title">{t('sidebar.library')}</span>
|
||||||
{selectedFolderName ? (
|
{selectedFolderName ? (
|
||||||
<span className="nav-library-scope-subtitle" title={selectedFolderName}>
|
<span className="nav-library-scope-subtitle" data-tooltip={selectedFolderName} data-tooltip-pos="right">
|
||||||
{selectedFolderName}
|
{selectedFolderName}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export const deTranslation = {
|
|||||||
playlists: 'Playlists',
|
playlists: 'Playlists',
|
||||||
radio: 'Internetradio',
|
radio: 'Internetradio',
|
||||||
libraryScope: 'Bibliotheksumfang',
|
libraryScope: 'Bibliotheksumfang',
|
||||||
libraryScopeHint: 'Gesamten Server-Katalog oder nur einen Medienordner durchsuchen.',
|
|
||||||
allLibraries: 'Alle Bibliotheken',
|
allLibraries: 'Alle Bibliotheken',
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export const enTranslation = {
|
|||||||
playlists: 'Playlists',
|
playlists: 'Playlists',
|
||||||
radio: 'Internet Radio',
|
radio: 'Internet Radio',
|
||||||
libraryScope: 'Library scope',
|
libraryScope: 'Library scope',
|
||||||
libraryScopeHint: 'Browse either your whole server catalog or a single media folder.',
|
|
||||||
allLibraries: 'All libraries',
|
allLibraries: 'All libraries',
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export const frTranslation = {
|
|||||||
playlists: 'Playlists',
|
playlists: 'Playlists',
|
||||||
radio: 'Radio Internet',
|
radio: 'Radio Internet',
|
||||||
libraryScope: 'Portée de la bibliothèque',
|
libraryScope: 'Portée de la bibliothèque',
|
||||||
libraryScopeHint: 'Parcourir tout le catalogue du serveur ou un seul dossier média.',
|
|
||||||
allLibraries: 'Toutes les bibliothèques',
|
allLibraries: 'Toutes les bibliothèques',
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export const nbTranslation = {
|
|||||||
playlists: 'Spillelister',
|
playlists: 'Spillelister',
|
||||||
radio: 'Internettradio',
|
radio: 'Internettradio',
|
||||||
libraryScope: 'Biblioteksomfang',
|
libraryScope: 'Biblioteksomfang',
|
||||||
libraryScopeHint: 'Vis hele serverkatalogen eller én mediemappe.',
|
|
||||||
allLibraries: 'Alle biblioteker',
|
allLibraries: 'Alle biblioteker',
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export const nlTranslation = {
|
|||||||
playlists: 'Playlists',
|
playlists: 'Playlists',
|
||||||
radio: 'Internetradio',
|
radio: 'Internetradio',
|
||||||
libraryScope: 'Bibliotheekbereik',
|
libraryScope: 'Bibliotheekbereik',
|
||||||
libraryScopeHint: 'Doorzoek de hele servercatalogus of één mediabibliotheek.',
|
|
||||||
allLibraries: 'Alle bibliotheken',
|
allLibraries: 'Alle bibliotheken',
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export const ruTranslation = {
|
|||||||
playlists: 'Плейлисты',
|
playlists: 'Плейлисты',
|
||||||
radio: 'Онлайн-радио',
|
radio: 'Онлайн-радио',
|
||||||
libraryScope: 'Область медиатеки',
|
libraryScope: 'Область медиатеки',
|
||||||
libraryScopeHint: 'Показывать весь каталог сервера или только одну медиапапку.',
|
|
||||||
allLibraries: 'Все библиотеки',
|
allLibraries: 'Все библиотеки',
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export const zhTranslation = {
|
|||||||
playlists: '播放列表',
|
playlists: '播放列表',
|
||||||
radio: '网络电台',
|
radio: '网络电台',
|
||||||
libraryScope: '资料库范围',
|
libraryScope: '资料库范围',
|
||||||
libraryScopeHint: '浏览整个服务器目录或仅单个媒体文件夹。',
|
|
||||||
allLibraries: '所有资料库',
|
allLibraries: '所有资料库',
|
||||||
},
|
},
|
||||||
home: {
|
home: {
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ const SCROLL_KEY = 'genres-scroll';
|
|||||||
export default function Genres() {
|
export default function Genres() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const musicLibraryFilterVersion = useAuthStore(s => s.musicLibraryFilterVersion);
|
|
||||||
const [genres, setGenres] = useState<SubsonicGenre[]>([]);
|
const [genres, setGenres] = useState<SubsonicGenre[]>([]);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
@@ -61,7 +60,7 @@ export default function Genres() {
|
|||||||
setGenres(sorted);
|
setGenres(sorted);
|
||||||
})
|
})
|
||||||
.finally(() => setLoading(false));
|
.finally(() => setLoading(false));
|
||||||
}, [musicLibraryFilterVersion]);
|
}, []); // getGenres is not folder-scoped — no dep on musicLibraryFilterVersion
|
||||||
|
|
||||||
// Restore scroll position after genres are rendered
|
// Restore scroll position after genres are rendered
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
+10
-8
@@ -243,15 +243,17 @@ export const useAuthStore = create<AuthState>()(
|
|||||||
setHotCacheDownloadDir: (v) => set({ hotCacheDownloadDir: v }),
|
setHotCacheDownloadDir: (v) => set({ hotCacheDownloadDir: v }),
|
||||||
|
|
||||||
setMusicFolders: (folders) => {
|
setMusicFolders: (folders) => {
|
||||||
set({ musicFolders: folders });
|
|
||||||
const sid = get().activeServerId;
|
const sid = get().activeServerId;
|
||||||
if (!sid) return;
|
set(s => {
|
||||||
const f = get().musicLibraryFilterByServer[sid];
|
const f = sid ? s.musicLibraryFilterByServer[sid] : undefined;
|
||||||
if (f && f !== 'all' && !folders.some(x => x.id === f)) {
|
const invalidFilter = f && f !== 'all' && !folders.some(x => x.id === f);
|
||||||
set(s => ({
|
return {
|
||||||
musicLibraryFilterByServer: { ...s.musicLibraryFilterByServer, [sid]: 'all' },
|
musicFolders: folders,
|
||||||
}));
|
...(sid && invalidFilter
|
||||||
}
|
? { musicLibraryFilterByServer: { ...s.musicLibraryFilterByServer, [sid]: 'all' } }
|
||||||
|
: {}),
|
||||||
|
};
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setMusicLibraryFilter: (folderId) => {
|
setMusicLibraryFilter: (folderId) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user