Skip to content

Commit

Permalink
Add "Move to next" button to queue (#781)
Browse files Browse the repository at this point in the history
  • Loading branch information
TrevTV authored Oct 10, 2024
1 parent 5e628d9 commit a00385e
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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)",
Expand Down Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions src/renderer/features/context-menu/context-menu-items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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' },
Expand Down
22 changes: 21 additions & 1 deletion src/renderer/features/context-menu/context-menu-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
RiAddBoxFill,
RiAddCircleFill,
RiArrowDownLine,
RiArrowGoForwardLine,
RiArrowRightSFill,
RiArrowUpLine,
RiDeleteBinFill,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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' }),
Expand Down Expand Up @@ -904,6 +923,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
handleDeselectAll,
ctx.data,
handleDownload,
handleMoveToNext,
handleMoveToBottom,
handleMoveToTop,
handleSimilar,
Expand Down
1 change: 1 addition & 0 deletions src/renderer/features/context-menu/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type ContextMenuItemType =
| 'shareItem'
| 'deletePlaylist'
| 'createPlaylist'
| 'moveToNextOfQueue'
| 'moveToBottomOfQueue'
| 'moveToTopOfQueue'
| 'removeFromQueue'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import isElectron from 'is-electron';
import { useTranslation } from 'react-i18next';
import {
RiArrowDownLine,
RiArrowGoForwardLine,
RiArrowUpLine,
RiShuffleLine,
RiDeleteBinLine,
Expand All @@ -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);
Expand Down Expand Up @@ -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"
Expand Down
30 changes: 30 additions & 0 deletions src/renderer/store/player.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit a00385e

Please sign in to comment.