properly handle switch between genre display states without filter clobber

This commit is contained in:
jeffvli
2025-11-29 16:57:34 -08:00
parent 3a5eb96410
commit b097d67d71
4 changed files with 87 additions and 10 deletions
@@ -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 (
<Flex justify="space-between">
@@ -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>(AlbumListSort.NAME, ItemListKey.ALBUM);
const { sortBy, setSortBy } = useSortByFilter<AlbumListSort>(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,
@@ -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
@@ -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>(SongListSort.NAME, ItemListKey.SONG);
const { setSortBy, sortBy } = useSortByFilter<SongListSort>(
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,