mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-10 04:30:25 +02:00
update query persistence to hooks
This commit is contained in:
@@ -54,8 +54,7 @@ export const AlbumListView = ({
|
|||||||
}: ItemListSettings) => {
|
}: ItemListSettings) => {
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
|
|
||||||
const filters = useAlbumListFilters();
|
const { query } = useAlbumListFilters();
|
||||||
const query = filters.query;
|
|
||||||
|
|
||||||
switch (display) {
|
switch (display) {
|
||||||
case ListDisplayType.GRID: {
|
case ListDisplayType.GRID: {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { useContainerQuery } from '/@/renderer/hooks';
|
|||||||
import { Divider } from '/@/shared/components/divider/divider';
|
import { Divider } from '/@/shared/components/divider/divider';
|
||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { AlbumListSort, LibraryItem } from '/@/shared/types/domain-types';
|
import { AlbumListSort, LibraryItem, SortOrder } from '/@/shared/types/domain-types';
|
||||||
import { ItemListKey } from '/@/shared/types/types';
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const AlbumListHeaderFilters = () => {
|
export const AlbumListHeaderFilters = () => {
|
||||||
@@ -24,7 +24,10 @@ export const AlbumListHeaderFilters = () => {
|
|||||||
listKey={ItemListKey.ALBUM}
|
listKey={ItemListKey.ALBUM}
|
||||||
/>
|
/>
|
||||||
<Divider orientation="vertical" />
|
<Divider orientation="vertical" />
|
||||||
<ListSortOrderToggleButton listKey={ItemListKey.ALBUM} />
|
<ListSortOrderToggleButton
|
||||||
|
defaultSortOrder={SortOrder.ASC}
|
||||||
|
listKey={ItemListKey.ALBUM}
|
||||||
|
/>
|
||||||
<ListMusicFolderDropdown listKey={ItemListKey.ALBUM} />
|
<ListMusicFolderDropdown listKey={ItemListKey.ALBUM} />
|
||||||
<ListFilters itemType={LibraryItem.ALBUM} />
|
<ListFilters itemType={LibraryItem.ALBUM} />
|
||||||
<ListRefreshButton listKey={ItemListKey.ALBUM} />
|
<ListRefreshButton listKey={ItemListKey.ALBUM} />
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ export const NavidromeAlbumFilters = ({ disableArtistFilter }: NavidromeAlbumFil
|
|||||||
const {
|
const {
|
||||||
query,
|
query,
|
||||||
setAlbumArtist,
|
setAlbumArtist,
|
||||||
setAlbumCompilation,
|
setCompilation,
|
||||||
setAlbumFavorite,
|
|
||||||
setAlbumGenre,
|
|
||||||
setAlbumHasRating,
|
|
||||||
setAlbumRecentlyPlayed,
|
|
||||||
setCustom,
|
setCustom,
|
||||||
setMaxAlbumYear,
|
setFavorite,
|
||||||
setMinAlbumYear,
|
setGenreId,
|
||||||
|
setHasRating,
|
||||||
|
setMaxYear,
|
||||||
|
setMinYear,
|
||||||
|
setRecentlyPlayed,
|
||||||
} = useAlbumListFilters();
|
} = useAlbumListFilters();
|
||||||
|
|
||||||
const genreListQuery = useQuery(
|
const genreListQuery = useQuery(
|
||||||
@@ -92,14 +92,14 @@ export const NavidromeAlbumFilters = ({ disableArtistFilter }: NavidromeAlbumFil
|
|||||||
{
|
{
|
||||||
label: t('filter.isFavorited', { postProcess: 'sentenceCase' }),
|
label: t('filter.isFavorited', { postProcess: 'sentenceCase' }),
|
||||||
onChange: (favorite?: boolean) => {
|
onChange: (favorite?: boolean) => {
|
||||||
setAlbumFavorite(favorite ?? null);
|
setFavorite(favorite ?? null);
|
||||||
},
|
},
|
||||||
value: query.favorite,
|
value: query.favorite,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('filter.isCompilation', { postProcess: 'sentenceCase' }),
|
label: t('filter.isCompilation', { postProcess: 'sentenceCase' }),
|
||||||
onChange: (compilation?: boolean) => {
|
onChange: (compilation?: boolean) => {
|
||||||
setAlbumCompilation(compilation ?? null);
|
setCompilation(compilation ?? null);
|
||||||
},
|
},
|
||||||
value: query.compilation,
|
value: query.compilation,
|
||||||
},
|
},
|
||||||
@@ -110,7 +110,7 @@ export const NavidromeAlbumFilters = ({ disableArtistFilter }: NavidromeAlbumFil
|
|||||||
label: t('filter.isRated', { postProcess: 'sentenceCase' }),
|
label: t('filter.isRated', { postProcess: 'sentenceCase' }),
|
||||||
onChange: (e: ChangeEvent<HTMLInputElement>) => {
|
onChange: (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
const hasRating = e.currentTarget.checked ? true : undefined;
|
const hasRating = e.currentTarget.checked ? true : undefined;
|
||||||
setAlbumHasRating(hasRating ?? null);
|
setHasRating(hasRating ?? null);
|
||||||
},
|
},
|
||||||
value: query.hasRating,
|
value: query.hasRating,
|
||||||
},
|
},
|
||||||
@@ -118,7 +118,7 @@ export const NavidromeAlbumFilters = ({ disableArtistFilter }: NavidromeAlbumFil
|
|||||||
label: t('filter.isRecentlyPlayed', { postProcess: 'sentenceCase' }),
|
label: t('filter.isRecentlyPlayed', { postProcess: 'sentenceCase' }),
|
||||||
onChange: (e: ChangeEvent<HTMLInputElement>) => {
|
onChange: (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
const recentlyPlayed = e.currentTarget.checked ? true : undefined;
|
const recentlyPlayed = e.currentTarget.checked ? true : undefined;
|
||||||
setAlbumRecentlyPlayed(recentlyPlayed ?? null);
|
setRecentlyPlayed(recentlyPlayed ?? null);
|
||||||
},
|
},
|
||||||
value: query.recentlyPlayed,
|
value: query.recentlyPlayed,
|
||||||
},
|
},
|
||||||
@@ -126,8 +126,8 @@ export const NavidromeAlbumFilters = ({ disableArtistFilter }: NavidromeAlbumFil
|
|||||||
|
|
||||||
const handleYearFilter = debounce((e: number | string) => {
|
const handleYearFilter = debounce((e: number | string) => {
|
||||||
const year = e === '' ? undefined : (e as number);
|
const year = e === '' ? undefined : (e as number);
|
||||||
setMinAlbumYear(year ?? null);
|
setMinYear(year ?? null);
|
||||||
setMaxAlbumYear(year ?? null);
|
setMaxYear(year ?? null);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
const albumArtistListQuery = useQuery(
|
const albumArtistListQuery = useQuery(
|
||||||
@@ -194,9 +194,9 @@ export const NavidromeAlbumFilters = ({ disableArtistFilter }: NavidromeAlbumFil
|
|||||||
<SelectWithInvalidData
|
<SelectWithInvalidData
|
||||||
clearable
|
clearable
|
||||||
data={genreList}
|
data={genreList}
|
||||||
defaultValue={query.genres ? query.genres[0] : undefined}
|
defaultValue={query.genreId ? query.genreId[0] : undefined}
|
||||||
label={t('entity.genre', { count: 1, postProcess: 'titleCase' })}
|
label={t('entity.genre', { count: 1, postProcess: 'titleCase' })}
|
||||||
onChange={(e) => (e ? setAlbumGenre([e]) : undefined)}
|
onChange={(e) => (e ? setGenreId([e]) : undefined)}
|
||||||
searchable
|
searchable
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
|
|||||||
@@ -12,19 +12,20 @@ import { useSearchTermFilter } from '/@/renderer/features/shared/hooks/use-searc
|
|||||||
import { useSortByFilter } from '/@/renderer/features/shared/hooks/use-sort-by-filter';
|
import { useSortByFilter } from '/@/renderer/features/shared/hooks/use-sort-by-filter';
|
||||||
import { useSortOrderFilter } from '/@/renderer/features/shared/hooks/use-sort-order-filter';
|
import { useSortOrderFilter } from '/@/renderer/features/shared/hooks/use-sort-order-filter';
|
||||||
import { customFiltersSchema, FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
import { customFiltersSchema, FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
||||||
import { AlbumListSort, SortOrder } from '/@/shared/types/domain-types';
|
import { AlbumListSort } from '/@/shared/types/domain-types';
|
||||||
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const useAlbumListFilters = () => {
|
export const useAlbumListFilters = () => {
|
||||||
const { sortBy } = useSortByFilter<AlbumListSort>(AlbumListSort.NAME);
|
const { sortBy } = useSortByFilter<AlbumListSort>(null, ItemListKey.ALBUM);
|
||||||
|
|
||||||
const { sortOrder } = useSortOrderFilter(SortOrder.ASC);
|
const { sortOrder } = useSortOrderFilter(null, ItemListKey.ALBUM);
|
||||||
|
|
||||||
const { musicFolderId } = useMusicFolderIdFilter('');
|
const { musicFolderId } = useMusicFolderIdFilter(null, ItemListKey.ALBUM);
|
||||||
|
|
||||||
const { searchTerm, setSearchTerm } = useSearchTermFilter('');
|
const { searchTerm, setSearchTerm } = useSearchTermFilter('');
|
||||||
|
|
||||||
const [albumGenre, setAlbumGenre] = useQueryState(
|
const [genreId, setGenreId] = useQueryState(
|
||||||
FILTER_KEYS.ALBUM.GENRES,
|
FILTER_KEYS.ALBUM.GENRE_ID,
|
||||||
parseAsArrayOf(parseAsString),
|
parseAsArrayOf(parseAsString),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -33,32 +34,20 @@ export const useAlbumListFilters = () => {
|
|||||||
parseAsArrayOf(parseAsString),
|
parseAsArrayOf(parseAsString),
|
||||||
);
|
);
|
||||||
|
|
||||||
const [minAlbumYear, setMinAlbumYear] = useQueryState(
|
const [minYear, setMinYear] = useQueryState(FILTER_KEYS.ALBUM.MIN_YEAR, parseAsInteger);
|
||||||
FILTER_KEYS.ALBUM.MIN_YEAR,
|
|
||||||
parseAsInteger,
|
|
||||||
);
|
|
||||||
|
|
||||||
const [maxAlbumYear, setMaxAlbumYear] = useQueryState(
|
const [maxYear, setMaxYear] = useQueryState(FILTER_KEYS.ALBUM.MAX_YEAR, parseAsInteger);
|
||||||
FILTER_KEYS.ALBUM.MAX_YEAR,
|
|
||||||
parseAsInteger,
|
|
||||||
);
|
|
||||||
|
|
||||||
const [albumFavorite, setAlbumFavorite] = useQueryState(
|
const [favorite, setFavorite] = useQueryState(FILTER_KEYS.ALBUM.FAVORITE, parseAsBoolean);
|
||||||
FILTER_KEYS.ALBUM.FAVORITE,
|
|
||||||
parseAsBoolean,
|
|
||||||
);
|
|
||||||
|
|
||||||
const [albumCompilation, setAlbumCompilation] = useQueryState(
|
const [compilation, setCompilation] = useQueryState(
|
||||||
FILTER_KEYS.ALBUM.COMPILATION,
|
FILTER_KEYS.ALBUM.COMPILATION,
|
||||||
parseAsBoolean,
|
parseAsBoolean,
|
||||||
);
|
);
|
||||||
|
|
||||||
const [albumHasRating, setAlbumHasRating] = useQueryState(
|
const [hasRating, setHasRating] = useQueryState(FILTER_KEYS.ALBUM.HAS_RATING, parseAsBoolean);
|
||||||
FILTER_KEYS.ALBUM.HAS_RATING,
|
|
||||||
parseAsBoolean,
|
|
||||||
);
|
|
||||||
|
|
||||||
const [albumRecentlyPlayed, setAlbumRecentlyPlayed] = useQueryState(
|
const [recentlyPlayed, setRecentlyPlayed] = useQueryState(
|
||||||
FILTER_KEYS.ALBUM.RECENTLY_PLAYED,
|
FILTER_KEYS.ALBUM.RECENTLY_PLAYED,
|
||||||
parseAsBoolean,
|
parseAsBoolean,
|
||||||
);
|
);
|
||||||
@@ -71,13 +60,13 @@ export const useAlbumListFilters = () => {
|
|||||||
const query = {
|
const query = {
|
||||||
[FILTER_KEYS.ALBUM._CUSTOM]: custom ?? undefined,
|
[FILTER_KEYS.ALBUM._CUSTOM]: custom ?? undefined,
|
||||||
[FILTER_KEYS.ALBUM.ARTIST_IDS]: albumArtist ?? undefined,
|
[FILTER_KEYS.ALBUM.ARTIST_IDS]: albumArtist ?? undefined,
|
||||||
[FILTER_KEYS.ALBUM.COMPILATION]: albumCompilation ?? undefined,
|
[FILTER_KEYS.ALBUM.COMPILATION]: compilation ?? undefined,
|
||||||
[FILTER_KEYS.ALBUM.FAVORITE]: albumFavorite ?? undefined,
|
[FILTER_KEYS.ALBUM.FAVORITE]: favorite ?? undefined,
|
||||||
[FILTER_KEYS.ALBUM.GENRES]: albumGenre ?? undefined,
|
[FILTER_KEYS.ALBUM.GENRE_ID]: genreId ?? undefined,
|
||||||
[FILTER_KEYS.ALBUM.HAS_RATING]: albumHasRating ?? undefined,
|
[FILTER_KEYS.ALBUM.HAS_RATING]: hasRating ?? undefined,
|
||||||
[FILTER_KEYS.ALBUM.MAX_YEAR]: maxAlbumYear ?? undefined,
|
[FILTER_KEYS.ALBUM.MAX_YEAR]: maxYear ?? undefined,
|
||||||
[FILTER_KEYS.ALBUM.MIN_YEAR]: minAlbumYear ?? undefined,
|
[FILTER_KEYS.ALBUM.MIN_YEAR]: minYear ?? undefined,
|
||||||
[FILTER_KEYS.ALBUM.RECENTLY_PLAYED]: albumRecentlyPlayed ?? undefined,
|
[FILTER_KEYS.ALBUM.RECENTLY_PLAYED]: recentlyPlayed ?? undefined,
|
||||||
[FILTER_KEYS.SHARED.MUSIC_FOLDER_ID]: musicFolderId ?? undefined,
|
[FILTER_KEYS.SHARED.MUSIC_FOLDER_ID]: musicFolderId ?? undefined,
|
||||||
[FILTER_KEYS.SHARED.SEARCH_TERM]: searchTerm ?? undefined,
|
[FILTER_KEYS.SHARED.SEARCH_TERM]: searchTerm ?? undefined,
|
||||||
[FILTER_KEYS.SHARED.SORT_BY]: sortBy ?? undefined,
|
[FILTER_KEYS.SHARED.SORT_BY]: sortBy ?? undefined,
|
||||||
@@ -87,14 +76,14 @@ export const useAlbumListFilters = () => {
|
|||||||
return {
|
return {
|
||||||
query,
|
query,
|
||||||
setAlbumArtist,
|
setAlbumArtist,
|
||||||
setAlbumCompilation,
|
setCompilation,
|
||||||
setAlbumFavorite,
|
|
||||||
setAlbumGenre,
|
|
||||||
setAlbumHasRating,
|
|
||||||
setAlbumRecentlyPlayed,
|
|
||||||
setCustom,
|
setCustom,
|
||||||
setMaxAlbumYear,
|
setFavorite,
|
||||||
setMinAlbumYear,
|
setGenreId,
|
||||||
|
setHasRating,
|
||||||
|
setMaxYear,
|
||||||
|
setMinYear,
|
||||||
|
setRecentlyPlayed,
|
||||||
setSearchTerm,
|
setSearchTerm,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,7 +30,11 @@ export const ListFilters = ({ isActive, itemType }: ListFiltersProps) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<FilterButton isActive={isActive} onClick={handlers.toggle} />
|
<FilterButton isActive={isActive} onClick={handlers.toggle} />
|
||||||
<Modal handlers={handlers} opened={isOpen} title={t('common.filters')}>
|
<Modal
|
||||||
|
handlers={handlers}
|
||||||
|
opened={isOpen}
|
||||||
|
title={t('common.filters', { postProcess: 'sentenceCase' })}
|
||||||
|
>
|
||||||
<FilterComponent />
|
<FilterComponent />
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -2,12 +2,10 @@ import { useQuery } from '@tanstack/react-query';
|
|||||||
|
|
||||||
import { sharedQueries } from '/@/renderer/features/shared/api/shared-api';
|
import { sharedQueries } from '/@/renderer/features/shared/api/shared-api';
|
||||||
import { FolderButton } from '/@/renderer/features/shared/components/folder-button';
|
import { FolderButton } from '/@/renderer/features/shared/components/folder-button';
|
||||||
import { FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
import { useMusicFolderIdFilter } from '/@/renderer/features/shared/hooks/use-music-folder-id-filter';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { DropdownMenu } from '/@/shared/components/dropdown-menu/dropdown-menu';
|
import { DropdownMenu } from '/@/shared/components/dropdown-menu/dropdown-menu';
|
||||||
import { useLocalStorage } from '/@/shared/hooks/use-local-storage';
|
|
||||||
import { ItemListKey } from '/@/shared/types/types';
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
import { useMusicFolderIdFilter } from '/@/renderer/features/shared/hooks/use-music-folder-id-filter';
|
|
||||||
|
|
||||||
interface ListMusicFolderDropdownProps {
|
interface ListMusicFolderDropdownProps {
|
||||||
listKey: ItemListKey;
|
listKey: ItemListKey;
|
||||||
@@ -19,22 +17,15 @@ export const ListMusicFolderDropdown = ({ listKey }: ListMusicFolderDropdownProp
|
|||||||
sharedQueries.musicFolders({ query: null, serverId: server.id }),
|
sharedQueries.musicFolders({ query: null, serverId: server.id }),
|
||||||
);
|
);
|
||||||
|
|
||||||
const [persisted, setPersisted] = useLocalStorage({
|
const { musicFolderId, setMusicFolderId } = useMusicFolderIdFilter('', listKey);
|
||||||
defaultValue: '',
|
|
||||||
key: getPersistenceKey(server.id, listKey),
|
|
||||||
});
|
|
||||||
|
|
||||||
const { musicFolderId, setMusicFolderId } = useMusicFolderIdFilter(persisted);
|
|
||||||
|
|
||||||
const handleSetMusicFolder = (e: string) => {
|
const handleSetMusicFolder = (e: string) => {
|
||||||
if (e === musicFolderId) {
|
if (e === musicFolderId) {
|
||||||
setMusicFolderId('');
|
setMusicFolderId('');
|
||||||
setPersisted('');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setMusicFolderId(e);
|
setMusicFolderId(e);
|
||||||
setPersisted(e);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -57,7 +48,3 @@ export const ListMusicFolderDropdown = ({ listKey }: ListMusicFolderDropdownProp
|
|||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPersistenceKey = (serverId: string, listKey: ItemListKey) => {
|
|
||||||
return `${serverId}-list-${listKey}-${FILTER_KEYS.SHARED.MUSIC_FOLDER_ID}`;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import i18n from '/@/i18n/i18n';
|
import i18n from '/@/i18n/i18n';
|
||||||
import { FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
import { useSortByFilter } from '/@/renderer/features/shared/hooks/use-sort-by-filter';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { Button } from '/@/shared/components/button/button';
|
import { Button } from '/@/shared/components/button/button';
|
||||||
import { DropdownMenu } from '/@/shared/components/dropdown-menu/dropdown-menu';
|
import { DropdownMenu } from '/@/shared/components/dropdown-menu/dropdown-menu';
|
||||||
import { useLocalStorage } from '/@/shared/hooks/use-local-storage';
|
|
||||||
import {
|
import {
|
||||||
AlbumListSort,
|
AlbumListSort,
|
||||||
LibraryItem,
|
LibraryItem,
|
||||||
@@ -12,7 +11,6 @@ import {
|
|||||||
SortOrder,
|
SortOrder,
|
||||||
} from '/@/shared/types/domain-types';
|
} from '/@/shared/types/domain-types';
|
||||||
import { ItemListKey } from '/@/shared/types/types';
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
import { useSortByFilter } from '/@/renderer/features/shared/hooks/use-sort-by-filter';
|
|
||||||
|
|
||||||
interface ListSortByDropdownProps {
|
interface ListSortByDropdownProps {
|
||||||
defaultSortByValue: string;
|
defaultSortByValue: string;
|
||||||
@@ -31,19 +29,13 @@ export const ListSortByDropdown = ({
|
|||||||
}: ListSortByDropdownProps) => {
|
}: ListSortByDropdownProps) => {
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
|
|
||||||
const [persisted, setPersisted] = useLocalStorage({
|
const { setSortBy, sortBy } = useSortByFilter(defaultSortByValue, listKey);
|
||||||
defaultValue: defaultSortByValue,
|
|
||||||
key: getPersistenceKey(server.id, listKey),
|
|
||||||
});
|
|
||||||
|
|
||||||
const { sortBy, setSortBy } = useSortByFilter(persisted || defaultSortByValue);
|
|
||||||
|
|
||||||
const sortByLabel =
|
const sortByLabel =
|
||||||
(itemType && FILTERS[itemType][server.type].find((f) => f.value === sortBy)?.name) || '—';
|
(itemType && FILTERS[itemType][server.type].find((f) => f.value === sortBy)?.name) || '—';
|
||||||
|
|
||||||
const handleSortByChange = (sortBy: string) => {
|
const handleSortByChange = (sortBy: string) => {
|
||||||
setSortBy(sortBy);
|
setSortBy(sortBy);
|
||||||
setPersisted(sortBy);
|
|
||||||
onChange?.(sortBy);
|
onChange?.(sortBy);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -369,7 +361,3 @@ const FILTERS: Partial<Record<LibraryItem, any>> = {
|
|||||||
[LibraryItem.ALBUM]: ALBUM_LIST_FILTERS,
|
[LibraryItem.ALBUM]: ALBUM_LIST_FILTERS,
|
||||||
[LibraryItem.SONG]: SONG_LIST_FILTERS,
|
[LibraryItem.SONG]: SONG_LIST_FILTERS,
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPersistenceKey = (serverId: string, listKey: ItemListKey) => {
|
|
||||||
return `${serverId}-list-${listKey}-${FILTER_KEYS.SHARED.SORT_BY}`;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,36 +1,25 @@
|
|||||||
import { OrderToggleButton } from '/@/renderer/features/shared/components/order-toggle-button';
|
import { OrderToggleButton } from '/@/renderer/features/shared/components/order-toggle-button';
|
||||||
import { useSortOrderFilter } from '/@/renderer/features/shared/hooks/use-sort-order-filter';
|
import { useSortOrderFilter } from '/@/renderer/features/shared/hooks/use-sort-order-filter';
|
||||||
import { FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
|
||||||
import { useLocalStorage } from '/@/shared/hooks/use-local-storage';
|
|
||||||
import { SortOrder } from '/@/shared/types/domain-types';
|
import { SortOrder } from '/@/shared/types/domain-types';
|
||||||
import { ItemListKey } from '/@/shared/types/types';
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface ListSortOrderToggleButtonProps {
|
interface ListSortOrderToggleButtonProps {
|
||||||
|
defaultSortOrder: SortOrder;
|
||||||
listKey: ItemListKey;
|
listKey: ItemListKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ListSortOrderToggleButton = ({ listKey }: ListSortOrderToggleButtonProps) => {
|
export const ListSortOrderToggleButton = ({
|
||||||
const server = useCurrentServer();
|
defaultSortOrder,
|
||||||
|
listKey,
|
||||||
const [persisted, setPersisted] = useLocalStorage({
|
}: ListSortOrderToggleButtonProps) => {
|
||||||
defaultValue: SortOrder.ASC,
|
const { setSortOrder, sortOrder } = useSortOrderFilter(defaultSortOrder, listKey);
|
||||||
key: getPersistenceKey(server.id, listKey),
|
|
||||||
});
|
|
||||||
|
|
||||||
const { sortOrder, setSortOrder } = useSortOrderFilter(persisted || SortOrder.ASC);
|
|
||||||
|
|
||||||
const handleToggleSortOrder = () => {
|
const handleToggleSortOrder = () => {
|
||||||
const newSortOrder = sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
const newSortOrder = sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
||||||
setSortOrder(newSortOrder);
|
setSortOrder(newSortOrder);
|
||||||
setPersisted(newSortOrder);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OrderToggleButton onToggle={handleToggleSortOrder} sortOrder={sortOrder as SortOrder} />
|
<OrderToggleButton onToggle={handleToggleSortOrder} sortOrder={sortOrder as SortOrder} />
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getPersistenceKey = (serverId: string, listKey: ItemListKey) => {
|
|
||||||
return `${serverId}-list-${listKey}-${FILTER_KEYS.SHARED.SORT_ORDER}`;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,15 +1,46 @@
|
|||||||
import { parseAsString, useQueryState } from 'nuqs';
|
import { parseAsString, useQueryState } from 'nuqs';
|
||||||
|
|
||||||
import { FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
import { FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
||||||
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
|
import { useLocalStorage } from '/@/shared/hooks/use-local-storage';
|
||||||
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
|
export const useMusicFolderIdFilter = (defaultValue: null | string, listKey: ItemListKey) => {
|
||||||
|
const server = useCurrentServer();
|
||||||
|
|
||||||
|
const [persisted, setPersisted] = useLocalStorage({
|
||||||
|
defaultValue: '',
|
||||||
|
key: getPersistenceKey(server.id, listKey),
|
||||||
|
});
|
||||||
|
|
||||||
export const useMusicFolderIdFilter = (defaultValue?: string) => {
|
|
||||||
const [musicFolderId, setMusicFolderId] = useQueryState(
|
const [musicFolderId, setMusicFolderId] = useQueryState(
|
||||||
FILTER_KEYS.SHARED.MUSIC_FOLDER_ID,
|
FILTER_KEYS.SHARED.MUSIC_FOLDER_ID,
|
||||||
defaultValue ? parseAsString.withDefault(defaultValue) : parseAsString,
|
getDefaultMusicFolderId(defaultValue, persisted),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleSetMusicFolderId = (musicFolderId: string) => {
|
||||||
|
setMusicFolderId(musicFolderId);
|
||||||
|
setPersisted(musicFolderId);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[FILTER_KEYS.SHARED.MUSIC_FOLDER_ID]: musicFolderId ?? undefined,
|
[FILTER_KEYS.SHARED.MUSIC_FOLDER_ID]: musicFolderId ?? undefined,
|
||||||
setMusicFolderId,
|
setMusicFolderId: handleSetMusicFolderId,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getDefaultMusicFolderId = (defaultValue: null | string, persisted: null | string) => {
|
||||||
|
if (persisted) {
|
||||||
|
return parseAsString.withDefault(persisted);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultValue) {
|
||||||
|
return parseAsString.withDefault(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseAsString;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPersistenceKey = (serverId: string, listKey: ItemListKey) => {
|
||||||
|
return `${serverId}-list-${listKey}-${FILTER_KEYS.SHARED.MUSIC_FOLDER_ID}`;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,15 +1,46 @@
|
|||||||
import { parseAsString, useQueryState } from 'nuqs';
|
import { parseAsString, useQueryState } from 'nuqs';
|
||||||
|
|
||||||
import { FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
import { FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
||||||
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
|
import { useLocalStorage } from '/@/shared/hooks/use-local-storage';
|
||||||
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
|
export const useSortByFilter = <TSortBy>(defaultValue: null | string, listKey: ItemListKey) => {
|
||||||
|
const server = useCurrentServer();
|
||||||
|
|
||||||
|
const [persisted, setPersisted] = useLocalStorage({
|
||||||
|
defaultValue: defaultValue,
|
||||||
|
key: getPersistenceKey(server.id, listKey),
|
||||||
|
});
|
||||||
|
|
||||||
export const useSortByFilter = <TSortBy>(defaultValue: string) => {
|
|
||||||
const [sortBy, setSortBy] = useQueryState(
|
const [sortBy, setSortBy] = useQueryState(
|
||||||
FILTER_KEYS.SHARED.SORT_BY,
|
FILTER_KEYS.SHARED.SORT_BY,
|
||||||
defaultValue ? parseAsString.withDefault(defaultValue) : parseAsString,
|
getDefaultSortBy(defaultValue, persisted),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleSetSortBy = (sortBy: string) => {
|
||||||
|
setSortBy(sortBy);
|
||||||
|
setPersisted(sortBy);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[FILTER_KEYS.SHARED.SORT_BY]: sortBy as TSortBy,
|
[FILTER_KEYS.SHARED.SORT_BY]: sortBy as TSortBy,
|
||||||
setSortBy,
|
setSortBy: handleSetSortBy,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getDefaultSortBy = (defaultValue: null | string, persisted: null | string) => {
|
||||||
|
if (persisted) {
|
||||||
|
return parseAsString.withDefault(persisted);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultValue) {
|
||||||
|
return parseAsString.withDefault(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseAsString;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPersistenceKey = (serverId: string, listKey: ItemListKey) => {
|
||||||
|
return `${serverId}-list-${listKey}-${FILTER_KEYS.SHARED.SORT_BY}`;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,16 +1,47 @@
|
|||||||
import { parseAsString, useQueryState } from 'nuqs';
|
import { parseAsString, useQueryState } from 'nuqs';
|
||||||
|
|
||||||
import { FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
import { FILTER_KEYS } from '/@/renderer/features/shared/utils';
|
||||||
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
|
import { useLocalStorage } from '/@/shared/hooks/use-local-storage';
|
||||||
import { SortOrder } from '/@/shared/types/domain-types';
|
import { SortOrder } from '/@/shared/types/domain-types';
|
||||||
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
|
export const useSortOrderFilter = (defaultValue: null | string, listKey: ItemListKey) => {
|
||||||
|
const server = useCurrentServer();
|
||||||
|
|
||||||
|
const [persisted, setPersisted] = useLocalStorage({
|
||||||
|
defaultValue: SortOrder.ASC,
|
||||||
|
key: getPersistenceKey(server.id, listKey),
|
||||||
|
});
|
||||||
|
|
||||||
export const useSortOrderFilter = (defaultValue: string) => {
|
|
||||||
const [sortOrder, setSortOrder] = useQueryState(
|
const [sortOrder, setSortOrder] = useQueryState(
|
||||||
FILTER_KEYS.SHARED.SORT_ORDER,
|
FILTER_KEYS.SHARED.SORT_ORDER,
|
||||||
defaultValue ? parseAsString.withDefault(defaultValue) : parseAsString,
|
getDefaultSortOrder(defaultValue, persisted),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleSetSortOrder = (sortOrder: SortOrder) => {
|
||||||
|
setSortOrder(sortOrder);
|
||||||
|
setPersisted(sortOrder);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
[FILTER_KEYS.SHARED.SORT_ORDER]: sortOrder as SortOrder,
|
[FILTER_KEYS.SHARED.SORT_ORDER]: sortOrder as SortOrder,
|
||||||
setSortOrder,
|
setSortOrder: handleSetSortOrder,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getDefaultSortOrder = (defaultValue: null | string, persisted: null | string) => {
|
||||||
|
if (persisted) {
|
||||||
|
return parseAsString.withDefault(persisted);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultValue) {
|
||||||
|
return parseAsString.withDefault(defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseAsString;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPersistenceKey = (serverId: string, listKey: ItemListKey) => {
|
||||||
|
return `${serverId}-list-${listKey}-${FILTER_KEYS.SHARED.SORT_ORDER}`;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user