From a308efaf06703c2cc8d02397a254b68f9a24b624 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Sun, 21 May 2023 15:34:52 -0700 Subject: [PATCH] Fix jellyfin discography views (#81) --- .../components/album-list-header-filters.tsx | 4 +++ .../albums/components/album-list-header.tsx | 6 +++- .../components/jellyfin-album-filters.tsx | 7 ++++- .../components/navidrome-album-filters.tsx | 9 +++++- .../album-artist-list-header-filters.tsx | 6 +++- .../components/album-artist-list-header.tsx | 2 ++ .../components/jellyfin-song-filters.tsx | 5 ++++ .../components/navidrome-song-filters.tsx | 4 +++ .../components/song-list-header-filters.tsx | 6 +++- .../songs/components/song-list-header.tsx | 8 +++-- src/renderer/store/list.store.ts | 29 ++++++++++++++----- 11 files changed, 72 insertions(+), 14 deletions(-) diff --git a/src/renderer/features/albums/components/album-list-header-filters.tsx b/src/renderer/features/albums/components/album-list-header-filters.tsx index d4681504..6981126b 100644 --- a/src/renderer/features/albums/components/album-list-header-filters.tsx +++ b/src/renderer/features/albums/components/album-list-header-filters.tsx @@ -253,6 +253,7 @@ export const AlbumListHeaderFilters = ({ sortBy: e.currentTarget.value as AlbumListSort, sortOrder: sortOrder || SortOrder.ASC, }, + itemType: LibraryItem.ALBUM, key: 'album', }) as AlbumListFilter; @@ -269,11 +270,13 @@ export const AlbumListHeaderFilters = ({ if (e.currentTarget.value === String(filter.musicFolderId)) { updatedFilters = setFilter({ data: { musicFolderId: undefined }, + itemType: LibraryItem.ALBUM, key: 'album', }) as AlbumListFilter; } else { updatedFilters = setFilter({ data: { musicFolderId: e.currentTarget.value }, + itemType: LibraryItem.ALBUM, key: 'album', }) as AlbumListFilter; } @@ -287,6 +290,7 @@ export const AlbumListHeaderFilters = ({ const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; const updatedFilters = setFilter({ data: { sortOrder: newSortOrder }, + itemType: LibraryItem.ALBUM, key: 'album', }) as AlbumListFilter; handleFilterChange(updatedFilters); diff --git a/src/renderer/features/albums/components/album-list-header.tsx b/src/renderer/features/albums/components/album-list-header.tsx index 4a20ca8b..67f977b6 100644 --- a/src/renderer/features/albums/components/album-list-header.tsx +++ b/src/renderer/features/albums/components/album-list-header.tsx @@ -158,7 +158,11 @@ export const AlbumListHeader = ({ const handleSearch = debounce((e: ChangeEvent) => { const previousSearchTerm = filter.searchTerm; const searchTerm = e.target.value === '' ? undefined : e.target.value; - const updatedFilters = setFilter({ data: { searchTerm }, key: 'album' }) as AlbumListFilter; + const updatedFilters = setFilter({ + data: { searchTerm }, + itemType: LibraryItem.ALBUM, + key: 'album', + }) as AlbumListFilter; if (previousSearchTerm !== searchTerm) handleFilterChange(updatedFilters); }, 500); diff --git a/src/renderer/features/albums/components/jellyfin-album-filters.tsx b/src/renderer/features/albums/components/jellyfin-album-filters.tsx index ace5581c..a74e65e6 100644 --- a/src/renderer/features/albums/components/jellyfin-album-filters.tsx +++ b/src/renderer/features/albums/components/jellyfin-album-filters.tsx @@ -4,7 +4,7 @@ import { MultiSelect, NumberInput, SpinnerIcon, Switch, Text } from '/@/renderer import { AlbumListFilter, useAlbumListFilter, useListStoreActions } from '/@/renderer/store'; import debounce from 'lodash/debounce'; import { useGenreList } from '/@/renderer/features/genres'; -import { AlbumArtistListSort, SortOrder } from '/@/renderer/api/types'; +import { AlbumArtistListSort, LibraryItem, SortOrder } from '/@/renderer/api/types'; import { useAlbumArtistList } from '/@/renderer/features/artists/queries/album-artist-list-query'; interface JellyfinAlbumFiltersProps { @@ -54,6 +54,7 @@ export const JellyfinAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -74,6 +75,7 @@ export const JellyfinAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -91,6 +93,7 @@ export const JellyfinAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -108,6 +111,7 @@ export const JellyfinAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -149,6 +153,7 @@ export const JellyfinAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); diff --git a/src/renderer/features/albums/components/navidrome-album-filters.tsx b/src/renderer/features/albums/components/navidrome-album-filters.tsx index a8d22eec..76a59061 100644 --- a/src/renderer/features/albums/components/navidrome-album-filters.tsx +++ b/src/renderer/features/albums/components/navidrome-album-filters.tsx @@ -5,7 +5,7 @@ import { AlbumListFilter, useAlbumListFilter, useListStoreActions } from '/@/ren import debounce from 'lodash/debounce'; import { useGenreList } from '/@/renderer/features/genres'; import { useAlbumArtistList } from '/@/renderer/features/artists/queries/album-artist-list-query'; -import { AlbumArtistListSort, SortOrder } from '/@/renderer/api/types'; +import { AlbumArtistListSort, LibraryItem, SortOrder } from '/@/renderer/api/types'; interface NavidromeAlbumFiltersProps { disableArtistFilter?: boolean; @@ -46,6 +46,7 @@ export const NavidromeAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: 'album', }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -65,6 +66,7 @@ export const NavidromeAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -85,6 +87,7 @@ export const NavidromeAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -104,6 +107,7 @@ export const NavidromeAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -123,6 +127,7 @@ export const NavidromeAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -142,6 +147,7 @@ export const NavidromeAlbumFilters = ({ ...filter._custom, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); @@ -183,6 +189,7 @@ export const NavidromeAlbumFilters = ({ }, }, }, + itemType: LibraryItem.ALBUM, key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); diff --git a/src/renderer/features/artists/components/album-artist-list-header-filters.tsx b/src/renderer/features/artists/components/album-artist-list-header-filters.tsx index a9865bdc..0c84e56a 100644 --- a/src/renderer/features/artists/components/album-artist-list-header-filters.tsx +++ b/src/renderer/features/artists/components/album-artist-list-header-filters.tsx @@ -14,7 +14,7 @@ import { } from 'react-icons/ri'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { AlbumArtistListSort, SortOrder } from '/@/renderer/api/types'; +import { AlbumArtistListSort, LibraryItem, SortOrder } from '/@/renderer/api/types'; import { DropdownMenu, Text, Button, Slider, MultiSelect, Switch } from '/@/renderer/components'; import { useMusicFolders } from '/@/renderer/features/shared'; import { useContainerQuery } from '/@/renderer/hooks'; @@ -199,6 +199,7 @@ export const AlbumArtistListHeaderFilters = ({ sortBy: e.currentTarget.value as AlbumArtistListSort, sortOrder: sortOrder || SortOrder.ASC, }, + itemType: LibraryItem.ALBUM_ARTIST, key: pageKey, }) as AlbumArtistListFilter; @@ -215,11 +216,13 @@ export const AlbumArtistListHeaderFilters = ({ if (e.currentTarget.value === String(filter.musicFolderId)) { updatedFilters = setFilter({ data: { musicFolderId: undefined }, + itemType: LibraryItem.ALBUM_ARTIST, key: pageKey, }) as AlbumArtistListFilter; } else { updatedFilters = setFilter({ data: { musicFolderId: e.currentTarget.value }, + itemType: LibraryItem.ALBUM_ARTIST, key: pageKey, }) as AlbumArtistListFilter; } @@ -233,6 +236,7 @@ export const AlbumArtistListHeaderFilters = ({ const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; const updatedFilters = setFilter({ data: { sortOrder: newSortOrder }, + itemType: LibraryItem.ALBUM_ARTIST, key: pageKey, }) as AlbumArtistListFilter; handleFilterChange(updatedFilters); diff --git a/src/renderer/features/artists/components/album-artist-list-header.tsx b/src/renderer/features/artists/components/album-artist-list-header.tsx index b5b4d4e8..e979e9bd 100644 --- a/src/renderer/features/artists/components/album-artist-list-header.tsx +++ b/src/renderer/features/artists/components/album-artist-list-header.tsx @@ -21,6 +21,7 @@ import { AlbumArtistListHeaderFilters } from '/@/renderer/features/artists/compo import { useAlbumArtistListContext } from '/@/renderer/features/artists/context/album-artist-list-context'; import { FilterBar } from '../../shared/components/filter-bar'; import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid'; +import { LibraryItem } from '/@/renderer/api/types'; interface AlbumArtistListHeaderProps { gridRef: MutableRefObject; @@ -136,6 +137,7 @@ export const AlbumArtistListHeader = ({ const searchTerm = e.target.value === '' ? undefined : e.target.value; const updatedFilters = setFilter({ data: { searchTerm }, + itemType: LibraryItem.ALBUM_ARTIST, key: pageKey, }) as AlbumArtistListFilter; if (previousSearchTerm !== searchTerm) handleFilterChange(updatedFilters); diff --git a/src/renderer/features/songs/components/jellyfin-song-filters.tsx b/src/renderer/features/songs/components/jellyfin-song-filters.tsx index 759b148c..3a75f274 100644 --- a/src/renderer/features/songs/components/jellyfin-song-filters.tsx +++ b/src/renderer/features/songs/components/jellyfin-song-filters.tsx @@ -4,6 +4,7 @@ import { MultiSelect, NumberInput, Switch, Text } from '/@/renderer/components'; import { SongListFilter, useListStoreActions, useSongListFilter } from '/@/renderer/store'; import debounce from 'lodash/debounce'; import { useGenreList } from '/@/renderer/features/genres'; +import { LibraryItem } from '/@/renderer/api/types'; interface JellyfinSongFiltersProps { handleFilterChange: (filters: SongListFilter) => void; @@ -51,6 +52,7 @@ export const JellyfinSongFilters = ({ }, }, }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; handleFilterChange(updatedFilters); @@ -72,6 +74,7 @@ export const JellyfinSongFilters = ({ }, }, }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; handleFilterChange(updatedFilters); @@ -90,6 +93,7 @@ export const JellyfinSongFilters = ({ }, }, }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; handleFilterChange(updatedFilters); @@ -108,6 +112,7 @@ export const JellyfinSongFilters = ({ }, }, }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; handleFilterChange(updatedFilters); diff --git a/src/renderer/features/songs/components/navidrome-song-filters.tsx b/src/renderer/features/songs/components/navidrome-song-filters.tsx index a6c068df..619b459f 100644 --- a/src/renderer/features/songs/components/navidrome-song-filters.tsx +++ b/src/renderer/features/songs/components/navidrome-song-filters.tsx @@ -4,6 +4,7 @@ import { NumberInput, Select, Switch, Text } from '/@/renderer/components'; import { SongListFilter, useListStoreActions, useSongListFilter } from '/@/renderer/store'; import debounce from 'lodash/debounce'; import { useGenreList } from '/@/renderer/features/genres'; +import { LibraryItem } from '/@/renderer/api/types'; interface NavidromeSongFiltersProps { handleFilterChange: (filters: SongListFilter) => void; @@ -41,6 +42,7 @@ export const NavidromeSongFilters = ({ }, }, }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; handleFilterChange(updatedFilters); @@ -59,6 +61,7 @@ export const NavidromeSongFilters = ({ }, }, }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; @@ -78,6 +81,7 @@ export const NavidromeSongFilters = ({ }, }, }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; diff --git a/src/renderer/features/songs/components/song-list-header-filters.tsx b/src/renderer/features/songs/components/song-list-header-filters.tsx index d454fe69..51f91b6d 100644 --- a/src/renderer/features/songs/components/song-list-header-filters.tsx +++ b/src/renderer/features/songs/components/song-list-header-filters.tsx @@ -17,7 +17,7 @@ import { } from 'react-icons/ri'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { SongListQuery, SongListSort, SortOrder } from '/@/renderer/api/types'; +import { LibraryItem, SongListQuery, SongListSort, SortOrder } from '/@/renderer/api/types'; import { DropdownMenu, Button, Slider, MultiSelect, Switch, Text } from '/@/renderer/components'; import { useMusicFolders } from '/@/renderer/features/shared'; import { JellyfinSongFilters } from '/@/renderer/features/songs/components/jellyfin-song-filters'; @@ -151,6 +151,7 @@ export const SongListHeaderFilters = ({ tableRef }: SongListHeaderFiltersProps) sortBy: e.currentTarget.value as SongListSort, sortOrder: sortOrder || SortOrder.ASC, }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; @@ -167,11 +168,13 @@ export const SongListHeaderFilters = ({ tableRef }: SongListHeaderFiltersProps) if (e.currentTarget.value === String(filter.musicFolderId)) { updatedFilters = setFilter({ data: { musicFolderId: undefined }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; } else { updatedFilters = setFilter({ data: { musicFolderId: e.currentTarget.value }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; } @@ -185,6 +188,7 @@ export const SongListHeaderFilters = ({ tableRef }: SongListHeaderFiltersProps) const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; const updatedFilters = setFilter({ data: { sortOrder: newSortOrder }, + itemType: LibraryItem.SONG, key: pageKey, }) as SongListFilter; handleFilterChange(updatedFilters); diff --git a/src/renderer/features/songs/components/song-list-header.tsx b/src/renderer/features/songs/components/song-list-header.tsx index b5e708c5..48651877 100644 --- a/src/renderer/features/songs/components/song-list-header.tsx +++ b/src/renderer/features/songs/components/song-list-header.tsx @@ -5,7 +5,7 @@ import debounce from 'lodash/debounce'; import { ChangeEvent, MutableRefObject, useCallback } from 'react'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; -import { SongListQuery } from '/@/renderer/api/types'; +import { LibraryItem, SongListQuery } from '/@/renderer/api/types'; import { PageHeader, SearchInput } from '/@/renderer/components'; import { FilterBar, LibraryHeaderBar } from '/@/renderer/features/shared'; import { SongListHeaderFilters } from '/@/renderer/features/songs/components/song-list-header-filters'; @@ -78,7 +78,11 @@ export const SongListHeader = ({ title, itemCount, tableRef }: SongListHeaderPro const handleSearch = debounce((e: ChangeEvent) => { const previousSearchTerm = filter.searchTerm; const searchTerm = e.target.value === '' ? undefined : e.target.value; - const updatedFilters = setFilter({ data: { searchTerm }, key: pageKey }) as SongListFilter; + const updatedFilters = setFilter({ + data: { searchTerm }, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; if (previousSearchTerm !== searchTerm) handleFilterChange(updatedFilters); }, 500); diff --git a/src/renderer/store/list.store.ts b/src/renderer/store/list.store.ts index 8b1e1d74..51e699b9 100644 --- a/src/renderer/store/list.store.ts +++ b/src/renderer/store/list.store.ts @@ -8,6 +8,7 @@ import { AlbumArtistListSort, AlbumListArgs, AlbumListSort, + LibraryItem, PlaylistListSort, SongListArgs, SongListSort, @@ -61,10 +62,12 @@ type DeterministicArgs = { key: ListKey }; export interface ListSlice extends ListState { _actions: { - getFilter: (args: { id?: string; key?: string }) => FilterType; + getFilter: (args: { id?: string; itemType: LibraryItem; key?: string }) => FilterType; resetFilter: () => void; setDisplayType: (args: { data: ListDisplayType } & DeterministicArgs) => void; - setFilter: (args: { data: Partial } & DeterministicArgs) => FilterType; + setFilter: ( + args: { data: Partial; itemType: LibraryItem } & DeterministicArgs, + ) => FilterType; setGrid: (args: { data: Partial } & DeterministicArgs) => void; setStore: (data: Partial) => void; setTable: (args: { data: Partial } & DeterministicArgs) => void; @@ -90,7 +93,7 @@ export const useListStore = create()( ...state.detail[args.key]?.filter?._custom, jellyfin: { ...state.detail[args.key]?.filter?._custom?.jellyfin, - includeItemTypes: 'Audio', + includeItemTypes: args?.itemType === LibraryItem.ALBUM ? 'MusicAlbum' : 'Audio', }, navidrome: { ...state.detail[args.key]?.filter?._custom?.navidrome, @@ -157,7 +160,7 @@ export const useListStore = create()( } }); - return get()._actions.getFilter({ id, key: args.key }); + return get()._actions.getFilter({ id, itemType: args.itemType, key: args.key }); }, setGrid: (args) => { const [page, id] = args.key.split('_'); @@ -526,17 +529,29 @@ export const useSongListStore = (args?: { id?: string; key?: string }) => export const useSongListFilter = (args: { id?: string; key?: string }) => useListStore((state) => { - return state._actions.getFilter({ id: args.id, key: args.key }) as SongListFilter; + return state._actions.getFilter({ + id: args.id, + itemType: LibraryItem.SONG, + key: args.key, + }) as SongListFilter; }, shallow); export const useAlbumListFilter = (args: { id?: string; key?: string }) => useListStore((state) => { - return state._actions.getFilter({ id: args.id, key: args.key }) as AlbumListFilter; + return state._actions.getFilter({ + id: args.id, + itemType: LibraryItem.ALBUM, + key: args.key, + }) as AlbumListFilter; }, shallow); export const useAlbumArtistListFilter = (args: { id?: string; key?: string }) => useListStore((state) => { - return state._actions.getFilter({ id: args.id, key: args.key }) as AlbumArtistListFilter; + return state._actions.getFilter({ + id: args.id, + itemType: LibraryItem.ALBUM_ARTIST, + key: args.key, + }) as AlbumArtistListFilter; }, shallow); export const useListDetail = (key: string) => useListStore((state) => state.detail[key], shallow);