feishin/src/renderer/features/now-playing/components/play-queue-list-controls.tsx

199 lines
6.9 KiB
TypeScript
Raw Normal View History

2022-12-19 15:59:14 -08:00
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
import type { MutableRefObject } from 'react';
2022-12-25 01:25:46 -08:00
import isElectron from 'is-electron';
import { useTranslation } from 'react-i18next';
import { TableConfigDropdown } from '/@/renderer/components/virtual-table';
2024-07-03 08:47:26 +00:00
import { updateSong } from '/@/renderer/features/player/update-remote-song';
import { usePlayerControls, useQueueControls } from '/@/renderer/store';
2025-05-20 19:23:36 -07:00
import { usePlayerStore, useSetCurrentTime } from '/@/renderer/store/player.store';
import { usePlaybackType } from '/@/renderer/store/settings.store';
2024-09-01 08:26:30 -07:00
import { setQueue, setQueueNext } from '/@/renderer/utils/set-transcoded-queue-data';
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
import { Group } from '/@/shared/components/group/group';
import { Popover } from '/@/shared/components/popover/popover';
2025-05-20 19:23:36 -07:00
import { Song } from '/@/shared/types/domain-types';
import { PlaybackType, TableType } from '/@/shared/types/types';
2022-12-19 15:59:14 -08:00
const mpvPlayer = isElectron() ? window.api.mpvPlayer : null;
2022-12-19 15:59:14 -08:00
interface PlayQueueListOptionsProps {
tableRef: MutableRefObject<null | { grid: AgGridReactType<Song> }>;
2023-07-01 19:10:05 -07:00
type: TableType;
2022-12-19 15:59:14 -08:00
}
export const PlayQueueListControls = ({ tableRef, type }: PlayQueueListOptionsProps) => {
const { t } = useTranslation();
const {
clearQueue,
moveToBottomOfQueue,
moveToNextOfQueue,
moveToTopOfQueue,
removeFromQueue,
shuffleQueue,
} = useQueueControls();
2023-07-01 19:10:05 -07:00
const { pause } = usePlayerControls();
const playbackType = usePlaybackType();
2023-07-01 19:10:05 -07:00
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);
}
};
2023-07-01 19:10:05 -07:00
const handleMoveToBottom = () => {
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) {
2024-09-01 08:26:30 -07:00
setQueueNext(playerData);
2023-07-01 19:10:05 -07:00
}
};
const handleMoveToTop = () => {
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) {
2024-09-01 08:26:30 -07:00
setQueueNext(playerData);
2023-07-01 19:10:05 -07:00
}
};
const handleRemoveSelected = () => {
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) {
2023-07-01 19:10:05 -07:00
if (isCurrentSongRemoved) {
2024-09-01 08:26:30 -07:00
setQueue(playerData);
2023-07-01 19:10:05 -07:00
} else {
2024-09-01 08:26:30 -07:00
setQueueNext(playerData);
2023-07-01 19:10:05 -07:00
}
}
if (isCurrentSongRemoved) {
2024-07-03 08:47:26 +00:00
updateSong(playerData.current.song);
}
2023-07-01 19:10:05 -07:00
};
const handleClearQueue = () => {
const playerData = clearQueue();
if (playbackType === PlaybackType.LOCAL) {
2024-09-01 08:26:30 -07:00
setQueue(playerData);
mpvPlayer!.pause();
2023-07-01 19:10:05 -07:00
}
2024-07-03 08:47:26 +00:00
updateSong(undefined);
2023-07-01 19:10:05 -07:00
setCurrentTime(0);
pause();
};
const handleShuffleQueue = () => {
const playerData = shuffleQueue();
if (playbackType === PlaybackType.LOCAL) {
2024-09-01 08:26:30 -07:00
setQueueNext(playerData);
2023-07-01 19:10:05 -07:00
}
};
return (
<Group
justify="space-between"
2023-07-01 19:10:05 -07:00
px="1rem"
py="1rem"
style={{ alignItems: 'center' }}
2023-07-01 19:10:05 -07:00
w="100%"
2022-12-19 15:59:14 -08:00
>
<Group gap="sm">
<ActionIcon
icon="mediaShuffle"
iconProps={{ size: 'lg' }}
onClick={handleShuffleQueue}
tooltip={{ label: t('player.shuffle', { postProcess: 'sentenceCase' }) }}
variant="subtle"
/>
<ActionIcon
icon="mediaPlayNext"
iconProps={{ size: 'lg' }}
onClick={handleMoveToNext}
tooltip={{ label: t('action.moveToNext', { postProcess: 'sentenceCase' }) }}
variant="subtle"
/>
<ActionIcon
icon="arrowDownToLine"
iconProps={{ size: 'lg' }}
onClick={handleMoveToBottom}
tooltip={{ label: t('action.moveToBottom', { postProcess: 'sentenceCase' }) }}
variant="subtle"
/>
<ActionIcon
icon="arrowUpToLine"
iconProps={{ size: 'lg' }}
onClick={handleMoveToTop}
tooltip={{ label: t('action.moveToTop', { postProcess: 'sentenceCase' }) }}
variant="subtle"
/>
<ActionIcon
icon="delete"
iconProps={{ size: 'lg' }}
onClick={handleRemoveSelected}
tooltip={{
label: t('action.removeFromQueue', { postProcess: 'sentenceCase' }),
}}
variant="subtle"
/>
<ActionIcon
icon="x"
iconProps={{ size: 'lg' }}
onClick={handleClearQueue}
tooltip={{ label: t('action.clearQueue', { postProcess: 'sentenceCase' }) }}
variant="subtle"
/>
2023-07-01 19:10:05 -07:00
</Group>
<Group>
<Popover
position="top-end"
transitionProps={{ transition: 'fade' }}
>
<Popover.Target>
<ActionIcon
icon="settings"
iconProps={{ size: 'lg' }}
tooltip={{
label: t('common.configure', { postProcess: 'sentenceCase' }),
}}
2023-07-01 19:10:05 -07:00
variant="subtle"
/>
2023-07-01 19:10:05 -07:00
</Popover.Target>
<Popover.Dropdown>
<TableConfigDropdown type={type} />
</Popover.Dropdown>
</Popover>
</Group>
</Group>
);
2022-12-19 15:59:14 -08:00
};