initial implementation of play queue for new list

This commit is contained in:
jeffvli
2025-11-08 14:28:31 -08:00
parent 3c996407d5
commit 7a4326f98d
7 changed files with 82 additions and 349 deletions
@@ -1,21 +1,18 @@
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
import isElectron from 'is-electron';
import { type MutableRefObject, useCallback } from 'react';
import { type MutableRefObject } from 'react';
import { useTranslation } from 'react-i18next';
import { TableConfigDropdown } from '/@/renderer/components/virtual-table';
import { SONG_TABLE_COLUMNS } from '/@/renderer/components/virtual-table';
import { usePlayerContext } from '/@/renderer/features/player/context/player-context';
import { updateSong } from '/@/renderer/features/player/update-remote-song';
import { SearchInput } from '/@/renderer/features/shared/components/search-input';
import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu';
import { usePlaybackType } from '/@/renderer/store/settings.store';
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
import { Group } from '/@/shared/components/group/group';
import { Popover } from '/@/shared/components/popover/popover';
import { Song } from '/@/shared/types/domain-types';
import { ItemListKey } from '/@/shared/types/types';
const mpvPlayer = isElectron() ? window.api.mpvPlayer : null;
interface PlayQueueListOptionsProps {
handleSearch: (value: string) => void;
searchTerm?: string;
@@ -41,54 +38,49 @@ export const PlayQueueListControls = ({
// const { pause } = usePlayerControls();
const player = usePlayerContext();
const playbackType = usePlaybackType();
// const setCurrentTime = useSetCurrentTime();
const handleMoveToNext = () => {
const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
const uniqueIds = selectedRows?.map((row) => row.uniqueId);
if (!uniqueIds?.length) return;
// const playerData = moveToNextOfQueue(uniqueIds);
// if (playbackType === PlaybackType.LOCAL) {
// setQueueNext(playerData);
// }
// const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
// const uniqueIds = selectedRows?.map((row) => row.uniqueId);
// if (!uniqueIds?.length) return;
// // const playerData = moveToNextOfQueue(uniqueIds);
// // if (playbackType === PlaybackType.LOCAL) {
// // setQueueNext(playerData);
// // }
// player.moveSelectedToNext(selectedRows);
};
const handleMoveToBottom = () => {
const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
const uniqueIds = selectedRows?.map((row) => row.uniqueId);
if (!uniqueIds?.length) return;
// const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
// const uniqueIds = selectedRows?.map((row) => row.uniqueId);
// if (!uniqueIds?.length) return;
// const playerData = moveToBottomOfQueue(uniqueIds);
// if (playbackType === PlaybackType.LOCAL) {
// setQueueNext(playerData);
// }
};
const handleMoveToTop = () => {
const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
const uniqueIds = selectedRows?.map((row) => row.uniqueId);
if (!uniqueIds?.length) return;
// const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
// const uniqueIds = selectedRows?.map((row) => row.uniqueId);
// if (!uniqueIds?.length) return;
// const playerData = moveToTopOfQueue(uniqueIds);
// if (playbackType === PlaybackType.LOCAL) {
// setQueueNext(playerData);
// }
};
const handleRemoveSelected = () => {
const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
const uniqueIds = selectedRows?.map((row) => row.uniqueId);
if (!uniqueIds?.length) return;
// const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
// const uniqueIds = selectedRows?.map((row) => row.uniqueId);
// if (!uniqueIds?.length) return;
// const currentSong = usePlayerStore.getState().current.song;
// const playerData = removeFromQueue(uniqueIds);
// const isCurrentSongRemoved = currentSong && uniqueIds.includes(currentSong.uniqueId);
// if (playbackType === PlaybackType.LOCAL) {
// if (isCurrentSongRemoved) {
// setQueue(playerData);
@@ -96,7 +88,6 @@ export const PlayQueueListControls = ({
// setQueueNext(playerData);
// }
// }
// if (isCurrentSongRemoved) {
// updateSong(playerData.current.song);
// }
@@ -123,25 +114,9 @@ export const PlayQueueListControls = ({
// }
};
const handleSearchTerm = useCallback(
(term: string) => {
handleSearch(term);
tableRef.current?.grid.api.redrawRows();
},
[handleSearch, tableRef],
);
const hasSearch = !!searchTerm;
return (
<Group
justify="space-between"
px="1rem"
py="1rem"
style={{ alignItems: 'center' }}
w="100%"
>
<Group gap="sm">
<Group justify="space-between" px="1rem" py="1rem" w="100%">
<Group gap="xs">
<ActionIcon
icon="mediaShuffle"
iconProps={{ size: 'lg' }}
@@ -150,7 +125,7 @@ export const PlayQueueListControls = ({
variant="subtle"
/>
<ActionIcon
disabled={hasSearch}
// disabled={hasSearch}
icon="mediaPlayNext"
iconProps={{ size: 'lg' }}
onClick={handleMoveToNext}
@@ -158,7 +133,7 @@ export const PlayQueueListControls = ({
variant="subtle"
/>
<ActionIcon
disabled={hasSearch}
// disabled={hasSearch}
icon="arrowDownToLine"
iconProps={{ size: 'lg' }}
onClick={handleMoveToBottom}
@@ -166,7 +141,7 @@ export const PlayQueueListControls = ({
variant="subtle"
/>
<ActionIcon
disabled={hasSearch}
// disabled={hasSearch}
icon="arrowUpToLine"
iconProps={{ size: 'lg' }}
onClick={handleMoveToTop}
@@ -189,27 +164,12 @@ export const PlayQueueListControls = ({
tooltip={{ label: t('action.clearQueue', { postProcess: 'sentenceCase' }) }}
variant="subtle"
/>
<SearchInput
onChange={(e) => handleSearchTerm(e.target.value)}
value={searchTerm}
/>
</Group>
<Group>
<Popover position="top-end" transitionProps={{ transition: 'fade' }}>
<Popover.Target>
<ActionIcon
icon="settings"
iconProps={{ size: 'lg' }}
tooltip={{
label: t('common.configure', { postProcess: 'sentenceCase' }),
}}
variant="subtle"
/>
</Popover.Target>
<Popover.Dropdown>
<TableConfigDropdown type={type} />
</Popover.Dropdown>
</Popover>
<ListConfigMenu
listKey={ItemListKey.SIDE_QUEUE}
tableColumnsData={SONG_TABLE_COLUMNS}
/>
</Group>
</Group>
);