mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-20 19:04:23 +02:00
refactor search into individual sections by itemtype, add infinite loader
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { generatePath, useNavigate } from 'react-router';
|
||||
|
||||
import { searchQueries } from '/@/renderer/features/search/api/search-api';
|
||||
import { CollapsibleCommandGroup } from '/@/renderer/features/search/components/collapsible-command-group';
|
||||
import { CommandItemSelectable } from '/@/renderer/features/search/components/command-item-selectable';
|
||||
import { LibraryCommandItem } from '/@/renderer/features/search/components/library-command-item';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import { useCurrentServer } from '/@/renderer/store';
|
||||
import { Box } from '/@/shared/components/box/box';
|
||||
import { Spinner } from '/@/shared/components/spinner/spinner';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
||||
|
||||
interface SearchAlbumArtistsSectionProps {
|
||||
debouncedQuery: string;
|
||||
expanded: boolean;
|
||||
isHome: boolean;
|
||||
onSelectResult: () => void;
|
||||
onToggle: () => void;
|
||||
query: string;
|
||||
}
|
||||
|
||||
export function SearchAlbumArtistsSection({
|
||||
debouncedQuery,
|
||||
expanded,
|
||||
isHome,
|
||||
onSelectResult,
|
||||
onToggle,
|
||||
query,
|
||||
}: SearchAlbumArtistsSectionProps) {
|
||||
const navigate = useNavigate();
|
||||
const server = useCurrentServer();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { data, fetchNextPage, hasNextPage, isFetched, isFetchingNextPage, isLoading } =
|
||||
useInfiniteQuery(
|
||||
searchQueries.searchAlbumArtistsInfinite({
|
||||
enabled: isHome && debouncedQuery !== '' && query !== '',
|
||||
searchTerm: debouncedQuery,
|
||||
serverId: server?.id,
|
||||
}),
|
||||
);
|
||||
|
||||
const artists = data?.pages.flatMap((p) => p.albumArtists) ?? [];
|
||||
const showSection = isHome;
|
||||
const numberOfResults = hasNextPage ? `${artists.length}+` : artists.length;
|
||||
|
||||
if (!showSection) return null;
|
||||
|
||||
return (
|
||||
<CollapsibleCommandGroup
|
||||
expanded={expanded}
|
||||
heading="Artists"
|
||||
onToggle={onToggle}
|
||||
subtitle={isFetched ? t('common.numberOfResults', { numberOfResults }) : undefined}
|
||||
>
|
||||
{isLoading ? (
|
||||
<Box p="md">
|
||||
<Spinner container />
|
||||
</Box>
|
||||
) : (
|
||||
<>
|
||||
{artists.map((artist) => (
|
||||
<CommandItemSelectable
|
||||
key={`search-artist-${artist.id}`}
|
||||
onSelect={() => {
|
||||
navigate(
|
||||
generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||
albumArtistId: artist.id,
|
||||
}),
|
||||
);
|
||||
onSelectResult();
|
||||
}}
|
||||
value={`search-artist-${artist.id}`}
|
||||
>
|
||||
{({ isHighlighted }) => (
|
||||
<LibraryCommandItem
|
||||
disabled={artist?.albumCount === 0}
|
||||
id={artist.id}
|
||||
imageId={artist.imageId}
|
||||
imageUrl={artist.imageUrl}
|
||||
isHighlighted={isHighlighted}
|
||||
itemType={LibraryItem.ALBUM_ARTIST}
|
||||
subtitle={
|
||||
artist?.albumCount !== undefined &&
|
||||
artist?.albumCount !== null
|
||||
? t('entity.albumWithCount', {
|
||||
count: artist.albumCount,
|
||||
})
|
||||
: undefined
|
||||
}
|
||||
title={artist.name}
|
||||
/>
|
||||
)}
|
||||
</CommandItemSelectable>
|
||||
))}
|
||||
{hasNextPage && (
|
||||
<CommandItemSelectable
|
||||
disabled={isFetchingNextPage}
|
||||
onSelect={() => fetchNextPage()}
|
||||
value="search-artists-load-more"
|
||||
>
|
||||
{() => (
|
||||
<Text>
|
||||
{isFetchingNextPage ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<Text size="sm">
|
||||
{t('action.viewMore', { postProcess: 'titleCase' })}
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
</CommandItemSelectable>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</CollapsibleCommandGroup>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user