Skip to content
This repository has been archived by the owner on Aug 23, 2024. It is now read-only.

Commit

Permalink
Refactor drag end to hook
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffvli committed Feb 5, 2022
1 parent b58d2c6 commit 97457de
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 136 deletions.
22 changes: 4 additions & 18 deletions src/components/player/NowPlayingMiniView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import { useHotkeys } from 'react-hotkeys-hook';
import { useQuery } from 'react-query';
import { useTranslation } from 'react-i18next';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import { clearSelected, setIsDragging } from '../../redux/multiSelectSlice';
import { clearSelected } from '../../redux/multiSelectSlice';
import {
fixPlayer2Index,
clearPlayQueue,
shuffleInPlace,
toggleShuffle,
moveToIndex,
setPlaybackSetting,
removeFromPlayQueue,
setStar,
Expand Down Expand Up @@ -129,22 +128,9 @@ const NowPlayingMiniView = () => {
}
}, [playQueue.currentIndex, tableRef, playQueue.displayQueue, playQueue.scrollWithCurrentSong]);

const { handleRowClick, handleRowDoubleClick } = useListClickHandler();

const handleDragEnd = () => {
if (multiSelect.isDragging) {
dispatch(
moveToIndex({
entries: multiSelect.selected,
moveBeforeId: multiSelect.currentMouseOverId,
})
);
dispatch(setIsDragging(false));
if (playQueue.currentPlayer === 1) {
dispatch(fixPlayer2Index());
}
}
};
const { handleRowClick, handleRowDoubleClick, handleDragEnd } = useListClickHandler({
dnd: 'playQueue',
});

const handlePlayRandom = async (action: 'play' | 'addNext' | 'addLater') => {
setIsLoadingRandom(true);
Expand Down
22 changes: 4 additions & 18 deletions src/components/player/NowPlayingView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
clearPlayQueue,
shuffleInPlace,
toggleShuffle,
moveToIndex,
setPlaybackSetting,
removeFromPlayQueue,
setPlayQueue,
Expand All @@ -22,7 +21,7 @@ import {
moveToTop,
moveToBottom,
} from '../../redux/playQueueSlice';
import { clearSelected, setIsDragging } from '../../redux/multiSelectSlice';
import { clearSelected } from '../../redux/multiSelectSlice';
import GenericPage from '../layout/GenericPage';
import GenericPageHeader from '../layout/GenericPageHeader';
import ListViewType from '../viewtypes/ListViewType';
Expand Down Expand Up @@ -143,22 +142,9 @@ const NowPlayingView = () => {
}
}, [playQueue.currentIndex, playQueue.scrollWithCurrentSong, tableRef]);

const { handleRowClick, handleRowDoubleClick } = useListClickHandler();

const handleDragEnd = () => {
if (multiSelect.isDragging) {
dispatch(
moveToIndex({
entries: multiSelect.selected,
moveBeforeId: multiSelect.currentMouseOverId,
})
);
dispatch(setIsDragging(false));
if (playQueue.currentPlayer === 1) {
dispatch(fixPlayer2Index());
}
}
};
const { handleRowClick, handleRowDoubleClick, handleDragEnd } = useListClickHandler({
dnd: 'playQueue',
});

const handlePlayRandom = async (action: 'play' | 'addNext' | 'addLater') => {
setIsLoadingRandom(true);
Expand Down
18 changes: 3 additions & 15 deletions src/components/playlist/PlaylistView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
setRate,
clearPlayQueue,
} from '../../redux/playQueueSlice';
import { clearSelected, setIsDragging } from '../../redux/multiSelectSlice';
import { clearSelected } from '../../redux/multiSelectSlice';
import {
createRecoveryFile,
errorMessages,
Expand Down Expand Up @@ -57,7 +57,6 @@ import {
StyledPopover,
} from '../shared/styled';
import {
moveToIndex,
removeFromPlaylist,
setPlaylistData,
setPlaylistRate,
Expand Down Expand Up @@ -148,7 +147,7 @@ const PlaylistView = ({ ...rest }) => {
}
}, [data?.song, playlist]);

const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
const { handleRowClick, handleRowDoubleClick, handleDragEnd } = useListClickHandler({
doubleClick: (rowData: any) => {
dispatch(
setPlayQueueByRowClick({
Expand All @@ -162,6 +161,7 @@ const PlaylistView = ({ ...rest }) => {
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
},
dnd: 'playlist',
});

const handlePlay = () => {
Expand Down Expand Up @@ -392,18 +392,6 @@ const PlaylistView = ({ ...rest }) => {
}
};

const handleDragEnd = () => {
if (multiSelect.isDragging) {
dispatch(
moveToIndex({
selectedEntries: multiSelect.selected,
moveBeforeId: multiSelect.currentMouseOverId,
})
);
dispatch(setIsDragging(false));
}
};

const handleRowFavorite = async (rowData: any) => {
if (!rowData.starred) {
await apiController({
Expand Down
22 changes: 15 additions & 7 deletions src/components/shared/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import {
getCurrentEntryList,
getPlayedSongsNotification,
isFailedResponse,
moveSelectedToIndex,
} from '../../shared/utils';
import { setStatus } from '../../redux/playerSlice';
import { apiController } from '../../api/controller';
Expand Down Expand Up @@ -644,20 +645,27 @@ export const GlobalContextMenu = () => {
if (Number(indexToMoveTo) === playQueue[currentEntryList].length) {
dispatch(moveToBottom({ selectedEntries: multiSelect.selected }));
} else {
const uniqueIdOfIndexToMoveTo = playQueue[currentEntryList][indexToMoveTo].uniqueId;
dispatch(
moveToIndex({ entries: multiSelect.selected, moveBeforeId: uniqueIdOfIndexToMoveTo })
moveToIndex(
moveSelectedToIndex(
playQueue[currentEntryList],
multiSelect.selected,
playQueue[currentEntryList][indexToMoveTo].uniqueId
)
)
);
}
} else if (Number(indexToMoveTo) === playlist.entry.length) {
dispatch(plMoveToBottom({ selectedEntries: multiSelect.selected }));
} else {
const uniqueIdOfIndexToMoveTo = playlist.entry[indexToMoveTo].uniqueId;
dispatch(
plMoveToIndex({
selectedEntries: multiSelect.selected,
moveBeforeId: uniqueIdOfIndexToMoveTo,
})
plMoveToIndex(
moveSelectedToIndex(
playlist.entry,
multiSelect.selected,
playlist.entry[indexToMoveTo].uniqueId
)
)
);
}
};
Expand Down
6 changes: 5 additions & 1 deletion src/components/viewtypes/ListViewTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,11 @@ const ListViewTable = ({
}}
onMouseUp={() => {
if (dnd) {
handleDragEnd();
handleDragEnd(sortColumn && !nowPlaying ? sortedData : data);

if (nowPlaying && playQueue.currentPlayer === 1) {
dispatch(fixPlayer2Index());
}
} else {
handleSelectMouseUp();
}
Expand Down
45 changes: 40 additions & 5 deletions src/hooks/useListClickHandler.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { useAppDispatch, useAppSelector } from '../redux/hooks';
import { clearSelected, setSelected, toggleSelected } from '../redux/multiSelectSlice';
import {
clearSelected,
setIsDragging,
setSelected,
toggleSelected,
} from '../redux/multiSelectSlice';
import { setStatus } from '../redux/playerSlice';
import { fixPlayer2Index, setPlayerIndex } from '../redux/playQueueSlice';
import { sliceRangeByUniqueId } from '../shared/utils';
import { fixPlayer2Index, moveToIndex, setPlayerIndex } from '../redux/playQueueSlice';
import { moveToIndex as moveToIndexPlaylist } from '../redux/playlistSlice';
import { moveToIndex as moveToIndexConfig } from '../redux/configSlice';
import { moveSelectedToIndex, sliceRangeByUniqueId } from '../shared/utils';

const useListClickHandler = (options?: { singleClick?: any; doubleClick?: any }) => {
const useListClickHandler = (options?: {
singleClick?: any;
doubleClick?: any;
dnd?: 'playQueue' | 'playlist' | 'config';
}) => {
const dispatch = useAppDispatch();
const multiSelect = useAppSelector((state) => state.multiSelect);

Expand Down Expand Up @@ -46,7 +57,31 @@ const useListClickHandler = (options?: { singleClick?: any; doubleClick?: any })
}
};

return { handleRowClick, handleRowDoubleClick };
const handleDragEnd = (entries: any) => {
if (multiSelect.isDragging) {
const reorderedQueue = moveSelectedToIndex(
entries,
multiSelect.selected,
multiSelect.currentMouseOverId
);

if (options?.dnd === 'playQueue') {
dispatch(moveToIndex(reorderedQueue));
}

if (options?.dnd === 'playlist') {
dispatch(moveToIndexPlaylist(reorderedQueue));
}

if (options?.dnd === 'config') {
dispatch(moveToIndexConfig(reorderedQueue));
}

dispatch(setIsDragging(false));
}
};

return { handleRowClick, handleRowDoubleClick, handleDragEnd };
};

export default useListClickHandler;
69 changes: 7 additions & 62 deletions src/redux/playQueueSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -907,73 +907,18 @@ const playQueueSlice = createSlice({
state.isFading = action.payload;
},

moveToIndex: (state, action: PayloadAction<{ entries: Entry[]; moveBeforeId: string }>) => {
moveToIndex: (state, action: PayloadAction<Entry[]>) => {
const currentEntry = entrySelect(state);
const tempQueue = state[currentEntry].slice();
const uniqueIds = _.map(action.payload.entries, 'uniqueId');

// Remove the selected entries from the queue
const newQueue = tempQueue.filter((entry: Entry) => {
return !uniqueIds.includes(entry.uniqueId);
});

/* Used if dragging onto the first selected row. We'll need to calculate the number of selected rows above the first selected row
so we can subtract it from the spliceIndexPre value when moving it into the newQueue, which has all selected entries removed */
const spliceIndexPre = getCurrentEntryIndexByUID(tempQueue, action.payload.moveBeforeId);

const queueAbovePre = tempQueue.slice(0, spliceIndexPre);
const selectedAbovePre = queueAbovePre.filter((entry: Entry) => {
return uniqueIds.includes(entry.uniqueId);
});

// Used if dragging onto a non-selected row
const spliceIndexPost = getCurrentEntryIndexByUID(newQueue, action.payload.moveBeforeId);

/* Used if dragging onto consecutive selected rows
If the moveBeforeId index is selected, then we find the first consecutive selected index to move to */
let firstConsecutiveSelectedDragIndex = -1;
for (let i = spliceIndexPre - 1; i > 0; i -= 1) {
if (uniqueIds.includes(tempQueue[i].uniqueId)) {
firstConsecutiveSelectedDragIndex = i;
} else {
break;
}
}

/* If we get a negative index, don't move the entry.
This can happen if you try to drag and drop too fast */
if (spliceIndexPre < 0 && spliceIndexPre < 0) {
return;
}

// Find the slice index to add the selected entries to
const spliceIndex =
spliceIndexPost >= 0
? spliceIndexPost
: firstConsecutiveSelectedDragIndex >= 0
? firstConsecutiveSelectedDragIndex
: spliceIndexPre - selectedAbovePre.length;

// Get the updated entry rowIndexes since dragging an entry multiple times will change the existing selected rowIndex
const updatedEntries = action.payload.entries.map((entry: Entry) => {
const findIndex = state[currentEntry].findIndex(
(item: Entry) => item.uniqueId === entry.uniqueId
);
return { ...entry, rowIndex: findIndex };
});

// Sort the entries by their rowIndex so that we can re-add them in the proper order
const sortedEntries = updatedEntries.sort((a, b) => a.rowIndex - b.rowIndex);

// Splice the entries into the new queue array
newQueue.splice(spliceIndex, 0, ...sortedEntries);

// Finally, set the modified entries into the redux state
state[currentEntry] = newQueue;
// Set the modified entries into the redux state
state[currentEntry] = action.payload;

// We'll need to fix the current player index after swapping the queue order
// This will be used in conjunction with fixPlayer2Index
const newCurrentSongIndex = getCurrentEntryIndexByUID(newQueue, state.currentSongUniqueId);
const newCurrentSongIndex = getCurrentEntryIndexByUID(
action.payload,
state.currentSongUniqueId
);

if (state.currentPlayer === 1) {
state.player1.index = newCurrentSongIndex;
Expand Down
12 changes: 2 additions & 10 deletions src/redux/playlistSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import _ from 'lodash';
import {
moveSelectedDown,
moveSelectedToBottom,
moveSelectedToIndex,
moveSelectedToTop,
moveSelectedUp,
} from '../shared/utils';
Expand Down Expand Up @@ -85,15 +84,8 @@ const playlistSlice = createSlice({
state.entry = state.entry.filter((entry) => !uniqueIds.includes(entry.uniqueId));
},

moveToIndex: (
state,
action: PayloadAction<{ selectedEntries: Entry[]; moveBeforeId: string }>
) => {
state.entry = moveSelectedToIndex(
state.entry,
action.payload.selectedEntries,
action.payload.moveBeforeId
);
moveToIndex: (state, action: PayloadAction<Entry[]>) => {
state.entry = action.payload;
},

moveUp: (state, action: PayloadAction<{ selectedEntries: Entry[] }>) => {
Expand Down

0 comments on commit 97457de

Please sign in to comment.