Update playlist list implementation
This commit is contained in:
parent
8b4a2d1ac0
commit
85964bfded
8 changed files with 77 additions and 130 deletions
|
@ -1,8 +1,8 @@
|
||||||
|
import { MutableRefObject, useMemo, useRef } from 'react';
|
||||||
import { ColDef, RowDoubleClickedEvent } from '@ag-grid-community/core';
|
import { ColDef, RowDoubleClickedEvent } from '@ag-grid-community/core';
|
||||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||||
import { Box, Group } from '@mantine/core';
|
import { Box, Group } from '@mantine/core';
|
||||||
import { closeAllModals, openModal } from '@mantine/modals';
|
import { closeAllModals, openModal } from '@mantine/modals';
|
||||||
import { MutableRefObject, useMemo, useRef } from 'react';
|
|
||||||
import { RiMoreFill } from 'react-icons/ri';
|
import { RiMoreFill } from 'react-icons/ri';
|
||||||
import { generatePath, useNavigate, useParams } from 'react-router';
|
import { generatePath, useNavigate, useParams } from 'react-router';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
@ -27,9 +27,10 @@ import { usePlaylistDetail } from '/@/renderer/features/playlists/queries/playli
|
||||||
import { usePlaylistSongListInfinite } from '/@/renderer/features/playlists/queries/playlist-song-list-query';
|
import { usePlaylistSongListInfinite } from '/@/renderer/features/playlists/queries/playlist-song-list-query';
|
||||||
import { PlayButton, PLAY_TYPES } from '/@/renderer/features/shared';
|
import { PlayButton, PLAY_TYPES } from '/@/renderer/features/shared';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { useCurrentServer, useSongListStore } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
||||||
import { Play } from '/@/renderer/types';
|
import { Play } from '/@/renderer/types';
|
||||||
|
import { useListStoreByKey } from '../../../store/list.store';
|
||||||
|
|
||||||
const ContentContainer = styled.div`
|
const ContentContainer = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -54,7 +55,7 @@ interface PlaylistDetailContentProps {
|
||||||
export const PlaylistDetailContent = ({ tableRef }: PlaylistDetailContentProps) => {
|
export const PlaylistDetailContent = ({ tableRef }: PlaylistDetailContentProps) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { playlistId } = useParams() as { playlistId: string };
|
const { playlistId } = useParams() as { playlistId: string };
|
||||||
const page = useSongListStore();
|
const { table } = useListStoreByKey({ key: LibraryItem.SONG });
|
||||||
const handlePlayQueueAdd = usePlayQueueAdd();
|
const handlePlayQueueAdd = usePlayQueueAdd();
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
||||||
|
@ -79,10 +80,8 @@ export const PlaylistDetailContent = ({ tableRef }: PlaylistDetailContentProps)
|
||||||
|
|
||||||
const columnDefs: ColDef[] = useMemo(
|
const columnDefs: ColDef[] = useMemo(
|
||||||
() =>
|
() =>
|
||||||
getColumnDefs(page.table.columns).filter(
|
getColumnDefs(table.columns).filter((c) => c.colId !== 'album' && c.colId !== 'artist'),
|
||||||
(c) => c.colId !== 'album' && c.colId !== 'artist',
|
[table.columns],
|
||||||
),
|
|
||||||
[page.table.columns],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const contextMenuItems = useMemo(() => {
|
const contextMenuItems = useMemo(() => {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
|
||||||
import { lazy, MutableRefObject, Suspense } from 'react';
|
import { lazy, MutableRefObject, Suspense } from 'react';
|
||||||
|
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||||
import { Spinner } from '/@/renderer/components';
|
import { Spinner } from '/@/renderer/components';
|
||||||
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid';
|
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid';
|
||||||
import { usePlaylistListStore } from '/@/renderer/store';
|
|
||||||
import { ListDisplayType } from '/@/renderer/types';
|
import { ListDisplayType } from '/@/renderer/types';
|
||||||
|
import { useListContext } from '../../../context/list-context';
|
||||||
|
import { useListStoreByKey } from '../../../store/list.store';
|
||||||
|
|
||||||
const PlaylistListTableView = lazy(() =>
|
const PlaylistListTableView = lazy(() =>
|
||||||
import('/@/renderer/features/playlists/components/playlist-list-table-view').then((module) => ({
|
import('/@/renderer/features/playlists/components/playlist-list-table-view').then((module) => ({
|
||||||
|
@ -24,7 +25,8 @@ interface PlaylistListContentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PlaylistListContent = ({ gridRef, tableRef, itemCount }: PlaylistListContentProps) => {
|
export const PlaylistListContent = ({ gridRef, tableRef, itemCount }: PlaylistListContentProps) => {
|
||||||
const { display } = usePlaylistListStore();
|
const { pageKey } = useListContext();
|
||||||
|
const { display } = useListStoreByKey({ key: pageKey });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<Spinner container />}>
|
<Suspense fallback={<Spinner container />}>
|
||||||
|
|
|
@ -2,7 +2,8 @@ import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { MutableRefObject, useCallback, useMemo } from 'react';
|
import { MutableRefObject, useCallback, useMemo } from 'react';
|
||||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||||
import { ListOnScrollProps } from 'react-window';
|
import { ListOnScrollProps } from 'react-window';
|
||||||
import { usePlaylistGridStore, usePlaylistStoreActions } from '../../../store/playlist.store';
|
import { useListContext } from '../../../context/list-context';
|
||||||
|
import { useListStoreActions } from '../../../store/list.store';
|
||||||
import { controller } from '/@/renderer/api/controller';
|
import { controller } from '/@/renderer/api/controller';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { LibraryItem, Playlist, PlaylistListQuery, PlaylistListSort } from '/@/renderer/api/types';
|
import { LibraryItem, Playlist, PlaylistListQuery, PlaylistListSort } from '/@/renderer/api/types';
|
||||||
|
@ -15,7 +16,7 @@ import {
|
||||||
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
||||||
import { useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared';
|
import { useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { useCurrentServer, useGeneralSettings, usePlaylistListStore } from '/@/renderer/store';
|
import { useCurrentServer, useGeneralSettings, useListStoreByKey } from '/@/renderer/store';
|
||||||
import { CardRow, ListDisplayType } from '/@/renderer/types';
|
import { CardRow, ListDisplayType } from '/@/renderer/types';
|
||||||
|
|
||||||
interface PlaylistListGridViewProps {
|
interface PlaylistListGridViewProps {
|
||||||
|
@ -24,13 +25,12 @@ interface PlaylistListGridViewProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridViewProps) => {
|
export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridViewProps) => {
|
||||||
|
const { pageKey } = useListContext();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
const handlePlayQueueAdd = usePlayQueueAdd();
|
const handlePlayQueueAdd = usePlayQueueAdd();
|
||||||
const { display } = usePlaylistListStore();
|
const { display, grid, filter } = useListStoreByKey({ key: pageKey });
|
||||||
const grid = usePlaylistGridStore();
|
const { setGrid } = useListStoreActions();
|
||||||
const { setGrid } = usePlaylistStoreActions();
|
|
||||||
const page = usePlaylistListStore();
|
|
||||||
const { defaultFullPlaylist } = useGeneralSettings();
|
const { defaultFullPlaylist } = useGeneralSettings();
|
||||||
|
|
||||||
const createFavoriteMutation = useCreateFavorite({});
|
const createFavoriteMutation = useCreateFavorite({});
|
||||||
|
@ -66,7 +66,7 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
||||||
? [PLAYLIST_CARD_ROWS.nameFull]
|
? [PLAYLIST_CARD_ROWS.nameFull]
|
||||||
: [PLAYLIST_CARD_ROWS.name];
|
: [PLAYLIST_CARD_ROWS.name];
|
||||||
|
|
||||||
switch (page.filter.sortBy) {
|
switch (filter.sortBy) {
|
||||||
case PlaylistListSort.DURATION:
|
case PlaylistListSort.DURATION:
|
||||||
rows.push(PLAYLIST_CARD_ROWS.duration);
|
rows.push(PLAYLIST_CARD_ROWS.duration);
|
||||||
break;
|
break;
|
||||||
|
@ -87,13 +87,13 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
||||||
}
|
}
|
||||||
|
|
||||||
return rows;
|
return rows;
|
||||||
}, [defaultFullPlaylist, page.filter.sortBy]);
|
}, [defaultFullPlaylist, filter.sortBy]);
|
||||||
|
|
||||||
const handleGridScroll = useCallback(
|
const handleGridScroll = useCallback(
|
||||||
(e: ListOnScrollProps) => {
|
(e: ListOnScrollProps) => {
|
||||||
setGrid({ data: { scrollOffset: e.scrollOffset } });
|
setGrid({ data: { scrollOffset: e.scrollOffset }, key: pageKey });
|
||||||
},
|
},
|
||||||
[setGrid],
|
[pageKey, setGrid],
|
||||||
);
|
);
|
||||||
|
|
||||||
const fetch = useCallback(
|
const fetch = useCallback(
|
||||||
|
@ -105,7 +105,7 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
||||||
const query: PlaylistListQuery = {
|
const query: PlaylistListQuery = {
|
||||||
limit: take,
|
limit: take,
|
||||||
startIndex: skip,
|
startIndex: skip,
|
||||||
...page.filter,
|
...filter,
|
||||||
_custom: {},
|
_custom: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ export const PlaylistListGridView = ({ gridRef, itemCount }: PlaylistListGridVie
|
||||||
|
|
||||||
return playlists;
|
return playlists;
|
||||||
},
|
},
|
||||||
[page.filter, queryClient, server],
|
[filter, queryClient, server],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -4,6 +4,8 @@ import { Divider, Flex, Group, Stack } from '@mantine/core';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { ChangeEvent, MouseEvent, MutableRefObject, useCallback } from 'react';
|
import { ChangeEvent, MouseEvent, MutableRefObject, useCallback } from 'react';
|
||||||
import { RiMoreFill, RiRefreshLine, RiSettings3Fill } from 'react-icons/ri';
|
import { RiMoreFill, RiRefreshLine, RiSettings3Fill } from 'react-icons/ri';
|
||||||
|
import { useListContext } from '../../../context/list-context';
|
||||||
|
import { useListStoreByKey } from '../../../store/list.store';
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { LibraryItem, PlaylistListQuery, PlaylistListSort, SortOrder } from '/@/renderer/api/types';
|
import { LibraryItem, PlaylistListQuery, PlaylistListSort, SortOrder } from '/@/renderer/api/types';
|
||||||
|
@ -12,12 +14,7 @@ import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid';
|
||||||
import { PLAYLIST_TABLE_COLUMNS } from '/@/renderer/components/virtual-table';
|
import { PLAYLIST_TABLE_COLUMNS } from '/@/renderer/components/virtual-table';
|
||||||
import { OrderToggleButton } from '/@/renderer/features/shared';
|
import { OrderToggleButton } from '/@/renderer/features/shared';
|
||||||
import { useContainerQuery } from '/@/renderer/hooks';
|
import { useContainerQuery } from '/@/renderer/hooks';
|
||||||
import {
|
import { PlaylistListFilter, useCurrentServer, useListStoreActions } from '/@/renderer/store';
|
||||||
PlaylistListFilter,
|
|
||||||
useCurrentServer,
|
|
||||||
useListStoreActions,
|
|
||||||
usePlaylistListStore,
|
|
||||||
} from '/@/renderer/store';
|
|
||||||
import { ListDisplayType, TableColumn } from '/@/renderer/types';
|
import { ListDisplayType, TableColumn } from '/@/renderer/types';
|
||||||
|
|
||||||
const FILTERS = {
|
const FILTERS = {
|
||||||
|
@ -45,12 +42,12 @@ export const PlaylistListHeaderFilters = ({
|
||||||
gridRef,
|
gridRef,
|
||||||
tableRef,
|
tableRef,
|
||||||
}: PlaylistListHeaderFiltersProps) => {
|
}: PlaylistListHeaderFiltersProps) => {
|
||||||
const pageKey = 'playlist';
|
const { pageKey } = useListContext();
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
const { setFilter, setTable, setTablePagination, setGrid, setDisplayType } =
|
const { setFilter, setTable, setTablePagination, setGrid, setDisplayType } =
|
||||||
useListStoreActions();
|
useListStoreActions();
|
||||||
const { display, filter, table, grid } = usePlaylistListStore({ key: pageKey });
|
const { display, filter, table, grid } = useListStoreByKey({ key: pageKey });
|
||||||
const cq = useContainerQuery();
|
const cq = useContainerQuery();
|
||||||
|
|
||||||
const isGrid = display === ListDisplayType.CARD || display === ListDisplayType.POSTER;
|
const isGrid = display === ListDisplayType.CARD || display === ListDisplayType.POSTER;
|
||||||
|
@ -146,7 +143,17 @@ export const PlaylistListHeaderFilters = ({
|
||||||
setTablePagination({ data: { currentPage: 0 }, key: pageKey });
|
setTablePagination({ data: { currentPage: 0 }, key: pageKey });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[isGrid, gridRef, fetch, filter, tableRef, setTablePagination, server, queryClient],
|
[
|
||||||
|
isGrid,
|
||||||
|
gridRef,
|
||||||
|
fetch,
|
||||||
|
filter,
|
||||||
|
tableRef,
|
||||||
|
setTablePagination,
|
||||||
|
pageKey,
|
||||||
|
server,
|
||||||
|
queryClient,
|
||||||
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSetSortBy = useCallback(
|
const handleSetSortBy = useCallback(
|
||||||
|
@ -168,7 +175,7 @@ export const PlaylistListHeaderFilters = ({
|
||||||
|
|
||||||
handleFilterChange(updatedFilters);
|
handleFilterChange(updatedFilters);
|
||||||
},
|
},
|
||||||
[handleFilterChange, server?.type, setFilter],
|
[handleFilterChange, pageKey, server?.type, setFilter],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleToggleSortOrder = useCallback(() => {
|
const handleToggleSortOrder = useCallback(() => {
|
||||||
|
@ -179,14 +186,14 @@ export const PlaylistListHeaderFilters = ({
|
||||||
key: pageKey,
|
key: pageKey,
|
||||||
}) as PlaylistListFilter;
|
}) as PlaylistListFilter;
|
||||||
handleFilterChange(updatedFilters);
|
handleFilterChange(updatedFilters);
|
||||||
}, [filter.sortOrder, handleFilterChange, setFilter]);
|
}, [filter.sortOrder, handleFilterChange, pageKey, setFilter]);
|
||||||
|
|
||||||
const handleSetViewType = useCallback(
|
const handleSetViewType = useCallback(
|
||||||
(e: MouseEvent<HTMLButtonElement>) => {
|
(e: MouseEvent<HTMLButtonElement>) => {
|
||||||
if (!e.currentTarget?.value) return;
|
if (!e.currentTarget?.value) return;
|
||||||
setDisplayType({ data: e.currentTarget.value as ListDisplayType, key: pageKey });
|
setDisplayType({ data: e.currentTarget.value as ListDisplayType, key: pageKey });
|
||||||
},
|
},
|
||||||
[setDisplayType],
|
[pageKey, setDisplayType],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleTableColumns = (values: TableColumn[]) => {
|
const handleTableColumns = (values: TableColumn[]) => {
|
||||||
|
|
|
@ -8,18 +8,14 @@ import { CreatePlaylistForm } from '/@/renderer/features/playlists/components/cr
|
||||||
import { PlaylistListHeaderFilters } from '/@/renderer/features/playlists/components/playlist-list-header-filters';
|
import { PlaylistListHeaderFilters } from '/@/renderer/features/playlists/components/playlist-list-header-filters';
|
||||||
import { LibraryHeaderBar } from '/@/renderer/features/shared';
|
import { LibraryHeaderBar } from '/@/renderer/features/shared';
|
||||||
import { useContainerQuery } from '/@/renderer/hooks';
|
import { useContainerQuery } from '/@/renderer/hooks';
|
||||||
import {
|
import { PlaylistListFilter, useCurrentServer, useListStoreActions } from '/@/renderer/store';
|
||||||
PlaylistListFilter,
|
|
||||||
useCurrentServer,
|
|
||||||
useListStoreActions,
|
|
||||||
usePlaylistListFilter,
|
|
||||||
usePlaylistListStore,
|
|
||||||
} from '/@/renderer/store';
|
|
||||||
import { ListDisplayType, ServerType } from '/@/renderer/types';
|
import { ListDisplayType, ServerType } from '/@/renderer/types';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import { RiFileAddFill } from 'react-icons/ri';
|
import { RiFileAddFill } from 'react-icons/ri';
|
||||||
import { LibraryItem } from '/@/renderer/api/types';
|
import { LibraryItem } from '/@/renderer/api/types';
|
||||||
import { useListFilterRefresh } from '../../../hooks/use-list-filter-refresh';
|
import { useListFilterRefresh } from '../../../hooks/use-list-filter-refresh';
|
||||||
|
import { useListContext } from '/@/renderer/context/list-context';
|
||||||
|
import { useListStoreByKey } from '../../../store/list.store';
|
||||||
|
|
||||||
interface PlaylistListHeaderProps {
|
interface PlaylistListHeaderProps {
|
||||||
gridRef: MutableRefObject<VirtualInfiniteGridRef | null>;
|
gridRef: MutableRefObject<VirtualInfiniteGridRef | null>;
|
||||||
|
@ -28,12 +24,11 @@ interface PlaylistListHeaderProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PlaylistListHeader = ({ itemCount, tableRef, gridRef }: PlaylistListHeaderProps) => {
|
export const PlaylistListHeader = ({ itemCount, tableRef, gridRef }: PlaylistListHeaderProps) => {
|
||||||
const pageKey = 'playlist';
|
const { pageKey } = useListContext();
|
||||||
const cq = useContainerQuery();
|
const cq = useContainerQuery();
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
const { setFilter, setTablePagination } = useListStoreActions();
|
const { setFilter, setTablePagination } = useListStoreActions();
|
||||||
const filter = usePlaylistListFilter({ key: pageKey });
|
const { display, filter } = useListStoreByKey({ key: pageKey });
|
||||||
const { display } = usePlaylistListStore({ key: pageKey });
|
|
||||||
|
|
||||||
const handleCreatePlaylistModal = () => {
|
const handleCreatePlaylistModal = () => {
|
||||||
openModal({
|
openModal({
|
||||||
|
|
|
@ -1,25 +1,13 @@
|
||||||
import { RowDoubleClickedEvent } from '@ag-grid-community/core';
|
import { RowDoubleClickedEvent } from '@ag-grid-community/core';
|
||||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||||
import { useCallback } from 'react';
|
|
||||||
import { generatePath, useNavigate } from 'react-router';
|
import { generatePath, useNavigate } from 'react-router';
|
||||||
import { api } from '/@/renderer/api';
|
import { LibraryItem } from '/@/renderer/api/types';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
|
||||||
import { LibraryItem, PlaylistListQuery, PlaylistListResponse } from '/@/renderer/api/types';
|
|
||||||
import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-grid';
|
import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-grid';
|
||||||
import { VirtualTable } from '/@/renderer/components/virtual-table';
|
import { VirtualTable } from '/@/renderer/components/virtual-table';
|
||||||
import {
|
import { useVirtualTable } from '/@/renderer/components/virtual-table/hooks/use-virtual-table';
|
||||||
AgGridFetchFn,
|
|
||||||
useVirtualTable,
|
|
||||||
} from '/@/renderer/components/virtual-table/hooks/use-virtual-table';
|
|
||||||
import { PLAYLIST_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
import { PLAYLIST_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import {
|
import { useCurrentServer, useGeneralSettings } from '/@/renderer/store';
|
||||||
useCurrentServer,
|
|
||||||
useGeneralSettings,
|
|
||||||
useListStoreActions,
|
|
||||||
usePlaylistListFilter,
|
|
||||||
usePlaylistListStore,
|
|
||||||
} from '/@/renderer/store';
|
|
||||||
|
|
||||||
interface PlaylistListTableViewProps {
|
interface PlaylistListTableViewProps {
|
||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
|
@ -30,36 +18,7 @@ export const PlaylistListTableView = ({ tableRef, itemCount }: PlaylistListTable
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
const { defaultFullPlaylist } = useGeneralSettings();
|
const { defaultFullPlaylist } = useGeneralSettings();
|
||||||
const { setTable, setTablePagination } = useListStoreActions();
|
|
||||||
const pageKey = 'playlist';
|
const pageKey = 'playlist';
|
||||||
const filter = usePlaylistListFilter({ key: pageKey });
|
|
||||||
const listProperties = usePlaylistListStore({ key: pageKey });
|
|
||||||
|
|
||||||
console.log('listProperties :>> ', listProperties);
|
|
||||||
|
|
||||||
const fetchFn: AgGridFetchFn<
|
|
||||||
PlaylistListResponse,
|
|
||||||
Omit<PlaylistListQuery, 'startIndex'>
|
|
||||||
> = useCallback(
|
|
||||||
async ({ filter, limit, startIndex }, signal) => {
|
|
||||||
const res = api.controller.getPlaylistList({
|
|
||||||
apiClientProps: {
|
|
||||||
server,
|
|
||||||
signal,
|
|
||||||
},
|
|
||||||
query: {
|
|
||||||
...filter,
|
|
||||||
limit,
|
|
||||||
sortBy: filter.sortBy,
|
|
||||||
sortOrder: filter.sortOrder,
|
|
||||||
startIndex,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return res;
|
|
||||||
},
|
|
||||||
[server],
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleRowDoubleClick = (e: RowDoubleClickedEvent) => {
|
const handleRowDoubleClick = (e: RowDoubleClickedEvent) => {
|
||||||
if (!e.data) return;
|
if (!e.data) return;
|
||||||
|
@ -70,25 +29,14 @@ export const PlaylistListTableView = ({ tableRef, itemCount }: PlaylistListTable
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const tableProps = useVirtualTable<PlaylistListResponse, Omit<PlaylistListQuery, 'startIndex'>>(
|
const tableProps = useVirtualTable({
|
||||||
{
|
contextMenu: PLAYLIST_CONTEXT_MENU_ITEMS,
|
||||||
contextMenu: PLAYLIST_CONTEXT_MENU_ITEMS,
|
itemCount,
|
||||||
fetch: {
|
itemType: LibraryItem.PLAYLIST,
|
||||||
filter,
|
pageKey,
|
||||||
fn: fetchFn,
|
server,
|
||||||
itemCount,
|
tableRef,
|
||||||
queryKey: queryKeys.playlists.list,
|
});
|
||||||
server,
|
|
||||||
},
|
|
||||||
itemCount,
|
|
||||||
itemType: LibraryItem.PLAYLIST,
|
|
||||||
pageKey,
|
|
||||||
properties: listProperties,
|
|
||||||
setTable,
|
|
||||||
setTablePagination,
|
|
||||||
tableRef,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VirtualGridAutoSizerContainer>
|
<VirtualGridAutoSizerContainer>
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
|
import { useParams } from 'react-router';
|
||||||
import { PlaylistListSort, SortOrder } from '/@/renderer/api/types';
|
import { PlaylistListSort, SortOrder } from '/@/renderer/api/types';
|
||||||
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid';
|
import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid';
|
||||||
|
import { ListContext } from '/@/renderer/context/list-context';
|
||||||
import { PlaylistListContent } from '/@/renderer/features/playlists/components/playlist-list-content';
|
import { PlaylistListContent } from '/@/renderer/features/playlists/components/playlist-list-content';
|
||||||
import { PlaylistListHeader } from '/@/renderer/features/playlists/components/playlist-list-header';
|
import { PlaylistListHeader } from '/@/renderer/features/playlists/components/playlist-list-header';
|
||||||
import { usePlaylistList } from '/@/renderer/features/playlists/queries/playlist-list-query';
|
import { usePlaylistList } from '/@/renderer/features/playlists/queries/playlist-list-query';
|
||||||
import { AnimatedPage } from '/@/renderer/features/shared';
|
import { AnimatedPage } from '/@/renderer/features/shared';
|
||||||
import { useCurrentServer, usePlaylistListFilter } from '/@/renderer/store';
|
import { useCurrentServer, useListStoreByKey } from '/@/renderer/store';
|
||||||
|
|
||||||
const PlaylistListRoute = () => {
|
const PlaylistListRoute = () => {
|
||||||
const gridRef = useRef<VirtualInfiniteGridRef | null>(null);
|
const gridRef = useRef<VirtualInfiniteGridRef | null>(null);
|
||||||
const tableRef = useRef<AgGridReactType | null>(null);
|
const tableRef = useRef<AgGridReactType | null>(null);
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
|
const { playlistId } = useParams();
|
||||||
const playlistListFilter = usePlaylistListFilter({ key: 'playlist' });
|
const pageKey = 'playlist';
|
||||||
|
const { filter } = useListStoreByKey({ key: pageKey });
|
||||||
|
|
||||||
const itemCountCheck = usePlaylistList({
|
const itemCountCheck = usePlaylistList({
|
||||||
options: {
|
options: {
|
||||||
|
@ -21,7 +24,7 @@ const PlaylistListRoute = () => {
|
||||||
staleTime: 1000 * 60 * 60 * 2,
|
staleTime: 1000 * 60 * 60 * 2,
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
...playlistListFilter,
|
...filter,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
sortBy: PlaylistListSort.NAME,
|
sortBy: PlaylistListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: SortOrder.ASC,
|
||||||
|
@ -37,16 +40,18 @@ const PlaylistListRoute = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimatedPage>
|
<AnimatedPage>
|
||||||
<PlaylistListHeader
|
<ListContext.Provider value={{ id: playlistId, pageKey }}>
|
||||||
gridRef={gridRef}
|
<PlaylistListHeader
|
||||||
itemCount={itemCount}
|
gridRef={gridRef}
|
||||||
tableRef={tableRef}
|
itemCount={itemCount}
|
||||||
/>
|
tableRef={tableRef}
|
||||||
<PlaylistListContent
|
/>
|
||||||
gridRef={gridRef}
|
<PlaylistListContent
|
||||||
itemCount={itemCount}
|
gridRef={gridRef}
|
||||||
tableRef={tableRef}
|
itemCount={itemCount}
|
||||||
/>
|
tableRef={tableRef}
|
||||||
|
/>
|
||||||
|
</ListContext.Provider>
|
||||||
</AnimatedPage>
|
</AnimatedPage>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -624,13 +624,4 @@ export const useAlbumArtistListFilter = (args: { id?: string; key?: string }) =>
|
||||||
}) as AlbumArtistListFilter;
|
}) as AlbumArtistListFilter;
|
||||||
}, shallow);
|
}, shallow);
|
||||||
|
|
||||||
export const usePlaylistListFilter = (args: { id?: string; key?: string }) =>
|
|
||||||
useListStore((state) => {
|
|
||||||
return state._actions.getFilter({
|
|
||||||
id: args.id,
|
|
||||||
itemType: LibraryItem.PLAYLIST,
|
|
||||||
key: args.key,
|
|
||||||
}) as PlaylistListFilter;
|
|
||||||
}, shallow);
|
|
||||||
|
|
||||||
export const useListDetail = (key: string) => useListStore((state) => state.detail[key], shallow);
|
export const useListDetail = (key: string) => useListStore((state) => state.detail[key], shallow);
|
||||||
|
|
Reference in a new issue