Refactor all api instances in components

This commit is contained in:
jeffvli 2023-04-30 22:01:52 -07:00
parent bdd023fde3
commit 314bd766df
56 changed files with 879 additions and 755 deletions

View file

@ -9,30 +9,32 @@ interface JellyfinSongFiltersProps {
handleFilterChange: (filters: SongListFilter) => void;
id?: string;
pageKey: string;
serverId?: string;
}
export const JellyfinSongFilters = ({
id,
pageKey,
handleFilterChange,
serverId,
}: JellyfinSongFiltersProps) => {
const { setFilter } = useListStoreActions();
const filter = useSongListFilter({ id, key: pageKey });
// TODO - eventually replace with /items/filters endpoint to fetch genres and tags specific to the selected library
const genreListQuery = useGenreList(null);
const genreListQuery = useGenreList({ query: null, serverId });
const genreList = useMemo(() => {
if (!genreListQuery?.data) return [];
return genreListQuery.data.map((genre) => ({
return genreListQuery.data.items.map((genre) => ({
label: genre.name,
value: genre.id,
}));
}, [genreListQuery.data]);
const selectedGenres = useMemo(() => {
return filter.jfParams?.genreIds?.split(',');
}, [filter.jfParams?.genreIds]);
return filter._custom?.jellyfin?.genreIds?.split(',');
}, [filter._custom?.jellyfin?.genreIds]);
const toggleFilters = [
{
@ -40,17 +42,20 @@ export const JellyfinSongFilters = ({
onChange: (e: ChangeEvent<HTMLInputElement>) => {
const updatedFilters = setFilter({
data: {
jfParams: {
...filter.jfParams,
includeItemTypes: 'Audio',
isFavorite: e.currentTarget.checked ? true : undefined,
_custom: {
...filter._custom,
jellyfin: {
...filter._custom?.jellyfin,
includeItemTypes: 'Audio',
isFavorite: e.currentTarget.checked ? true : undefined,
},
},
},
key: pageKey,
}) as SongListFilter;
handleFilterChange(updatedFilters);
},
value: filter.jfParams?.isFavorite,
value: filter._custom?.jellyfin?.isFavorite,
},
];
@ -58,10 +63,13 @@ export const JellyfinSongFilters = ({
if (typeof e === 'number' && (e < 1700 || e > 2300)) return;
const updatedFilters = setFilter({
data: {
jfParams: {
...filter.jfParams,
includeItemTypes: 'Audio',
minYear: e === '' ? undefined : (e as number),
_custom: {
...filter._custom,
jellyfin: {
...filter._custom?.jellyfin,
includeItemTypes: 'Audio',
minYear: e === '' ? undefined : (e as number),
},
},
},
key: pageKey,
@ -73,10 +81,13 @@ export const JellyfinSongFilters = ({
if (typeof e === 'number' && (e < 1700 || e > 2300)) return;
const updatedFilters = setFilter({
data: {
jfParams: {
...filter.jfParams,
includeItemTypes: 'Audio',
maxYear: e === '' ? undefined : (e as number),
_custom: {
...filter._custom,
jellyfin: {
...filter._custom?.jellyfin,
includeItemTypes: 'Audio',
maxYear: e === '' ? undefined : (e as number),
},
},
},
key: pageKey,
@ -88,10 +99,13 @@ export const JellyfinSongFilters = ({
const genreFilterString = e?.length ? e.join(',') : undefined;
const updatedFilters = setFilter({
data: {
jfParams: {
...filter.jfParams,
genreIds: genreFilterString,
includeItemTypes: 'Audio',
_custom: {
...filter._custom,
jellyfin: {
...filter._custom?.jellyfin,
genreIds: genreFilterString,
includeItemTypes: 'Audio',
},
},
},
key: pageKey,
@ -117,14 +131,14 @@ export const JellyfinSongFilters = ({
<Group grow>
<NumberInput
required
defaultValue={filter.jfParams?.minYear}
defaultValue={filter._custom?.jellyfin?.minYear}
label="From year"
max={2300}
min={1700}
onChange={handleMinYearFilter}
/>
<NumberInput
defaultValue={filter.jfParams?.maxYear}
defaultValue={filter._custom?.jellyfin?.maxYear}
label="To year"
max={2300}
min={1700}

View file

@ -9,21 +9,23 @@ interface NavidromeSongFiltersProps {
handleFilterChange: (filters: SongListFilter) => void;
id?: string;
pageKey: string;
serverId?: string;
}
export const NavidromeSongFilters = ({
handleFilterChange,
pageKey,
id,
serverId,
}: NavidromeSongFiltersProps) => {
const { setFilter } = useListStoreActions();
const filter = useSongListFilter({ id, key: pageKey });
const genreListQuery = useGenreList(null);
const genreListQuery = useGenreList({ query: null, serverId });
const genreList = useMemo(() => {
if (!genreListQuery?.data) return [];
return genreListQuery.data.map((genre) => ({
return genreListQuery.data.items.map((genre) => ({
label: genre.name,
value: genre.id,
}));
@ -32,9 +34,11 @@ export const NavidromeSongFilters = ({
const handleGenresFilter = debounce((e: string | null) => {
const updatedFilters = setFilter({
data: {
ndParams: {
...filter.ndParams,
genre_id: e || undefined,
_custom: {
...filter._custom,
navidrome: {
genre_id: e || undefined,
},
},
},
key: pageKey,
@ -48,23 +52,30 @@ export const NavidromeSongFilters = ({
onChange: (e: ChangeEvent<HTMLInputElement>) => {
const updatedFilters = setFilter({
data: {
ndParams: { ...filter.ndParams, starred: e.currentTarget.checked ? true : undefined },
_custom: {
...filter._custom,
navidrome: {
starred: e.currentTarget.checked ? true : undefined,
},
},
},
key: pageKey,
}) as SongListFilter;
handleFilterChange(updatedFilters);
},
value: filter.ndParams?.starred,
value: filter._custom?.navidrome?.starred,
},
];
const handleYearFilter = debounce((e: number | string) => {
const updatedFilters = setFilter({
data: {
ndParams: {
...filter.ndParams,
year: e === '' ? undefined : (e as number),
_custom: {
...filter._custom,
navidrome: {
year: e === '' ? undefined : (e as number),
},
},
},
key: pageKey,
@ -94,7 +105,7 @@ export const NavidromeSongFilters = ({
label="Year"
max={5000}
min={0}
value={filter.ndParams?.year}
value={filter._custom?.navidrome?.year}
width={50}
onChange={(e) => handleYearFilter(e)}
/>
@ -102,7 +113,7 @@ export const NavidromeSongFilters = ({
clearable
searchable
data={genreList}
defaultValue={filter.ndParams?.genre_id}
defaultValue={filter._custom?.navidrome?.genre_id}
label="Genre"
width={150}
onChange={handleGenresFilter}

View file

@ -12,12 +12,6 @@ import { Stack } from '@mantine/core';
import { useQueryClient } from '@tanstack/react-query';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import {
getColumnDefs,
TablePagination,
VirtualGridAutoSizerContainer,
VirtualTable,
} from '/@/renderer/components';
import {
useCurrentServer,
useListStoreActions,
@ -33,6 +27,8 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
import { LibraryItem, QueueSong, SongListQuery } from '/@/renderer/api/types';
import { usePlayQueueAdd } from '/@/renderer/features/player';
import { useSongListContext } from '/@/renderer/features/songs/context/song-list-context';
import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-grid';
import { getColumnDefs, VirtualTable, TablePagination } from '/@/renderer/components/virtual-table';
interface SongListContentProps {
itemCount?: number;
@ -74,9 +70,11 @@ export const SongListContent = ({ itemCount, tableRef }: SongListContentProps) =
queryKey,
async ({ signal }) =>
api.controller.getSongList({
apiClientProps: {
server,
signal,
},
query,
server,
signal,
}),
{ cacheTime: 1000 * 60 * 1 },
);

View file

@ -17,15 +17,7 @@ import {
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
import { LibraryItem, SongListQuery, SongListSort, SortOrder } from '/@/renderer/api/types';
import {
DropdownMenu,
SONG_TABLE_COLUMNS,
Button,
Slider,
MultiSelect,
Switch,
Text,
} from '/@/renderer/components';
import { DropdownMenu, Button, Slider, MultiSelect, Switch, Text } from '/@/renderer/components';
import { usePlayQueueAdd } from '/@/renderer/features/player';
import { useMusicFolders } from '/@/renderer/features/shared';
import { JellyfinSongFilters } from '/@/renderer/features/songs/components/jellyfin-song-filters';
@ -42,6 +34,7 @@ import {
} from '/@/renderer/store';
import { ListDisplayType, ServerType, Play, TableColumn } from '/@/renderer/types';
import { useSongListContext } from '/@/renderer/features/songs/context/song-list-context';
import { SONG_TABLE_COLUMNS } from '/@/renderer/components/virtual-table';
const FILTERS = {
jellyfin: [
@ -100,7 +93,7 @@ export const SongListHeaderFilters = ({
const handlePlayQueueAdd = usePlayQueueAdd();
const cq = useContainerQuery();
const musicFoldersQuery = useMusicFolders();
const musicFoldersQuery = useMusicFolders({ query: null, serverId: server?.id });
const sortByLabel =
(server?.type &&
@ -133,9 +126,11 @@ export const SongListHeaderFilters = ({
queryKey,
async ({ signal }) =>
api.controller.getSongList({
apiClientProps: {
server,
signal,
},
query,
server,
signal,
}),
{ cacheTime: 1000 * 60 * 1 },
);
@ -306,18 +301,18 @@ export const SongListHeaderFilters = ({
const isFilterApplied = useMemo(() => {
const isNavidromeFilterApplied =
server?.type === ServerType.NAVIDROME &&
filter.ndParams &&
Object.values(filter.ndParams).some((value) => value !== undefined);
filter._custom?.navidrome &&
Object.values(filter._custom?.navidrome).some((value) => value !== undefined);
const isJellyfinFilterApplied =
server?.type === ServerType.JELLYFIN &&
filter.jfParams &&
Object.values(filter.jfParams)
filter._custom?.jellyfin &&
Object.values(filter._custom?.jellyfin)
.filter((value) => value !== 'Audio') // Don't account for includeItemTypes: Audio
.some((value) => value !== undefined);
return isNavidromeFilterApplied || isJellyfinFilterApplied;
}, [filter.jfParams, filter.ndParams, server?.type]);
}, [filter._custom?.jellyfin, filter._custom?.navidrome, server?.type]);
return (
<Flex justify="space-between">
@ -382,7 +377,7 @@ export const SongListHeaderFilters = ({
</Button>
</DropdownMenu.Target>
<DropdownMenu.Dropdown>
{musicFoldersQuery.data?.map((folder) => (
{musicFoldersQuery.data?.items.map((folder) => (
<DropdownMenu.Item
key={`musicFolder-${folder.id}`}
$isActive={filter.musicFolderId === folder.id}

View file

@ -64,15 +64,16 @@ export const SongListHeader = ({
queryKey,
async ({ signal }) =>
api.controller.getSongList({
apiClientProps: {
server,
signal,
},
query,
server,
signal,
}),
{ cacheTime: 1000 * 60 * 1 },
);
const songs = api.normalize.songList(songsRes, server);
params.successCallback(songs?.items || [], songsRes?.totalRecordCount || 0);
params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0);
},
rowCount: undefined,
};

View file

@ -19,17 +19,18 @@ const TrackListRoute = () => {
);
const songListFilter = useSongListFilter({ id: albumArtistId, key: pageKey });
const itemCountCheck = useSongList(
{
const itemCountCheck = useSongList({
options: {
cacheTime: 1000 * 60,
staleTime: 1000 * 60,
},
query: {
limit: 1,
startIndex: 0,
...songListFilter,
},
{
cacheTime: 1000 * 60,
staleTime: 1000 * 60,
},
);
serverId: server?.id,
});
const itemCount =
itemCountCheck.data?.totalRecordCount === null