mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-06 20:10:12 +02:00
reimplement playqueue list controls
This commit is contained in:
@@ -564,15 +564,6 @@ export const ItemGridList = ({
|
|||||||
|
|
||||||
const imperativeHandle: ItemListHandle = useMemo(() => {
|
const imperativeHandle: ItemListHandle = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
clearExpanded: () => {
|
|
||||||
internalState.clearExpanded();
|
|
||||||
},
|
|
||||||
clearSelected: () => {
|
|
||||||
internalState.clearSelected();
|
|
||||||
},
|
|
||||||
getItem: (index: number) => data[index],
|
|
||||||
getItemCount: () => data.length,
|
|
||||||
getItems: () => data,
|
|
||||||
internalState,
|
internalState,
|
||||||
scrollToIndex: (index: number) => {
|
scrollToIndex: (index: number) => {
|
||||||
scrollToIndex(index);
|
scrollToIndex(index);
|
||||||
@@ -581,7 +572,7 @@ export const ItemGridList = ({
|
|||||||
scrollToOffset(offset);
|
scrollToOffset(offset);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}, [data, internalState, scrollToIndex, scrollToOffset]);
|
}, [internalState, scrollToIndex, scrollToOffset]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
handleRef.current = imperativeHandle;
|
handleRef.current = imperativeHandle;
|
||||||
|
|||||||
@@ -1276,15 +1276,6 @@ export const ItemTableList = ({
|
|||||||
|
|
||||||
const imperativeHandle: ItemListHandle = useMemo(() => {
|
const imperativeHandle: ItemListHandle = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
clearExpanded: () => {
|
|
||||||
internalState.clearExpanded();
|
|
||||||
},
|
|
||||||
clearSelected: () => {
|
|
||||||
internalState.clearSelected();
|
|
||||||
},
|
|
||||||
getItem: (index: number) => (enableHeader ? data[index - 1] : data[index]),
|
|
||||||
getItemCount: () => (enableHeader ? data.length : data.length),
|
|
||||||
getItems: () => data,
|
|
||||||
internalState,
|
internalState,
|
||||||
scrollToIndex: (index: number) => {
|
scrollToIndex: (index: number) => {
|
||||||
scrollToTableIndex(enableHeader ? index + 1 : index);
|
scrollToTableIndex(enableHeader ? index + 1 : index);
|
||||||
@@ -1293,7 +1284,7 @@ export const ItemTableList = ({
|
|||||||
scrollToTableOffset(offset);
|
scrollToTableOffset(offset);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}, [data, enableHeader, internalState, scrollToTableIndex, scrollToTableOffset]);
|
}, [enableHeader, internalState, scrollToTableIndex, scrollToTableOffset]);
|
||||||
|
|
||||||
useImperativeHandle(ref, () => imperativeHandle);
|
useImperativeHandle(ref, () => imperativeHandle);
|
||||||
|
|
||||||
|
|||||||
@@ -53,11 +53,6 @@ export interface ItemListGridComponentProps<TQuery> extends ItemListComponentPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ItemListHandle {
|
export interface ItemListHandle {
|
||||||
clearExpanded: () => void;
|
|
||||||
clearSelected: () => void;
|
|
||||||
getItem: (index: number) => unknown;
|
|
||||||
getItemCount: () => number;
|
|
||||||
getItems: () => unknown[];
|
|
||||||
internalState: ItemListStateActions;
|
internalState: ItemListStateActions;
|
||||||
scrollToIndex: (index: number, options?: { behavior?: 'auto' | 'smooth' }) => void;
|
scrollToIndex: (index: number, options?: { behavior?: 'auto' | 'smooth' }) => void;
|
||||||
scrollToOffset: (offset: number, options?: { behavior?: 'auto' | 'smooth' }) => void;
|
scrollToOffset: (offset: number, options?: { behavior?: 'auto' | 'smooth' }) => void;
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
|
||||||
|
|
||||||
import { type MutableRefObject } from 'react';
|
import { type MutableRefObject } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { ItemListHandle } from '/@/renderer/components/item-list/types';
|
||||||
import { SONG_TABLE_COLUMNS } from '/@/renderer/components/virtual-table';
|
import { SONG_TABLE_COLUMNS } from '/@/renderer/components/virtual-table';
|
||||||
import { usePlayerContext } from '/@/renderer/features/player/context/player-context';
|
import { usePlayerContext } from '/@/renderer/features/player/context/player-context';
|
||||||
import { updateSong } from '/@/renderer/features/player/update-remote-song';
|
import { updateSong } from '/@/renderer/features/player/update-remote-song';
|
||||||
import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu';
|
import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu';
|
||||||
import { usePlaybackType } from '/@/renderer/store/settings.store';
|
import { SearchInput } from '/@/renderer/features/shared/components/search-input';
|
||||||
|
import { usePlayerSong, usePlayerStoreBase } from '/@/renderer/store';
|
||||||
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Song } from '/@/shared/types/domain-types';
|
import { QueueSong } from '/@/shared/types/domain-types';
|
||||||
import { ItemListKey } from '/@/shared/types/types';
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface PlayQueueListOptionsProps {
|
interface PlayQueueListOptionsProps {
|
||||||
handleSearch: (value: string) => void;
|
handleSearch: (value: string) => void;
|
||||||
searchTerm?: string;
|
searchTerm?: string;
|
||||||
tableRef: MutableRefObject<null | { grid: AgGridReactType<Song> }>;
|
tableRef: MutableRefObject<ItemListHandle | null>;
|
||||||
type: ItemListKey;
|
type: ItemListKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,94 +24,60 @@ export const PlayQueueListControls = ({
|
|||||||
handleSearch,
|
handleSearch,
|
||||||
searchTerm,
|
searchTerm,
|
||||||
tableRef,
|
tableRef,
|
||||||
type,
|
|
||||||
}: PlayQueueListOptionsProps) => {
|
}: PlayQueueListOptionsProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
// const {
|
|
||||||
// clearQueue,
|
|
||||||
// moveToBottomOfQueue,
|
|
||||||
// moveToNextOfQueue,
|
|
||||||
// moveToTopOfQueue,
|
|
||||||
// removeFromQueue,
|
|
||||||
// shuffleQueue,
|
|
||||||
// } = useQueueControls();
|
|
||||||
|
|
||||||
// const { pause } = usePlayerControls();
|
|
||||||
|
|
||||||
const player = usePlayerContext();
|
const player = usePlayerContext();
|
||||||
|
const currentSong = usePlayerSong();
|
||||||
const playbackType = usePlaybackType();
|
|
||||||
// const setCurrentTime = useSetCurrentTime();
|
|
||||||
|
|
||||||
const handleMoveToNext = () => {
|
const handleMoveToNext = () => {
|
||||||
// const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
|
const selectedItems = tableRef?.current?.internalState.getSelected() as
|
||||||
// const uniqueIds = selectedRows?.map((row) => row.uniqueId);
|
| QueueSong[]
|
||||||
// if (!uniqueIds?.length) return;
|
| undefined;
|
||||||
// // const playerData = moveToNextOfQueue(uniqueIds);
|
if (!selectedItems || selectedItems.length === 0) return;
|
||||||
// // if (playbackType === PlaybackType.LOCAL) {
|
player.moveSelectedToNext(selectedItems);
|
||||||
// // setQueueNext(playerData);
|
|
||||||
// // }
|
|
||||||
// player.moveSelectedToNext(selectedRows);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMoveToBottom = () => {
|
const handleMoveToBottom = () => {
|
||||||
// const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
|
const selectedItems = tableRef?.current?.internalState.getSelected() as
|
||||||
// const uniqueIds = selectedRows?.map((row) => row.uniqueId);
|
| QueueSong[]
|
||||||
// if (!uniqueIds?.length) return;
|
| undefined;
|
||||||
// const playerData = moveToBottomOfQueue(uniqueIds);
|
if (!selectedItems || selectedItems.length === 0) return;
|
||||||
// if (playbackType === PlaybackType.LOCAL) {
|
player.moveSelectedToBottom(selectedItems);
|
||||||
// setQueueNext(playerData);
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMoveToTop = () => {
|
const handleMoveToTop = () => {
|
||||||
// const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
|
const selectedItems = tableRef?.current?.internalState.getSelected() as
|
||||||
// const uniqueIds = selectedRows?.map((row) => row.uniqueId);
|
| QueueSong[]
|
||||||
// if (!uniqueIds?.length) return;
|
| undefined;
|
||||||
// const playerData = moveToTopOfQueue(uniqueIds);
|
if (!selectedItems || selectedItems.length === 0) return;
|
||||||
// if (playbackType === PlaybackType.LOCAL) {
|
player.moveSelectedToTop(selectedItems);
|
||||||
// setQueueNext(playerData);
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemoveSelected = () => {
|
const handleRemoveSelected = () => {
|
||||||
// const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
|
const selectedItems = tableRef?.current?.internalState.getSelected() as
|
||||||
// const uniqueIds = selectedRows?.map((row) => row.uniqueId);
|
| QueueSong[]
|
||||||
// if (!uniqueIds?.length) return;
|
| undefined;
|
||||||
// const currentSong = usePlayerStore.getState().current.song;
|
if (!selectedItems || selectedItems.length === 0) return;
|
||||||
// const playerData = removeFromQueue(uniqueIds);
|
|
||||||
// const isCurrentSongRemoved = currentSong && uniqueIds.includes(currentSong.uniqueId);
|
const selectedUniqueIds = selectedItems.map((item) => item._uniqueId);
|
||||||
// if (playbackType === PlaybackType.LOCAL) {
|
const isCurrentSongRemoved =
|
||||||
// if (isCurrentSongRemoved) {
|
currentSong && selectedUniqueIds.includes(currentSong._uniqueId);
|
||||||
// setQueue(playerData);
|
|
||||||
// } else {
|
player.clearSelected(selectedItems);
|
||||||
// setQueueNext(playerData);
|
|
||||||
// }
|
if (isCurrentSongRemoved) {
|
||||||
// }
|
// Get the new current song after removal
|
||||||
// if (isCurrentSongRemoved) {
|
const newCurrentSong = usePlayerStoreBase.getState().getCurrentSong();
|
||||||
// updateSong(playerData.current.song);
|
updateSong(newCurrentSong);
|
||||||
// }
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClearQueue = () => {
|
const handleClearQueue = () => {
|
||||||
// const playerData = clearQueue();
|
|
||||||
|
|
||||||
// if (playbackType === PlaybackType.LOCAL) {
|
|
||||||
// setQueue(playerData);
|
|
||||||
// mpvPlayer!.pause();
|
|
||||||
// }
|
|
||||||
|
|
||||||
player.clearQueue();
|
player.clearQueue();
|
||||||
|
|
||||||
// setCurrentTime(0);
|
|
||||||
// pause();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleShuffleQueue = () => {
|
const handleShuffleQueue = () => {
|
||||||
// const playerData = shuffleQueue();
|
player.shuffleAll();
|
||||||
// if (playbackType === PlaybackType.LOCAL) {
|
|
||||||
// setQueueNext(playerData);
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -165,7 +131,12 @@ export const PlayQueueListControls = ({
|
|||||||
variant="subtle"
|
variant="subtle"
|
||||||
/>
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group gap="xs">
|
||||||
|
<SearchInput
|
||||||
|
enableHotkey={false}
|
||||||
|
onChange={(e) => handleSearch(e.target.value)}
|
||||||
|
value={searchTerm}
|
||||||
|
/>
|
||||||
<ListConfigMenu
|
<ListConfigMenu
|
||||||
listKey={ItemListKey.SIDE_QUEUE}
|
listKey={ItemListKey.SIDE_QUEUE}
|
||||||
tableColumnsData={SONG_TABLE_COLUMNS}
|
tableColumnsData={SONG_TABLE_COLUMNS}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import type { Ref } from 'react';
|
|
||||||
|
|
||||||
import { nanoid } from 'nanoid/non-secure';
|
import { nanoid } from 'nanoid/non-secure';
|
||||||
import { forwardRef, useEffect, useMemo, useRef } from 'react';
|
import { forwardRef, useEffect, useMemo, useRef } from 'react';
|
||||||
|
|
||||||
import { ItemTableList } from '/@/renderer/components/item-list/item-table-list/item-table-list';
|
import { ItemTableList } from '/@/renderer/components/item-list/item-table-list/item-table-list';
|
||||||
import { ItemTableListColumn } from '/@/renderer/components/item-list/item-table-list/item-table-list-column';
|
import { ItemTableListColumn } from '/@/renderer/components/item-list/item-table-list/item-table-list-column';
|
||||||
|
import { ItemListHandle } from '/@/renderer/components/item-list/types';
|
||||||
import {
|
import {
|
||||||
useIsPlayerFetching,
|
useIsPlayerFetching,
|
||||||
usePlayerContext,
|
usePlayerContext,
|
||||||
@@ -24,7 +23,7 @@ type QueueProps = {
|
|||||||
searchTerm: string | undefined;
|
searchTerm: string | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PlayQueue = forwardRef(({ listKey, searchTerm }: QueueProps, ref: Ref<any>) => {
|
export const PlayQueue = forwardRef<ItemListHandle, QueueProps>(({ listKey, searchTerm }, ref) => {
|
||||||
const { table } = useListSettings(listKey) || {};
|
const { table } = useListSettings(listKey) || {};
|
||||||
|
|
||||||
const queue = usePlayerQueue();
|
const queue = usePlayerQueue();
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import { ItemListHandle } from '/@/renderer/components/item-list/types';
|
||||||
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
|
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
|
||||||
import { PlayQueueListControls } from '/@/renderer/features/now-playing/components/play-queue-list-controls';
|
import { PlayQueueListControls } from '/@/renderer/features/now-playing/components/play-queue-list-controls';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { ItemListKey } from '/@/shared/types/types';
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const SidebarPlayQueue = () => {
|
export const SidebarPlayQueue = () => {
|
||||||
const tableRef = useRef<null>(null);
|
const tableRef = useRef<ItemListHandle | null>(null);
|
||||||
const [search, setSearch] = useState<string | undefined>(undefined);
|
const [search, setSearch] = useState<string | undefined>(undefined);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -17,7 +18,7 @@ export const SidebarPlayQueue = () => {
|
|||||||
tableRef={tableRef}
|
tableRef={tableRef}
|
||||||
type={ItemListKey.SIDE_QUEUE}
|
type={ItemListKey.SIDE_QUEUE}
|
||||||
/>
|
/>
|
||||||
<PlayQueue listKey={ItemListKey.SIDE_QUEUE} searchTerm={search} />
|
<PlayQueue listKey={ItemListKey.SIDE_QUEUE} ref={tableRef} searchTerm={search} />
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user