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, RiArrowDownSLine, RiArrowUpSLine, RiPlayFill, } from 'react-icons/ri'; import { generatePath } from 'react-router'; import { Link } from 'react-router-dom'; import { LibraryItem, Playlist, PlaylistListSort, SortOrder } 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, useSettingsStoreActions } from '/@/renderer/store'; import { openContextMenu } from '/@/renderer/features/context-menu'; import { PLAYLIST_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items'; const PlaylistRow = ({ index, data, style }: ListChildComponentProps) => { const { t } = useTranslation(); if (Array.isArray(data?.items[index])) { const [collapse, setCollapse] = data.items[index]; return (
{t('page.sidebar.shared', { postProcess: 'titleCase' })}
); } const path = data?.items[index].id ? generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { playlistId: data.items[index].id }) : undefined; return (
{ e.preventDefault(); e.stopPropagation(); if (!data?.items?.[index].id) return; openContextMenu({ data: [data?.items?.[index]], dataNodes: undefined, menuItems: PLAYLIST_CONTEXT_MENU_ITEMS, type: LibraryItem.PLAYLIST, xPos: e.clientX + 15, yPos: e.clientY + 5, }); }} > {data?.items[index].name}
); }; export const SidebarPlaylistList = () => { const { isScrollbarHidden, hideScrollbarElementProps } = useHideScrollbar(0); const handlePlayQueueAdd = usePlayQueueAdd(); const { sidebarCollapseShared } = useGeneralSettings(); const { toggleSidebarCollapseShare } = useSettingsStoreActions(); const server = useCurrentServer(); const playlistsQuery = usePlaylistList({ query: { sortBy: PlaylistListSort.NAME, sortOrder: SortOrder.ASC, startIndex: 0, }, serverId: server?.id, }); 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 data = playlistsQuery.data; const memoizedItemData = useMemo(() => { const base = { handlePlay: handlePlayPlaylist }; if (!server?.type || !server?.username || !data?.items) { return { ...base, items: data?.items }; } const owned: Array void]> = []; const shared: Playlist[] = []; for (const playlist of data.items) { if (playlist.owner && playlist.owner !== server.username) { shared.push(playlist); } else { owned.push(playlist); } } if (shared.length > 0) { owned.push([sidebarCollapseShared, toggleSidebarCollapseShare]); } const final = sidebarCollapseShared ? owned : owned.concat(shared); return { ...base, items: final }; }, [ data?.items, handlePlayPlaylist, server?.type, server?.username, sidebarCollapseShared, toggleSidebarCollapseShare, ]); return ( setRect(e as { height: number; width: number })}> {() => ( {PlaylistRow} )} ); };