From b097d67d7149214140f12ee15f8362355b44b054 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Sat, 29 Nov 2025 16:57:34 -0800 Subject: [PATCH] properly handle switch between genre display states without filter clobber --- .../components/album-list-header-filters.tsx | 15 ++++++-- .../albums/hooks/use-album-list-filters.ts | 34 +++++++++++++++++-- .../components/song-list-header-filters.tsx | 15 ++++++-- .../songs/hooks/use-song-list-filters.ts | 33 ++++++++++++++++-- 4 files changed, 87 insertions(+), 10 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 03f2d8c62..f6aa8c053 100644 --- a/src/renderer/features/albums/components/album-list-header-filters.tsx +++ b/src/renderer/features/albums/components/album-list-header-filters.tsx @@ -1,12 +1,14 @@ -import { useMemo } from 'react'; +import { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { ALBUM_TABLE_COLUMNS } from '/@/renderer/components/item-list/item-table-list/default-columns'; +import { useAlbumListFilters } from '/@/renderer/features/albums/hooks/use-album-list-filters'; import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu'; import { ListFilters } from '/@/renderer/features/shared/components/list-filters'; import { ListRefreshButton } from '/@/renderer/features/shared/components/list-refresh-button'; import { ListSortByDropdown } from '/@/renderer/features/shared/components/list-sort-by-dropdown'; import { ListSortOrderToggleButton } from '/@/renderer/features/shared/components/list-sort-order-toggle-button'; +import { useSongListFilters } from '/@/renderer/features/songs/hooks/use-song-list-filters'; import { GenreTarget, useGenreTarget, useSettingsStoreActions } from '/@/renderer/store'; import { Button } from '/@/shared/components/button/button'; import { Divider } from '/@/shared/components/divider/divider'; @@ -20,6 +22,8 @@ export const AlbumListHeaderFilters = ({ toggleGenreTarget }: { toggleGenreTarge const { t } = useTranslation(); const target = useGenreTarget(); const { setGenreBehavior } = useSettingsStoreActions(); + const albumFilters = useAlbumListFilters(); + const songFilters = useSongListFilters(); const choice = useMemo(() => { return target === GenreTarget.ALBUM @@ -27,9 +31,14 @@ export const AlbumListHeaderFilters = ({ toggleGenreTarget }: { toggleGenreTarge : t('entity.track_other', { postProcess: 'titleCase' }); }, [target, t]); - const handleToggleGenreTarget = () => { + const handleToggleGenreTarget = useCallback(() => { + // Clear all filter query states + albumFilters.clear(); + songFilters.clear(); + + // Toggle the genre target setGenreBehavior(target === GenreTarget.ALBUM ? GenreTarget.TRACK : GenreTarget.ALBUM); - }; + }, [target, setGenreBehavior, albumFilters, songFilters]); return ( diff --git a/src/renderer/features/albums/hooks/use-album-list-filters.ts b/src/renderer/features/albums/hooks/use-album-list-filters.ts index fc85d731b..f70b2e18e 100644 --- a/src/renderer/features/albums/hooks/use-album-list-filters.ts +++ b/src/renderer/features/albums/hooks/use-album-list-filters.ts @@ -1,3 +1,4 @@ +import { useCallback } from 'react'; import { parseAsArrayOf, parseAsBoolean, @@ -15,9 +16,9 @@ import { AlbumListSort, SortOrder } from '/@/shared/types/domain-types'; import { ItemListKey } from '/@/shared/types/types'; export const useAlbumListFilters = () => { - const { sortBy } = useSortByFilter(AlbumListSort.NAME, ItemListKey.ALBUM); + const { sortBy, setSortBy } = useSortByFilter(AlbumListSort.NAME, ItemListKey.ALBUM); - const { sortOrder } = useSortOrderFilter(SortOrder.ASC, ItemListKey.ALBUM); + const { sortOrder, setSortOrder } = useSortOrderFilter(SortOrder.ASC, ItemListKey.ALBUM); const { searchTerm, setSearchTerm } = useSearchTermFilter(''); @@ -54,6 +55,34 @@ export const useAlbumListFilters = () => { parseAsJson(customFiltersSchema), ); + const clear = useCallback(() => { + setAlbumArtist(null); + setCompilation(null); + setCustom(null); + setFavorite(null); + setGenreId(null); + setHasRating(null); + setMaxYear(null); + setMinYear(null); + setRecentlyPlayed(null); + setSearchTerm(null); + setSortBy(AlbumListSort.NAME); + setSortOrder(SortOrder.ASC); + }, [ + setAlbumArtist, + setCompilation, + setCustom, + setFavorite, + setGenreId, + setHasRating, + setMaxYear, + setMinYear, + setRecentlyPlayed, + setSearchTerm, + setSortBy, + setSortOrder, + ]); + const query = { [FILTER_KEYS.ALBUM._CUSTOM]: custom ?? undefined, [FILTER_KEYS.ALBUM.ARTIST_IDS]: albumArtist ?? undefined, @@ -70,6 +99,7 @@ export const useAlbumListFilters = () => { }; return { + clear, query, setAlbumArtist, setCompilation, 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 216275290..d5214ee57 100644 --- a/src/renderer/features/songs/components/song-list-header-filters.tsx +++ b/src/renderer/features/songs/components/song-list-header-filters.tsx @@ -1,12 +1,14 @@ -import { useMemo } from 'react'; +import { useCallback, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { SONG_TABLE_COLUMNS } from '/@/renderer/components/item-list/item-table-list/default-columns'; +import { useAlbumListFilters } from '/@/renderer/features/albums/hooks/use-album-list-filters'; import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu'; import { ListFilters } from '/@/renderer/features/shared/components/list-filters'; import { ListRefreshButton } from '/@/renderer/features/shared/components/list-refresh-button'; import { ListSortByDropdown } from '/@/renderer/features/shared/components/list-sort-by-dropdown'; import { ListSortOrderToggleButton } from '/@/renderer/features/shared/components/list-sort-order-toggle-button'; +import { useSongListFilters } from '/@/renderer/features/songs/hooks/use-song-list-filters'; import { GenreTarget, useGenreTarget, useSettingsStoreActions } from '/@/renderer/store'; import { Button } from '/@/shared/components/button/button'; import { Divider } from '/@/shared/components/divider/divider'; @@ -20,10 +22,17 @@ export const SongListHeaderFilters = ({ toggleGenreTarget }: { toggleGenreTarget const { t } = useTranslation(); const target = useGenreTarget(); const { setGenreBehavior } = useSettingsStoreActions(); + const albumFilters = useAlbumListFilters(); + const songFilters = useSongListFilters(); - const handleToggleGenreTarget = () => { + const handleToggleGenreTarget = useCallback(() => { + // Clear all filter query states + albumFilters.clear(); + songFilters.clear(); + + // Toggle the genre target setGenreBehavior(target === GenreTarget.ALBUM ? GenreTarget.TRACK : GenreTarget.ALBUM); - }; + }, [target, setGenreBehavior, albumFilters, songFilters]); const choice = useMemo(() => { return target === GenreTarget.ALBUM diff --git a/src/renderer/features/songs/hooks/use-song-list-filters.ts b/src/renderer/features/songs/hooks/use-song-list-filters.ts index fc77089ab..eb2ad3b84 100644 --- a/src/renderer/features/songs/hooks/use-song-list-filters.ts +++ b/src/renderer/features/songs/hooks/use-song-list-filters.ts @@ -6,6 +6,7 @@ import { parseAsString, useQueryState, } from 'nuqs'; +import { useCallback } from 'react'; import { useSearchTermFilter } from '/@/renderer/features/shared/hooks/use-search-term-filter'; import { useSortByFilter } from '/@/renderer/features/shared/hooks/use-sort-by-filter'; @@ -15,9 +16,12 @@ import { SongListSort, SortOrder } from '/@/shared/types/domain-types'; import { ItemListKey } from '/@/shared/types/types'; export const useSongListFilters = () => { - const { sortBy } = useSortByFilter(SongListSort.NAME, ItemListKey.SONG); + const { setSortBy, sortBy } = useSortByFilter( + SongListSort.NAME, + ItemListKey.SONG, + ); - const { sortOrder } = useSortOrderFilter(SortOrder.ASC, ItemListKey.SONG); + const { setSortOrder, sortOrder } = useSortOrderFilter(SortOrder.ASC, ItemListKey.SONG); const { searchTerm, setSearchTerm } = useSearchTermFilter(''); @@ -47,6 +51,30 @@ export const useSongListFilters = () => { parseAsJson(customFiltersSchema), ); + const clear = useCallback(() => { + setAlbumIds(null); + setArtistIds(null); + setCustom(null); + setFavorite(null); + setGenreId(null); + setMaxYear(null); + setMinYear(null); + setSearchTerm(null); + setSortBy(SongListSort.NAME); + setSortOrder(SortOrder.ASC); + }, [ + setAlbumIds, + setArtistIds, + setCustom, + setFavorite, + setGenreId, + setMaxYear, + setMinYear, + setSearchTerm, + setSortBy, + setSortOrder, + ]); + const query = { [FILTER_KEYS.SHARED.SEARCH_TERM]: searchTerm ?? undefined, [FILTER_KEYS.SHARED.SORT_BY]: sortBy ?? undefined, @@ -61,6 +89,7 @@ export const useSongListFilters = () => { }; return { + clear, query, setAlbumIds, setArtistIds,