import { useQueryClient } from '@tanstack/react-query'; import { MutableRefObject, useCallback, useMemo } from 'react'; import AutoSizer, { Size } from 'react-virtualized-auto-sizer'; import { ListOnScrollProps } from 'react-window'; import { useListContext } from '../../../context/list-context'; import { useListStoreActions } from '../../../store/list.store'; import { controller } from '/@/renderer/api/controller'; import { queryKeys } from '/@/renderer/api/query-keys'; import { LibraryItem, Playlist, PlaylistListQuery, PlaylistListSort } from '/@/renderer/api/types'; import { PLAYLIST_CARD_ROWS } from '/@/renderer/components'; import { VirtualGridAutoSizerContainer, VirtualInfiniteGrid, VirtualInfiniteGridRef, } from '/@/renderer/components/virtual-grid'; import { usePlayQueueAdd } from '/@/renderer/features/player'; import { useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared'; import { AppRoute } from '/@/renderer/router/routes'; import { useCurrentServer, useGeneralSettings, useListStoreByKey } from '/@/renderer/store'; import { CardRow, ListDisplayType } from '/@/renderer/types'; interface PlaylistListGridViewProps { gridRef: MutableRefObject; itemCount?: number; } export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridViewProps) => { const { pageKey } = useListContext(); const queryClient = useQueryClient(); const server = useCurrentServer(); const handlePlayQueueAdd = usePlayQueueAdd(); const { display, grid, filter } = useListStoreByKey({ key: pageKey }); const { setGrid } = useListStoreActions(); const { defaultFullPlaylist } = useGeneralSettings(); const createFavoriteMutation = useCreateFavorite({}); const deleteFavoriteMutation = useDeleteFavorite({}); const handleFavorite = (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem; }) => { const { id, itemType, isFavorite } = options; if (isFavorite) { deleteFavoriteMutation.mutate({ query: { id, type: itemType, }, serverId: server?.id, }); } else { createFavoriteMutation.mutate({ query: { id, type: itemType, }, serverId: server?.id, }); } }; const cardRows = useMemo(() => { const rows: CardRow[] = defaultFullPlaylist ? [PLAYLIST_CARD_ROWS.nameFull] : [PLAYLIST_CARD_ROWS.name]; switch (filter.sortBy) { case PlaylistListSort.DURATION: rows.push(PLAYLIST_CARD_ROWS.duration); break; case PlaylistListSort.NAME: rows.push(PLAYLIST_CARD_ROWS.songCount); break; case PlaylistListSort.SONG_COUNT: rows.push(PLAYLIST_CARD_ROWS.songCount); break; case PlaylistListSort.OWNER: rows.push(PLAYLIST_CARD_ROWS.owner); break; case PlaylistListSort.PUBLIC: rows.push(PLAYLIST_CARD_ROWS.public); break; case PlaylistListSort.UPDATED_AT: break; } return rows; }, [defaultFullPlaylist, filter.sortBy]); const handleGridScroll = useCallback( (e: ListOnScrollProps) => { setGrid({ data: { scrollOffset: e.scrollOffset }, key: pageKey }); }, [pageKey, setGrid], ); const fetch = useCallback( async ({ skip, take }: { skip: number; take: number }) => { if (!server) { return []; } const query: PlaylistListQuery = { limit: take, startIndex: skip, ...filter, _custom: {}, }; const queryKey = queryKeys.playlists.list(server?.id || '', query); const playlists = await queryClient.fetchQuery(queryKey, async ({ signal }) => controller.getPlaylistList({ apiClientProps: { server, signal, }, query, }), ); return playlists; }, [filter, queryClient, server], ); return ( {({ height, width }: Size) => ( )} ); };