mirror of
https://github.com/antebudimir/feishin.git
synced 2025-12-31 10:03:33 +00:00
playlist sort and refactoring
This commit is contained in:
parent
1cbb3e56bc
commit
306167fee3
3 changed files with 63 additions and 57 deletions
|
|
@ -3,20 +3,20 @@ import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/li
|
||||||
import { closeAllModals, openModal } from '@mantine/modals';
|
import { closeAllModals, openModal } from '@mantine/modals';
|
||||||
import { useQueryClient } from '@tanstack/react-query';
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import { MouseEvent, MutableRefObject, useCallback } from 'react';
|
import { ChangeEvent, MouseEvent, MutableRefObject, useCallback } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useNavigate, useParams } from 'react-router';
|
import { useNavigate, useParams } from 'react-router';
|
||||||
|
|
||||||
import i18n from '/@/i18n/i18n';
|
import i18n from '/@/i18n/i18n';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { SONG_TABLE_COLUMNS } from '/@/renderer/components/virtual-table';
|
import { SONG_TABLE_COLUMNS } from '/@/renderer/components/virtual-table';
|
||||||
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
|
||||||
import { openUpdatePlaylistModal } from '/@/renderer/features/playlists/components/update-playlist-form';
|
import { openUpdatePlaylistModal } from '/@/renderer/features/playlists/components/update-playlist-form';
|
||||||
import { useDeletePlaylist } from '/@/renderer/features/playlists/mutations/delete-playlist-mutation';
|
import { useDeletePlaylist } from '/@/renderer/features/playlists/mutations/delete-playlist-mutation';
|
||||||
import { usePlaylistDetail } from '/@/renderer/features/playlists/queries/playlist-detail-query';
|
import { usePlaylistDetail } from '/@/renderer/features/playlists/queries/playlist-detail-query';
|
||||||
import { OrderToggleButton } from '/@/renderer/features/shared';
|
import { OrderToggleButton } from '/@/renderer/features/shared';
|
||||||
import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu';
|
import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu';
|
||||||
import { MoreButton } from '/@/renderer/features/shared/components/more-button';
|
import { MoreButton } from '/@/renderer/features/shared/components/more-button';
|
||||||
|
import { SearchInput } from '/@/renderer/features/shared/components/search-input';
|
||||||
import { useContainerQuery } from '/@/renderer/hooks';
|
import { useContainerQuery } from '/@/renderer/hooks';
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import {
|
import {
|
||||||
|
|
@ -37,13 +37,7 @@ import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { ConfirmModal } from '/@/shared/components/modal/modal';
|
import { ConfirmModal } from '/@/shared/components/modal/modal';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { toast } from '/@/shared/components/toast/toast';
|
import { toast } from '/@/shared/components/toast/toast';
|
||||||
import {
|
import { ServerType, SongListSort, SortOrder } from '/@/shared/types/domain-types';
|
||||||
LibraryItem,
|
|
||||||
PlaylistSongListQueryClientSide,
|
|
||||||
ServerType,
|
|
||||||
SongListSort,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { ListDisplayType, Play } from '/@/shared/types/types';
|
import { ListDisplayType, Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
const FILTERS = {
|
const FILTERS = {
|
||||||
|
|
@ -246,11 +240,13 @@ const FILTERS = {
|
||||||
};
|
};
|
||||||
|
|
||||||
interface PlaylistDetailSongListHeaderFiltersProps {
|
interface PlaylistDetailSongListHeaderFiltersProps {
|
||||||
|
handlePlay: (playType: Play) => void;
|
||||||
handleToggleShowQueryBuilder: () => void;
|
handleToggleShowQueryBuilder: () => void;
|
||||||
tableRef: MutableRefObject<AgGridReactType | null>;
|
tableRef: MutableRefObject<AgGridReactType | null>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PlaylistDetailSongListHeaderFilters = ({
|
export const PlaylistDetailSongListHeaderFilters = ({
|
||||||
|
handlePlay,
|
||||||
handleToggleShowQueryBuilder,
|
handleToggleShowQueryBuilder,
|
||||||
tableRef,
|
tableRef,
|
||||||
}: PlaylistDetailSongListHeaderFiltersProps) => {
|
}: PlaylistDetailSongListHeaderFiltersProps) => {
|
||||||
|
|
@ -262,16 +258,13 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||||
const setPage = useSetPlaylistStore();
|
const setPage = useSetPlaylistStore();
|
||||||
const setFilter = useSetPlaylistDetailFilters();
|
const setFilter = useSetPlaylistDetailFilters();
|
||||||
const page = usePlaylistDetailStore();
|
const page = usePlaylistDetailStore();
|
||||||
const filters: Partial<PlaylistSongListQueryClientSide> = {
|
const searchTerm = page?.table.id[playlistId]?.filter?.searchTerm;
|
||||||
sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID,
|
const sortBy = page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID;
|
||||||
sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC,
|
const sortOrder = page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC;
|
||||||
};
|
|
||||||
|
|
||||||
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
||||||
const isSmartPlaylist = detailQuery.data?.rules;
|
const isSmartPlaylist = detailQuery.data?.rules;
|
||||||
|
|
||||||
const handlePlayQueueAdd = usePlayQueueAdd();
|
|
||||||
|
|
||||||
const cq = useContainerQuery();
|
const cq = useContainerQuery();
|
||||||
|
|
||||||
const setPagination = useSetPlaylistTablePagination();
|
const setPagination = useSetPlaylistTablePagination();
|
||||||
|
|
@ -279,8 +272,7 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||||
|
|
||||||
const sortByLabel =
|
const sortByLabel =
|
||||||
(server?.type &&
|
(server?.type &&
|
||||||
FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === filters.sortBy)
|
FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === sortBy)?.name) ||
|
||||||
?.name) ||
|
|
||||||
'Unknown';
|
'Unknown';
|
||||||
|
|
||||||
const handleItemSize = (e: number) => {
|
const handleItemSize = (e: number) => {
|
||||||
|
|
@ -307,13 +299,13 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||||
(e: MouseEvent<HTMLButtonElement>) => {
|
(e: MouseEvent<HTMLButtonElement>) => {
|
||||||
if (!e.currentTarget?.value || !server?.type) return;
|
if (!e.currentTarget?.value || !server?.type) return;
|
||||||
|
|
||||||
const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find(
|
const newSortOrder = FILTERS[server.type as keyof typeof FILTERS].find(
|
||||||
(f) => f.value === e.currentTarget.value,
|
(f) => f.value === e.currentTarget.value,
|
||||||
)?.defaultOrder;
|
)?.defaultOrder;
|
||||||
|
|
||||||
setFilter(playlistId, {
|
setFilter(playlistId, {
|
||||||
sortBy: e.currentTarget.value as SongListSort,
|
sortBy: e.currentTarget.value as SongListSort,
|
||||||
sortOrder: sortOrder || SortOrder.ASC,
|
sortOrder: newSortOrder || SortOrder.ASC,
|
||||||
});
|
});
|
||||||
|
|
||||||
handleFilterChange();
|
handleFilterChange();
|
||||||
|
|
@ -322,10 +314,15 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleToggleSortOrder = useCallback(() => {
|
const handleToggleSortOrder = useCallback(() => {
|
||||||
const newSortOrder = filters.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
const newSortOrder = sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
||||||
setFilter(playlistId, { sortOrder: newSortOrder });
|
setFilter(playlistId, { sortOrder: newSortOrder });
|
||||||
handleFilterChange();
|
handleFilterChange();
|
||||||
}, [filters.sortOrder, handleFilterChange, playlistId, setFilter]);
|
}, [sortOrder, handleFilterChange, playlistId, setFilter]);
|
||||||
|
|
||||||
|
const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setFilter(playlistId, { searchTerm: e.target.value });
|
||||||
|
handleFilterChange();
|
||||||
|
}, 500);
|
||||||
|
|
||||||
const handleSetViewType = useCallback(
|
const handleSetViewType = useCallback(
|
||||||
(displayType: ListDisplayType) => {
|
(displayType: ListDisplayType) => {
|
||||||
|
|
@ -370,14 +367,6 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePlay = async (playType: Play) => {
|
|
||||||
handlePlayQueueAdd?.({
|
|
||||||
byItemType: { id: [playlistId], type: LibraryItem.PLAYLIST },
|
|
||||||
playType,
|
|
||||||
query: filters,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const deletePlaylistMutation = useDeletePlaylist({});
|
const deletePlaylistMutation = useDeletePlaylist({});
|
||||||
|
|
||||||
const handleDeletePlaylist = useCallback(() => {
|
const handleDeletePlaylist = useCallback(() => {
|
||||||
|
|
@ -427,7 +416,7 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||||
<DropdownMenu.Dropdown>
|
<DropdownMenu.Dropdown>
|
||||||
{FILTERS[server?.type as keyof typeof FILTERS].map((filter) => (
|
{FILTERS[server?.type as keyof typeof FILTERS].map((filter) => (
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
isSelected={filter.value === filters.sortBy}
|
isSelected={filter.value === sortBy}
|
||||||
key={`filter-${filter.name}`}
|
key={`filter-${filter.name}`}
|
||||||
onClick={handleSetSortBy}
|
onClick={handleSetSortBy}
|
||||||
value={filter.value}
|
value={filter.value}
|
||||||
|
|
@ -441,7 +430,7 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||||
<Divider orientation="vertical" />
|
<Divider orientation="vertical" />
|
||||||
<OrderToggleButton
|
<OrderToggleButton
|
||||||
onToggle={handleToggleSortOrder}
|
onToggle={handleToggleSortOrder}
|
||||||
sortOrder={filters.sortOrder || SortOrder.ASC}
|
sortOrder={sortOrder || SortOrder.ASC}
|
||||||
/>
|
/>
|
||||||
<DropdownMenu position="bottom-start">
|
<DropdownMenu position="bottom-start">
|
||||||
<DropdownMenu.Target>
|
<DropdownMenu.Target>
|
||||||
|
|
@ -503,6 +492,7 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
||||||
)}
|
)}
|
||||||
</DropdownMenu.Dropdown>
|
</DropdownMenu.Dropdown>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
<SearchInput defaultValue={searchTerm} onChange={handleSearch} />
|
||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group>
|
||||||
<ListConfigMenu
|
<ListConfigMenu
|
||||||
|
|
|
||||||
|
|
@ -5,31 +5,27 @@ import { useTranslation } from 'react-i18next';
|
||||||
import { useParams } from 'react-router';
|
import { useParams } from 'react-router';
|
||||||
|
|
||||||
import { PageHeader } from '/@/renderer/components/page-header/page-header';
|
import { PageHeader } from '/@/renderer/components/page-header/page-header';
|
||||||
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
|
||||||
import { PlaylistDetailSongListHeaderFilters } from '/@/renderer/features/playlists/components/playlist-detail-song-list-header-filters';
|
import { PlaylistDetailSongListHeaderFilters } from '/@/renderer/features/playlists/components/playlist-detail-song-list-header-filters';
|
||||||
import { usePlaylistDetail } from '/@/renderer/features/playlists/queries/playlist-detail-query';
|
import { usePlaylistDetail } from '/@/renderer/features/playlists/queries/playlist-detail-query';
|
||||||
import { FilterBar, LibraryHeaderBar } from '/@/renderer/features/shared';
|
import { FilterBar, LibraryHeaderBar } from '/@/renderer/features/shared';
|
||||||
import { useCurrentServer, usePlaylistDetailStore } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
||||||
import { formatDurationString } from '/@/renderer/utils';
|
import { formatDurationString } from '/@/renderer/utils';
|
||||||
import { Badge } from '/@/shared/components/badge/badge';
|
import { Badge } from '/@/shared/components/badge/badge';
|
||||||
import { SpinnerIcon } from '/@/shared/components/spinner/spinner';
|
import { SpinnerIcon } from '/@/shared/components/spinner/spinner';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import {
|
|
||||||
LibraryItem,
|
|
||||||
PlaylistSongListQueryClientSide,
|
|
||||||
SongListSort,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { Play } from '/@/shared/types/types';
|
import { Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface PlaylistDetailHeaderProps {
|
interface PlaylistDetailHeaderProps {
|
||||||
|
handlePlay: (playType: Play) => void;
|
||||||
|
|
||||||
handleToggleShowQueryBuilder: () => void;
|
handleToggleShowQueryBuilder: () => void;
|
||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
tableRef: MutableRefObject<AgGridReactType | null>;
|
tableRef: MutableRefObject<AgGridReactType | null>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PlaylistDetailSongListHeader = ({
|
export const PlaylistDetailSongListHeader = ({
|
||||||
|
handlePlay,
|
||||||
handleToggleShowQueryBuilder,
|
handleToggleShowQueryBuilder,
|
||||||
itemCount,
|
itemCount,
|
||||||
tableRef,
|
tableRef,
|
||||||
|
|
@ -38,20 +34,6 @@ export const PlaylistDetailSongListHeader = ({
|
||||||
const { playlistId } = useParams() as { playlistId: string };
|
const { playlistId } = useParams() as { playlistId: string };
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
||||||
const handlePlayQueueAdd = usePlayQueueAdd();
|
|
||||||
const page = usePlaylistDetailStore();
|
|
||||||
const filters: Partial<PlaylistSongListQueryClientSide> = {
|
|
||||||
sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID,
|
|
||||||
sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC,
|
|
||||||
};
|
|
||||||
|
|
||||||
const handlePlay = async (playType: Play) => {
|
|
||||||
handlePlayQueueAdd?.({
|
|
||||||
byItemType: { id: [playlistId], type: LibraryItem.PLAYLIST },
|
|
||||||
playType,
|
|
||||||
query: filters,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const playButtonBehavior = usePlayButtonBehavior();
|
const playButtonBehavior = usePlayButtonBehavior();
|
||||||
|
|
||||||
|
|
@ -78,6 +60,7 @@ export const PlaylistDetailSongListHeader = ({
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<FilterBar>
|
<FilterBar>
|
||||||
<PlaylistDetailSongListHeaderFilters
|
<PlaylistDetailSongListHeaderFilters
|
||||||
|
handlePlay={handlePlay}
|
||||||
handleToggleShowQueryBuilder={handleToggleShowQueryBuilder}
|
handleToggleShowQueryBuilder={handleToggleShowQueryBuilder}
|
||||||
tableRef={tableRef}
|
tableRef={tableRef}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
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 { closeAllModals, openModal } from '@mantine/modals';
|
import { closeAllModals, openModal } from '@mantine/modals';
|
||||||
|
import Fuse from 'fuse.js';
|
||||||
import { motion } from 'motion/react';
|
import { motion } from 'motion/react';
|
||||||
import { useMemo, useRef, useState } from 'react';
|
import { useMemo, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { generatePath, useNavigate, useParams } from 'react-router';
|
import { generatePath, useNavigate, useParams } from 'react-router';
|
||||||
|
|
||||||
|
import { useHandlePlayQueueAdd } from '/@/renderer/features/player/hooks/use-handle-playqueue-add';
|
||||||
import { PlaylistDetailSongListContent } from '/@/renderer/features/playlists/components/playlist-detail-song-list-content';
|
import { PlaylistDetailSongListContent } from '/@/renderer/features/playlists/components/playlist-detail-song-list-content';
|
||||||
import { PlaylistDetailSongListHeader } from '/@/renderer/features/playlists/components/playlist-detail-song-list-header';
|
import { PlaylistDetailSongListHeader } from '/@/renderer/features/playlists/components/playlist-detail-song-list-header';
|
||||||
import { PlaylistQueryBuilder } from '/@/renderer/features/playlists/components/playlist-query-builder';
|
import { PlaylistQueryBuilder } from '/@/renderer/features/playlists/components/playlist-query-builder';
|
||||||
|
|
@ -23,6 +25,7 @@ import { Group } from '/@/shared/components/group/group';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { toast } from '/@/shared/components/toast/toast';
|
import { toast } from '/@/shared/components/toast/toast';
|
||||||
import { ServerType, SongListSort, SortOrder, sortSongList } from '/@/shared/types/domain-types';
|
import { ServerType, SongListSort, SortOrder, sortSongList } from '/@/shared/types/domain-types';
|
||||||
|
import { Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
const PlaylistDetailSongListRoute = () => {
|
const PlaylistDetailSongListRoute = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
@ -30,6 +33,7 @@ const PlaylistDetailSongListRoute = () => {
|
||||||
const tableRef = useRef<AgGridReactType | null>(null);
|
const tableRef = useRef<AgGridReactType | null>(null);
|
||||||
const { playlistId } = useParams() as { playlistId: string };
|
const { playlistId } = useParams() as { playlistId: string };
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
|
const handlePlayQueueAdd = useHandlePlayQueueAdd();
|
||||||
|
|
||||||
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
||||||
const createPlaylistMutation = useCreatePlaylist({});
|
const createPlaylistMutation = useCreatePlaylist({});
|
||||||
|
|
@ -151,21 +155,50 @@ const PlaylistDetailSongListRoute = () => {
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
const itemCount = playlistSongs.data?.totalRecordCount ?? undefined;
|
|
||||||
|
|
||||||
const filterSortedSongs = useMemo(() => {
|
const filterSortedSongs = useMemo(() => {
|
||||||
if (playlistSongs.data?.items) {
|
let items = playlistSongs.data?.items;
|
||||||
|
|
||||||
|
if (items) {
|
||||||
|
const searchTerm = page?.table.id[playlistId]?.filter.searchTerm;
|
||||||
|
|
||||||
|
if (searchTerm) {
|
||||||
|
const fuse = new Fuse(items, {
|
||||||
|
fieldNormWeight: 1,
|
||||||
|
ignoreLocation: true,
|
||||||
|
keys: [
|
||||||
|
'name',
|
||||||
|
'album',
|
||||||
|
{
|
||||||
|
getFn: (song) => song.artists.map((artist) => artist.name),
|
||||||
|
name: 'artist',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
threshold: 0,
|
||||||
|
});
|
||||||
|
items = fuse.search(searchTerm).map((item) => item.item);
|
||||||
|
}
|
||||||
|
|
||||||
const sortBy = page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID;
|
const sortBy = page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID;
|
||||||
const sortOrder = page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC;
|
const sortOrder = page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC;
|
||||||
return sortSongList(playlistSongs.data?.items, sortBy, sortOrder);
|
return sortSongList(items, sortBy, sortOrder);
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}, [playlistSongs.data?.items, page?.table.id, playlistId]);
|
}, [playlistSongs.data?.items, page?.table.id, playlistId]);
|
||||||
|
|
||||||
|
const itemCount = playlistSongs.data?.totalRecordCount ? filterSortedSongs.length : undefined;
|
||||||
|
|
||||||
|
const handlePlay = (play: Play) => {
|
||||||
|
handlePlayQueueAdd?.({
|
||||||
|
byData: filterSortedSongs,
|
||||||
|
playType: play,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnimatedPage key={`playlist-detail-songList-${playlistId}`}>
|
<AnimatedPage key={`playlist-detail-songList-${playlistId}`}>
|
||||||
<PlaylistDetailSongListHeader
|
<PlaylistDetailSongListHeader
|
||||||
|
handlePlay={handlePlay}
|
||||||
handleToggleShowQueryBuilder={handleToggleShowQueryBuilder}
|
handleToggleShowQueryBuilder={handleToggleShowQueryBuilder}
|
||||||
itemCount={itemCount}
|
itemCount={itemCount}
|
||||||
tableRef={tableRef}
|
tableRef={tableRef}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue