mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 18:33:33 +00:00
Refactor all api instances in components
This commit is contained in:
parent
bdd023fde3
commit
314bd766df
56 changed files with 879 additions and 755 deletions
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue