support filter pinning on the genre detail list

This commit is contained in:
jeffvli
2026-01-30 21:42:17 -08:00
parent 4d60f5b8d9
commit 131e1ec11d
3 changed files with 69 additions and 13 deletions
@@ -2,22 +2,65 @@ import { Suspense, useMemo } from 'react';
import { useParams } from 'react-router';
import { AlbumListView } from '/@/renderer/features/albums/components/album-list-content';
import { ListFilters, ListFiltersTitle } from '/@/renderer/features/shared/components/list-filters';
import { ListWithSidebarContainer } from '/@/renderer/features/shared/components/list-with-sidebar-container';
import { SaveAsCollectionButton } from '/@/renderer/features/shared/components/save-as-collection-button';
import { SongListView } from '/@/renderer/features/songs/components/song-list-content';
import { GenreTarget, useGenreTarget, useListSettings } from '/@/renderer/store';
import { ScrollArea } from '/@/shared/components/scroll-area/scroll-area';
import { Spinner } from '/@/shared/components/spinner/spinner';
import { Stack } from '/@/shared/components/stack/stack';
import { LibraryItem } from '/@/shared/types/domain-types';
import { ItemListKey } from '/@/shared/types/types';
const GenreDetailFilters = () => {
const genreTarget = useGenreTarget();
if (genreTarget === GenreTarget.ALBUM) {
return (
<ListWithSidebarContainer.SidebarPortal>
<Stack h="100%" style={{ minHeight: 0 }}>
<ListFiltersTitle itemType={LibraryItem.ALBUM} />
<ScrollArea style={{ flex: 1, minHeight: 0 }}>
<ListFilters itemType={LibraryItem.ALBUM} />
</ScrollArea>
<Stack p="sm">
<SaveAsCollectionButton fullWidth itemType={LibraryItem.ALBUM} />
</Stack>
</Stack>
</ListWithSidebarContainer.SidebarPortal>
);
}
if (genreTarget === GenreTarget.TRACK) {
return (
<ListWithSidebarContainer.SidebarPortal>
<Stack h="100%" style={{ minHeight: 0 }}>
<ListFiltersTitle itemType={LibraryItem.SONG} />
<ScrollArea style={{ flex: 1, minHeight: 0 }}>
<ListFilters itemType={LibraryItem.SONG} />
</ScrollArea>
<Stack p="sm">
<SaveAsCollectionButton fullWidth itemType={LibraryItem.SONG} />
</Stack>
</Stack>
</ListWithSidebarContainer.SidebarPortal>
);
}
return null;
};
export const GenreDetailContent = () => {
const genreTarget = useGenreTarget();
switch (genreTarget) {
case GenreTarget.ALBUM:
return <GenreDetailContentAlbums />;
case GenreTarget.TRACK:
return <GenreDetailContentSongs />;
default:
return null;
}
return (
<>
<GenreDetailFilters />
{genreTarget === GenreTarget.ALBUM && <GenreDetailContentAlbums />}
{genreTarget === GenreTarget.TRACK && <GenreDetailContentSongs />}
</>
);
};
function GenreDetailContentAlbums() {
@@ -6,22 +6,31 @@ import { useGenreList } from '/@/renderer/features/genres/api/genres-api';
import { GenreDetailContent } from '/@/renderer/features/genres/components/genre-detail-content';
import { GenreDetailHeader } from '/@/renderer/features/genres/components/genre-detail-header';
import { AnimatedPage } from '/@/renderer/features/shared/components/animated-page';
import { ListWithSidebarContainer } from '/@/renderer/features/shared/components/list-with-sidebar-container';
import { PageErrorBoundary } from '/@/renderer/features/shared/components/page-error-boundary';
import { GenreTarget, useGenreTarget } from '/@/renderer/store';
import { usePageSidebar } from '/@/renderer/store/app.store';
import { ItemListKey } from '/@/shared/types/types';
const GenreDetailRoute = () => {
const { genreId } = useParams() as { genreId: string };
const pageKey = 'genre';
const genreTarget = useGenreTarget();
const pageKey =
genreTarget === GenreTarget.ALBUM ? ItemListKey.GENRE_ALBUM : ItemListKey.GENRE_SONG;
const [itemCount, setItemCount] = useState<number | undefined>(undefined);
const [isSidebarOpen, setIsSidebarOpen] = usePageSidebar(pageKey);
const providerValue = useMemo(() => {
return {
id: genreId,
isSidebarOpen,
itemCount,
pageKey,
setIsSidebarOpen,
setItemCount,
};
}, [genreId, itemCount, pageKey, setItemCount]);
}, [genreId, isSidebarOpen, itemCount, pageKey, setIsSidebarOpen, setItemCount]);
const { data: genres } = useGenreList();
@@ -33,7 +42,9 @@ const GenreDetailRoute = () => {
<AnimatedPage>
<ListContext.Provider value={providerValue}>
<GenreDetailHeader title={name} />
<ListWithSidebarContainer>
<GenreDetailContent />
</ListWithSidebarContainer>
</ListContext.Provider>
</AnimatedPage>
);
@@ -62,7 +62,8 @@ export const ListFiltersModal = ({ isActive, itemType }: ListFiltersProps) => {
const canPin = Boolean(setIsSidebarOpen);
const disableArtistFilter = pageKey === ItemListKey.ALBUM_ARTIST_ALBUM;
const disableGenreFilter = pageKey === ItemListKey.GENRE_ALBUM;
const disableGenreFilter =
pageKey === ItemListKey.GENRE_ALBUM || pageKey === ItemListKey.GENRE_SONG;
return (
<>
@@ -114,7 +115,8 @@ export const ListFilters = ({ itemType }: ListFiltersProps) => {
const { pageKey } = useListContext();
const disableArtistFilter = pageKey === ItemListKey.ALBUM_ARTIST_ALBUM;
const disableGenreFilter = pageKey === ItemListKey.GENRE_ALBUM;
const disableGenreFilter =
pageKey === ItemListKey.GENRE_ALBUM || pageKey === ItemListKey.GENRE_SONG;
return (
<ComponentErrorBoundary>