mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 04:20:12 +02:00
feat(queue): add go to current button
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
"addOrRemoveFromSelection": "add or remove from selection",
|
"addOrRemoveFromSelection": "add or remove from selection",
|
||||||
"selectRangeOfItems": "select a range of items",
|
"selectRangeOfItems": "select a range of items",
|
||||||
"clearQueue": "clear queue",
|
"clearQueue": "clear queue",
|
||||||
|
"goToCurrent": "go to current item",
|
||||||
"createPlaylist": "create $t(entity.playlist, {\"count\": 1})",
|
"createPlaylist": "create $t(entity.playlist, {\"count\": 1})",
|
||||||
"createRadioStation": "create $t(entity.radioStation, {\"count\": 1})",
|
"createRadioStation": "create $t(entity.radioStation, {\"count\": 1})",
|
||||||
"deletePlaylist": "delete $t(entity.playlist, {\"count\": 1})",
|
"deletePlaylist": "delete $t(entity.playlist, {\"count\": 1})",
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ export const DrawerPlayQueue = () => {
|
|||||||
<PlayQueueListControls
|
<PlayQueueListControls
|
||||||
handleSearch={setSearch}
|
handleSearch={setSearch}
|
||||||
searchTerm={search}
|
searchTerm={search}
|
||||||
|
tableRef={queueRef}
|
||||||
type={ItemListKey.SIDE_QUEUE}
|
type={ItemListKey.SIDE_QUEUE}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { useIsFetching } from '@tanstack/react-query';
|
import { useIsFetching } from '@tanstack/react-query';
|
||||||
import { t } from 'i18next';
|
import { t } from 'i18next';
|
||||||
|
import { RefObject } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { SONG_TABLE_COLUMNS } from '/@/renderer/components/item-list/item-table-list/default-columns';
|
import { SONG_TABLE_COLUMNS } from '/@/renderer/components/item-list/item-table-list/default-columns';
|
||||||
|
import { ItemListHandle } from '/@/renderer/components/item-list/types';
|
||||||
import { usePlayer } from '/@/renderer/features/player/context/player-context';
|
import { usePlayer } from '/@/renderer/features/player/context/player-context';
|
||||||
import { useRestoreQueue, useSaveQueue } from '/@/renderer/features/player/hooks/use-queue-restore';
|
import { useRestoreQueue, useSaveQueue } from '/@/renderer/features/player/hooks/use-queue-restore';
|
||||||
import {
|
import {
|
||||||
@@ -11,7 +13,7 @@ import {
|
|||||||
SONG_DISPLAY_TYPES,
|
SONG_DISPLAY_TYPES,
|
||||||
} from '/@/renderer/features/shared/components/list-config-menu';
|
} from '/@/renderer/features/shared/components/list-config-menu';
|
||||||
import { SearchInput } from '/@/renderer/features/shared/components/search-input';
|
import { SearchInput } from '/@/renderer/features/shared/components/search-input';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer, usePlayerStoreBase } from '/@/renderer/store';
|
||||||
import { hasFeature } from '/@/shared/api/utils';
|
import { hasFeature } from '/@/shared/api/utils';
|
||||||
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';
|
||||||
@@ -21,12 +23,14 @@ import { ItemListKey, ListDisplayType } from '/@/shared/types/types';
|
|||||||
interface PlayQueueListOptionsProps {
|
interface PlayQueueListOptionsProps {
|
||||||
handleSearch: (value: string) => void;
|
handleSearch: (value: string) => void;
|
||||||
searchTerm?: string;
|
searchTerm?: string;
|
||||||
|
tableRef: RefObject<ItemListHandle | null>;
|
||||||
type: ItemListKey;
|
type: ItemListKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PlayQueueListControls = ({
|
export const PlayQueueListControls = ({
|
||||||
handleSearch,
|
handleSearch,
|
||||||
searchTerm,
|
searchTerm,
|
||||||
|
tableRef,
|
||||||
type,
|
type,
|
||||||
}: PlayQueueListOptionsProps) => {
|
}: PlayQueueListOptionsProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@@ -36,6 +40,13 @@ export const PlayQueueListControls = ({
|
|||||||
player.clearQueue();
|
player.clearQueue();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleJumpToCurrent = () => {
|
||||||
|
const index = usePlayerStoreBase.getState().player.index;
|
||||||
|
if (index !== -1) {
|
||||||
|
tableRef.current?.scrollToIndex(index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleShuffleQueue = () => {
|
const handleShuffleQueue = () => {
|
||||||
player.shuffleAll();
|
player.shuffleAll();
|
||||||
};
|
};
|
||||||
@@ -58,6 +69,13 @@ export const PlayQueueListControls = ({
|
|||||||
tooltip={{ label: t('action.clearQueue', { postProcess: 'sentenceCase' }) }}
|
tooltip={{ label: t('action.clearQueue', { postProcess: 'sentenceCase' }) }}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
/>
|
/>
|
||||||
|
<ActionIcon
|
||||||
|
icon="goToItem"
|
||||||
|
iconProps={{ size: 'lg' }}
|
||||||
|
onClick={handleJumpToCurrent}
|
||||||
|
tooltip={{ label: t('action.goToCurrent', { postProcess: 'sentenceCase' }) }}
|
||||||
|
variant="subtle"
|
||||||
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
<Group gap="xs">
|
<Group gap="xs">
|
||||||
<SearchInput
|
<SearchInput
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ export const PopoverPlayQueue = ({
|
|||||||
<PlayQueueListControls
|
<PlayQueueListControls
|
||||||
handleSearch={setSearch}
|
handleSearch={setSearch}
|
||||||
searchTerm={search}
|
searchTerm={search}
|
||||||
|
tableRef={queueRef}
|
||||||
type={ItemListKey.SIDE_QUEUE}
|
type={ItemListKey.SIDE_QUEUE}
|
||||||
/>
|
/>
|
||||||
<PlayQueue
|
<PlayQueue
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ export const SidebarPlayQueue = () => {
|
|||||||
<PlayQueueListControls
|
<PlayQueueListControls
|
||||||
handleSearch={setSearch}
|
handleSearch={setSearch}
|
||||||
searchTerm={search}
|
searchTerm={search}
|
||||||
|
tableRef={tableRef}
|
||||||
type={ItemListKey.SIDE_QUEUE}
|
type={ItemListKey.SIDE_QUEUE}
|
||||||
/>
|
/>
|
||||||
<div className={styles.playQueueSection}>
|
<div className={styles.playQueueSection}>
|
||||||
@@ -217,6 +218,7 @@ export const SidebarPlayQueue = () => {
|
|||||||
<PlayQueueListControls
|
<PlayQueueListControls
|
||||||
handleSearch={setSearch}
|
handleSearch={setSearch}
|
||||||
searchTerm={search}
|
searchTerm={search}
|
||||||
|
tableRef={tableRef}
|
||||||
type={ItemListKey.SIDE_QUEUE}
|
type={ItemListKey.SIDE_QUEUE}
|
||||||
/>
|
/>
|
||||||
<Flex direction="column" style={{ flex: 1, minHeight: 0 }}>
|
<Flex direction="column" style={{ flex: 1, minHeight: 0 }}>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import { ItemListHandle } from '/@/renderer/components/item-list/types';
|
||||||
import { NowPlayingHeader } from '/@/renderer/features/now-playing/components/now-playing-header';
|
import { NowPlayingHeader } from '/@/renderer/features/now-playing/components/now-playing-header';
|
||||||
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';
|
||||||
@@ -11,6 +12,7 @@ import { ItemListKey } from '/@/shared/types/types';
|
|||||||
const NowPlayingRoute = () => {
|
const NowPlayingRoute = () => {
|
||||||
const [search, setSearch] = useState<string | undefined>(undefined);
|
const [search, setSearch] = useState<string | undefined>(undefined);
|
||||||
const { setSideBar } = useAppStoreActions();
|
const { setSideBar } = useAppStoreActions();
|
||||||
|
const tableRef = useRef<ItemListHandle | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// On page enter, set rightExpanded to false
|
// On page enter, set rightExpanded to false
|
||||||
@@ -28,9 +30,10 @@ const NowPlayingRoute = () => {
|
|||||||
<PlayQueueListControls
|
<PlayQueueListControls
|
||||||
handleSearch={setSearch}
|
handleSearch={setSearch}
|
||||||
searchTerm={search}
|
searchTerm={search}
|
||||||
|
tableRef={tableRef}
|
||||||
type={ItemListKey.QUEUE_SONG}
|
type={ItemListKey.QUEUE_SONG}
|
||||||
/>
|
/>
|
||||||
<PlayQueue listKey={ItemListKey.QUEUE_SONG} searchTerm={search} />
|
<PlayQueue listKey={ItemListKey.QUEUE_SONG} ref={tableRef} searchTerm={search} />
|
||||||
</AnimatedPage>
|
</AnimatedPage>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import {
|
|||||||
LuClipboardCopy,
|
LuClipboardCopy,
|
||||||
LuClock3,
|
LuClock3,
|
||||||
LuCloudDownload,
|
LuCloudDownload,
|
||||||
|
LuCornerDownRight,
|
||||||
LuCornerUpRight,
|
LuCornerUpRight,
|
||||||
LuDelete,
|
LuDelete,
|
||||||
LuDisc,
|
LuDisc,
|
||||||
@@ -183,6 +184,7 @@ export const AppIcon = {
|
|||||||
filter: LuListFilter,
|
filter: LuListFilter,
|
||||||
folder: LuFolderOpen,
|
folder: LuFolderOpen,
|
||||||
genre: LuFlag,
|
genre: LuFlag,
|
||||||
|
goToItem: LuCornerDownRight,
|
||||||
hash: LuHash,
|
hash: LuHash,
|
||||||
home: LuSquareMenu,
|
home: LuSquareMenu,
|
||||||
image: LuImage,
|
image: LuImage,
|
||||||
|
|||||||
Reference in New Issue
Block a user