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