import { useCallback, useMemo, useState } from 'react'; import { Box, Flex, Group } from '@mantine/core'; import { useDebouncedValue } from '@mantine/hooks'; import { useTranslation } from 'react-i18next'; import { RiAddBoxFill, RiAddCircleFill, RiPlayFill } from 'react-icons/ri'; import { generatePath } from 'react-router'; import { Link } from 'react-router-dom'; import { LibraryItem, Playlist } from '/@/renderer/api/types'; import { Button, Text } from '/@/renderer/components'; import { usePlayQueueAdd } from '/@/renderer/features/player'; import { usePlaylistList } from '/@/renderer/features/playlists'; import { AppRoute } from '/@/renderer/router/routes'; import { Play } from '/@/renderer/types'; import AutoSizer from 'react-virtualized-auto-sizer'; import { FixedSizeList, ListChildComponentProps } from 'react-window'; import { useHideScrollbar } from '/@/renderer/hooks'; import { useCurrentServer, useGeneralSettings } from '/@/renderer/store'; interface SidebarPlaylistListProps { data: ReturnType['data']; } const PlaylistRow = ({ index, data, style }: ListChildComponentProps) => { const { t } = useTranslation(); if (data?.items[index] === null) { return (
{t('page.sidebar.shared', { postProcess: 'titleCase' })}
); } const path = data?.items[index].id ? data.defaultFullPlaylist ? generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { playlistId: data.items[index].id }) : generatePath(AppRoute.PLAYLISTS_DETAIL, { playlistId: data?.items[index].id, }) : undefined; return (
{data?.items[index].name}
); }; export const SidebarPlaylistList = ({ data }: SidebarPlaylistListProps) => { const { isScrollbarHidden, hideScrollbarElementProps } = useHideScrollbar(0); const handlePlayQueueAdd = usePlayQueueAdd(); const { defaultFullPlaylist } = useGeneralSettings(); const { type, username } = useCurrentServer() || {}; const [rect, setRect] = useState({ height: 0, width: 0, }); const [debounced] = useDebouncedValue(rect, 25); const handlePlayPlaylist = useCallback( (id: string, playType: Play) => { handlePlayQueueAdd?.({ byItemType: { id: [id], type: LibraryItem.PLAYLIST, }, playType, }); }, [handlePlayQueueAdd], ); const memoizedItemData = useMemo(() => { const base = { defaultFullPlaylist, handlePlay: handlePlayPlaylist }; if (!type || !username || !data?.items) { return { ...base, items: data?.items }; } const owned: Array = []; const shared: Playlist[] = []; for (const playlist of data.items) { if (playlist.owner !== username) { shared.push(playlist); } else { owned.push(playlist); } } if (shared.length > 0) { // Use `null` as a separator between owned and shared playlists owned.push(null); } return { ...base, items: owned.concat(shared) }; }, [data?.items, defaultFullPlaylist, handlePlayPlaylist, type, username]); return ( setRect(e as { height: number; width: number })}> {() => ( {PlaylistRow} )} ); };