mirror of
https://github.com/jeffvli/feishin.git
synced 2024-11-20 14:37:06 +01:00
Add "Move to next" button to queue (#781)
This commit is contained in:
parent
5e628d96c7
commit
a00385e78f
@ -8,6 +8,7 @@
|
|||||||
"deselectAll": "deselect all",
|
"deselectAll": "deselect all",
|
||||||
"editPlaylist": "edit $t(entity.playlist_one)",
|
"editPlaylist": "edit $t(entity.playlist_one)",
|
||||||
"goToPage": "go to page",
|
"goToPage": "go to page",
|
||||||
|
"moveToNext": "move to next",
|
||||||
"moveToBottom": "move to bottom",
|
"moveToBottom": "move to bottom",
|
||||||
"moveToTop": "move to top",
|
"moveToTop": "move to top",
|
||||||
"refresh": "$t(common.refresh)",
|
"refresh": "$t(common.refresh)",
|
||||||
@ -335,6 +336,7 @@
|
|||||||
"deletePlaylist": "$t(action.deletePlaylist)",
|
"deletePlaylist": "$t(action.deletePlaylist)",
|
||||||
"deselectAll": "$t(action.deselectAll)",
|
"deselectAll": "$t(action.deselectAll)",
|
||||||
"download": "download",
|
"download": "download",
|
||||||
|
"moveToNext": "$t(action.moveToNext)",
|
||||||
"moveToBottom": "$t(action.moveToBottom)",
|
"moveToBottom": "$t(action.moveToBottom)",
|
||||||
"moveToTop": "$t(action.moveToTop)",
|
"moveToTop": "$t(action.moveToTop)",
|
||||||
"numberSelected": "{{count}} selected",
|
"numberSelected": "{{count}} selected",
|
||||||
|
@ -2,6 +2,7 @@ import { SetContextMenuItems } from '/@/renderer/features/context-menu/events';
|
|||||||
|
|
||||||
export const QUEUE_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
|
export const QUEUE_CONTEXT_MENU_ITEMS: SetContextMenuItems = [
|
||||||
{ divider: true, id: 'removeFromQueue' },
|
{ divider: true, id: 'removeFromQueue' },
|
||||||
|
{ id: 'moveToNextOfQueue' },
|
||||||
{ id: 'moveToBottomOfQueue' },
|
{ id: 'moveToBottomOfQueue' },
|
||||||
{ divider: true, id: 'moveToTopOfQueue' },
|
{ divider: true, id: 'moveToTopOfQueue' },
|
||||||
{ divider: true, id: 'addToPlaylist' },
|
{ divider: true, id: 'addToPlaylist' },
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
RiAddBoxFill,
|
RiAddBoxFill,
|
||||||
RiAddCircleFill,
|
RiAddCircleFill,
|
||||||
RiArrowDownLine,
|
RiArrowDownLine,
|
||||||
|
RiArrowGoForwardLine,
|
||||||
RiArrowRightSFill,
|
RiArrowRightSFill,
|
||||||
RiArrowUpLine,
|
RiArrowUpLine,
|
||||||
RiDeleteBinFill,
|
RiDeleteBinFill,
|
||||||
@ -609,7 +610,19 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const playbackType = usePlaybackType();
|
const playbackType = usePlaybackType();
|
||||||
const { moveToBottomOfQueue, moveToTopOfQueue, removeFromQueue } = useQueueControls();
|
const { moveToNextOfQueue, moveToBottomOfQueue, moveToTopOfQueue, removeFromQueue } =
|
||||||
|
useQueueControls();
|
||||||
|
|
||||||
|
const handleMoveToNext = useCallback(() => {
|
||||||
|
const uniqueIds = ctx.dataNodes?.map((row) => row.data.uniqueId);
|
||||||
|
if (!uniqueIds?.length) return;
|
||||||
|
|
||||||
|
const playerData = moveToNextOfQueue(uniqueIds);
|
||||||
|
|
||||||
|
if (playbackType === PlaybackType.LOCAL) {
|
||||||
|
setQueueNext(playerData);
|
||||||
|
}
|
||||||
|
}, [ctx.dataNodes, moveToNextOfQueue, playbackType]);
|
||||||
|
|
||||||
const handleMoveToBottom = useCallback(() => {
|
const handleMoveToBottom = useCallback(() => {
|
||||||
const uniqueIds = ctx.dataNodes?.map((row) => row.data.uniqueId);
|
const uniqueIds = ctx.dataNodes?.map((row) => row.data.uniqueId);
|
||||||
@ -758,6 +771,12 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||||||
leftIcon: <RiArrowDownLine size="1.1rem" />,
|
leftIcon: <RiArrowDownLine size="1.1rem" />,
|
||||||
onClick: handleMoveToBottom,
|
onClick: handleMoveToBottom,
|
||||||
},
|
},
|
||||||
|
moveToNextOfQueue: {
|
||||||
|
id: 'moveToNext',
|
||||||
|
label: t('page.contextMenu.moveToNext', { postProcess: 'sentenceCase' }),
|
||||||
|
leftIcon: <RiArrowGoForwardLine size="1.1rem" />,
|
||||||
|
onClick: handleMoveToNext,
|
||||||
|
},
|
||||||
moveToTopOfQueue: {
|
moveToTopOfQueue: {
|
||||||
id: 'moveToTopOfQueue',
|
id: 'moveToTopOfQueue',
|
||||||
label: t('page.contextMenu.moveToTop', { postProcess: 'sentenceCase' }),
|
label: t('page.contextMenu.moveToTop', { postProcess: 'sentenceCase' }),
|
||||||
@ -904,6 +923,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||||||
handleDeselectAll,
|
handleDeselectAll,
|
||||||
ctx.data,
|
ctx.data,
|
||||||
handleDownload,
|
handleDownload,
|
||||||
|
handleMoveToNext,
|
||||||
handleMoveToBottom,
|
handleMoveToBottom,
|
||||||
handleMoveToTop,
|
handleMoveToTop,
|
||||||
handleSimilar,
|
handleSimilar,
|
||||||
|
@ -32,6 +32,7 @@ export type ContextMenuItemType =
|
|||||||
| 'shareItem'
|
| 'shareItem'
|
||||||
| 'deletePlaylist'
|
| 'deletePlaylist'
|
||||||
| 'createPlaylist'
|
| 'createPlaylist'
|
||||||
|
| 'moveToNextOfQueue'
|
||||||
| 'moveToBottomOfQueue'
|
| 'moveToBottomOfQueue'
|
||||||
| 'moveToTopOfQueue'
|
| 'moveToTopOfQueue'
|
||||||
| 'removeFromQueue'
|
| 'removeFromQueue'
|
||||||
|
@ -6,6 +6,7 @@ import isElectron from 'is-electron';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {
|
import {
|
||||||
RiArrowDownLine,
|
RiArrowDownLine,
|
||||||
|
RiArrowGoForwardLine,
|
||||||
RiArrowUpLine,
|
RiArrowUpLine,
|
||||||
RiShuffleLine,
|
RiShuffleLine,
|
||||||
RiDeleteBinLine,
|
RiDeleteBinLine,
|
||||||
@ -30,14 +31,32 @@ interface PlayQueueListOptionsProps {
|
|||||||
|
|
||||||
export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsProps) => {
|
export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { clearQueue, moveToBottomOfQueue, moveToTopOfQueue, shuffleQueue, removeFromQueue } =
|
const {
|
||||||
useQueueControls();
|
clearQueue,
|
||||||
|
moveToBottomOfQueue,
|
||||||
|
moveToNextOfQueue,
|
||||||
|
moveToTopOfQueue,
|
||||||
|
shuffleQueue,
|
||||||
|
removeFromQueue,
|
||||||
|
} = useQueueControls();
|
||||||
|
|
||||||
const { pause } = usePlayerControls();
|
const { pause } = usePlayerControls();
|
||||||
|
|
||||||
const playbackType = usePlaybackType();
|
const playbackType = usePlaybackType();
|
||||||
const setCurrentTime = useSetCurrentTime();
|
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 handleMoveToBottom = () => {
|
const handleMoveToBottom = () => {
|
||||||
const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
|
const selectedRows = tableRef?.current?.grid.api.getSelectedRows();
|
||||||
const uniqueIds = selectedRows?.map((row) => row.uniqueId);
|
const uniqueIds = selectedRows?.map((row) => row.uniqueId);
|
||||||
@ -124,6 +143,15 @@ export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsPr
|
|||||||
>
|
>
|
||||||
<RiShuffleLine size="1.1rem" />
|
<RiShuffleLine size="1.1rem" />
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
size="md"
|
||||||
|
tooltip={{ label: t('action.moveToNext', { postProcess: 'sentenceCase' }) }}
|
||||||
|
variant="default"
|
||||||
|
onClick={handleMoveToNext}
|
||||||
|
>
|
||||||
|
<RiArrowGoForwardLine size="1.1rem" />
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
size="md"
|
size="md"
|
||||||
|
@ -72,6 +72,7 @@ export interface PlayerSlice extends PlayerState {
|
|||||||
getQueueData: () => QueueData;
|
getQueueData: () => QueueData;
|
||||||
incrementPlayCount: (ids: string[]) => string[];
|
incrementPlayCount: (ids: string[]) => string[];
|
||||||
moveToBottomOfQueue: (uniqueIds: string[]) => PlayerData;
|
moveToBottomOfQueue: (uniqueIds: string[]) => PlayerData;
|
||||||
|
moveToNextOfQueue: (uniqueIds: string[]) => PlayerData;
|
||||||
moveToTopOfQueue: (uniqueIds: string[]) => PlayerData;
|
moveToTopOfQueue: (uniqueIds: string[]) => PlayerData;
|
||||||
next: () => PlayerData;
|
next: () => PlayerData;
|
||||||
pause: () => void;
|
pause: () => void;
|
||||||
@ -536,6 +537,34 @@ export const usePlayerStore = create<PlayerSlice>()(
|
|||||||
|
|
||||||
return get().actions.getPlayerData();
|
return get().actions.getPlayerData();
|
||||||
},
|
},
|
||||||
|
moveToNextOfQueue: (uniqueIds) => {
|
||||||
|
const queue = get().queue.default;
|
||||||
|
const songsToMove = queue.filter((song) =>
|
||||||
|
uniqueIds.includes(song.uniqueId),
|
||||||
|
);
|
||||||
|
const currentSong = get().current.song;
|
||||||
|
const currentPosition =
|
||||||
|
get().current.index -
|
||||||
|
queue
|
||||||
|
.slice(0, get().current.index)
|
||||||
|
.filter((song) => uniqueIds.includes(song.uniqueId)).length;
|
||||||
|
const songsToStay = queue.filter(
|
||||||
|
(song) => !uniqueIds.includes(song.uniqueId),
|
||||||
|
);
|
||||||
|
const newQueue = [
|
||||||
|
...songsToStay.slice(0, currentPosition + 1),
|
||||||
|
...songsToMove,
|
||||||
|
...songsToStay.slice(currentPosition + 1),
|
||||||
|
];
|
||||||
|
const newCurrentSongIndex = newQueue.findIndex(
|
||||||
|
(song) => song.uniqueId === currentSong?.uniqueId,
|
||||||
|
);
|
||||||
|
set((state) => {
|
||||||
|
state.queue.default = newQueue;
|
||||||
|
state.current.index = newCurrentSongIndex;
|
||||||
|
});
|
||||||
|
return get().actions.getPlayerData();
|
||||||
|
},
|
||||||
moveToTopOfQueue: (uniqueIds) => {
|
moveToTopOfQueue: (uniqueIds) => {
|
||||||
const queue = get().queue.default;
|
const queue = get().queue.default;
|
||||||
|
|
||||||
@ -1076,6 +1105,7 @@ export const useQueueControls = () =>
|
|||||||
addToQueue: state.actions.addToQueue,
|
addToQueue: state.actions.addToQueue,
|
||||||
clearQueue: state.actions.clearQueue,
|
clearQueue: state.actions.clearQueue,
|
||||||
moveToBottomOfQueue: state.actions.moveToBottomOfQueue,
|
moveToBottomOfQueue: state.actions.moveToBottomOfQueue,
|
||||||
|
moveToNextOfQueue: state.actions.moveToNextOfQueue,
|
||||||
moveToTopOfQueue: state.actions.moveToTopOfQueue,
|
moveToTopOfQueue: state.actions.moveToTopOfQueue,
|
||||||
removeFromQueue: state.actions.removeFromQueue,
|
removeFromQueue: state.actions.removeFromQueue,
|
||||||
reorderQueue: state.actions.reorderQueue,
|
reorderQueue: state.actions.reorderQueue,
|
||||||
|
Loading…
Reference in New Issue
Block a user