optimize various base components

This commit is contained in:
jeffvli
2026-01-02 12:46:35 -08:00
parent a66c67e86d
commit d06d1674d1
31 changed files with 669 additions and 393 deletions
@@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query';
import { useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { MultiSelectWithInvalidData } from '/@/renderer/components/select-with-invalid-data';
@@ -147,8 +147,8 @@ export const JellyfinAlbumFilters = ({ disableArtistFilter }: JellyfinAlbumFilte
[setMaxYear],
);
const handleGenresFilter = useMemo(
() => (e: string[] | undefined) => {
const handleGenresFilter = useCallback(
(e: null | string[]) => {
setGenreId(e && e.length > 0 ? e : null);
},
[setGenreId],
@@ -178,13 +178,16 @@ export const JellyfinAlbumFilters = ({ disableArtistFilter }: JellyfinAlbumFilte
}));
}, [albumArtistListQuery.data?.items]);
const handleAlbumArtistFilter = (e: null | string[]) => {
setAlbumArtist(e ?? null);
};
const handleAlbumArtistFilter = useCallback(
(e: null | string[]) => {
setAlbumArtist(e ?? null);
},
[setAlbumArtist],
);
const handleTagFilter = useMemo(
() => (e: string[] | undefined) => {
setCustom({ Tags: e?.join('|') ?? null });
const handleTagFilter = useCallback(
(e: null | string[]) => {
setCustom({ Tags: e && e.length > 0 ? e.join('|') : null });
},
[setCustom],
);
@@ -1,5 +1,5 @@
import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
import { ChangeEvent, useMemo } from 'react';
import { ChangeEvent, useCallback, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { MultiSelectWithInvalidData } from '/@/renderer/components/select-with-invalid-data';
@@ -148,6 +148,28 @@ export const NavidromeAlbumFilters = ({ disableArtistFilter }: NavidromeAlbumFil
const debouncedHandleYearFilter = useDebouncedCallback(handleYearFilter, 300);
const handleGenreChange = useCallback(
(e: null | string[]) => {
if (e && e.length > 0) {
setGenreId(e);
} else {
setGenreId(null);
}
},
[setGenreId],
);
const handleAlbumArtistChange = useCallback(
(e: null | string[]) => {
if (e && e.length > 0) {
setAlbumArtist(e);
} else {
setAlbumArtist(null);
}
},
[setAlbumArtist],
);
return (
<Stack px="md" py="md">
{yesNoUndefinedFilters.map((filter) => (
@@ -180,7 +202,7 @@ export const NavidromeAlbumFilters = ({ disableArtistFilter }: NavidromeAlbumFil
data={genreList}
defaultValue={query.genreIds || []}
label={t('entity.genre', { count: 2, postProcess: 'sentenceCase' })}
onChange={(e) => (e && e.length > 0 ? setGenreId(e) : setGenreId(null))}
onChange={handleGenreChange}
searchable
/>
)}
@@ -191,7 +213,7 @@ export const NavidromeAlbumFilters = ({ disableArtistFilter }: NavidromeAlbumFil
disabled={disableArtistFilter}
label={t('entity.artist', { count: 2, postProcess: 'sentenceCase' })}
limit={300}
onChange={(e) => (e && e.length > 0 ? setAlbumArtist(e) : setAlbumArtist(null))}
onChange={handleAlbumArtistChange}
rightSection={albumArtistListQuery.isFetching ? <SpinnerIcon /> : undefined}
searchable
/>
@@ -224,6 +246,17 @@ const TagFilterItem = ({ label, onChange, options, tagValue, value }: TagFilterI
return Array.isArray(value) ? value : [value];
}, [value]);
const handleChange = useCallback(
(e: null | string[]) => {
if (e && e.length > 0) {
onChange(e);
} else {
onChange(null);
}
},
[onChange],
);
return (
<MultiSelectWithInvalidData
clearable
@@ -232,7 +265,7 @@ const TagFilterItem = ({ label, onChange, options, tagValue, value }: TagFilterI
key={tagValue}
label={label}
limit={100}
onChange={(e) => (e && e.length > 0 ? onChange(e) : onChange(null))}
onChange={handleChange}
searchable
/>
);
@@ -1,5 +1,5 @@
import { useSuspenseQuery } from '@tanstack/react-query';
import { ChangeEvent, useMemo, useState } from 'react';
import { ChangeEvent, useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { MultiSelectWithInvalidData } from '/@/renderer/components/select-with-invalid-data';
@@ -63,8 +63,8 @@ export const SubsonicAlbumFilters = ({ disableArtistFilter }: SubsonicAlbumFilte
}));
}, [items]);
const handleAlbumArtistFilter = useMemo(
() => (e: null | string[]) => {
const handleAlbumArtistFilter = useCallback(
(e: null | string[]) => {
setAlbumArtist(e ?? null);
},
[setAlbumArtist],
@@ -80,8 +80,8 @@ export const SubsonicAlbumFilters = ({ disableArtistFilter }: SubsonicAlbumFilte
}));
}, [genreListQuery.data]);
const handleGenresFilter = useMemo(
() => (e: null | string) => {
const handleGenresFilter = useCallback(
(e: null | string) => {
setGenreId(e ? [e] : null);
},
[setGenreId],
@@ -178,7 +178,7 @@ export const SubsonicAlbumFilters = ({ disableArtistFilter }: SubsonicAlbumFilte
defaultValue={query.genreIds?.[0] ?? undefined}
disabled={Boolean(query.minYear || query.maxYear)}
label={t('entity.genre', { count: 1, postProcess: 'titleCase' })}
onChange={(e) => handleGenresFilter(e)}
onChange={handleGenresFilter}
searchable
/>
)}