Browse Source

add shuffledEntry in slice

master
jeffvli 3 years ago
parent
commit
fae14521bb
  1. 19
      src/components/player/NowPlayingView.tsx
  2. 73
      src/components/player/Player.tsx
  3. 77
      src/components/player/PlayerBar.tsx
  4. 45
      src/components/settings/Config.tsx
  5. 14
      src/components/shared/setDefaultSettings.ts
  6. 203
      src/redux/playQueueSlice.ts

19
src/components/player/NowPlayingView.tsx

@ -1,6 +1,6 @@
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import settings from 'electron-settings'; import settings from 'electron-settings';
import { Button, Checkbox } from 'rsuite'; import { Checkbox } from 'rsuite';
import { useAppDispatch, useAppSelector } from '../../redux/hooks'; import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import useSearchQuery from '../../hooks/useSearchQuery'; import useSearchQuery from '../../hooks/useSearchQuery';
import { import {
@ -10,7 +10,9 @@ import {
setPlayerVolume, setPlayerVolume,
fixPlayer2Index, fixPlayer2Index,
clearPlayQueue, clearPlayQueue,
shuffleInPlace,
shufflePlayQueue, shufflePlayQueue,
toggleShuffle,
} from '../../redux/playQueueSlice'; } from '../../redux/playQueueSlice';
import { import {
toggleSelected, toggleSelected,
@ -130,7 +132,12 @@ const NowPlayingView = () => {
<HeaderButton <HeaderButton
size="sm" size="sm"
onClick={() => { onClick={() => {
dispatch(shufflePlayQueue()); if (!playQueue.shuffle) {
dispatch(shufflePlayQueue());
dispatch(toggleShuffle());
} else {
dispatch(shuffleInPlace());
}
}} }}
> >
Shuffle Shuffle
@ -160,7 +167,13 @@ const NowPlayingView = () => {
> >
<ListViewType <ListViewType
ref={tableRef} ref={tableRef}
data={searchQuery !== '' ? filteredData : playQueue.entry} data={
searchQuery !== ''
? filteredData
: playQueue.shuffle
? playQueue.shuffledEntry
: playQueue.entry
}
currentIndex={playQueue.currentIndex} currentIndex={playQueue.currentIndex}
tableColumns={settings.getSync('songListColumns')} tableColumns={settings.getSync('songListColumns')}
handleRowClick={handleRowClick} handleRowClick={handleRowClick}

73
src/components/player/Player.tsx

@ -34,6 +34,15 @@ const Player = ({ children }: any, ref: any) => {
const cacheSongs = settings.getSync('cacheSongs'); const cacheSongs = settings.getSync('cacheSongs');
const [title, setTitle] = useState(''); const [title, setTitle] = useState('');
const [cachePath] = useState(path.join(getSongCachePath(), '/')); const [cachePath] = useState(path.join(getSongCachePath(), '/'));
const [currentEntryList, setCurrentEntryList] = useState('entry');
useEffect(() => {
if (playQueue.shuffle) {
setCurrentEntryList('shuffledEntry');
} else {
setCurrentEntryList('entry');
}
}, [playQueue.shuffle]);
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
get player1() { get player1() {
@ -80,7 +89,7 @@ const Player = ({ children }: any, ref: any) => {
// Don't fade if player2Index <= player1Index unless repeat==='all' // Don't fade if player2Index <= player1Index unless repeat==='all'
if ( if (
playQueue.player1.index + 1 < playQueue.entry.length || playQueue.player1.index + 1 < playQueue[currentEntryList].length ||
playQueue.repeat === 'all' playQueue.repeat === 'all'
) { ) {
if (currentSeek >= fadeAtTime) { if (currentSeek >= fadeAtTime) {
@ -139,7 +148,7 @@ const Player = ({ children }: any, ref: any) => {
const fadeAtTime = duration - fadeDuration; const fadeAtTime = duration - fadeDuration;
if ( if (
playQueue.player2.index + 1 < playQueue.entry.length || playQueue.player2.index + 1 < playQueue[currentEntryList].length ||
playQueue.repeat === 'all' playQueue.repeat === 'all'
) { ) {
if (currentSeek >= fadeAtTime) { if (currentSeek >= fadeAtTime) {
@ -182,8 +191,8 @@ const Player = ({ children }: any, ref: any) => {
const handleOnEnded1 = () => { const handleOnEnded1 = () => {
if (cacheSongs) { if (cacheSongs) {
cacheSong( cacheSong(
`${playQueue.entry[playQueue.player1.index].id}.mp3`, `${playQueue[currentEntryList][playQueue.player1.index].id}.mp3`,
playQueue.entry[playQueue.player1.index].streamUrl.replace( playQueue[currentEntryList][playQueue.player1.index].streamUrl.replace(
/stream/, /stream/,
'download' 'download'
) )
@ -201,10 +210,15 @@ const Player = ({ children }: any, ref: any) => {
} else { } else {
if (!playQueue.autoIncremented) { if (!playQueue.autoIncremented) {
dispatch(incrementCurrentIndex('none')); dispatch(incrementCurrentIndex('none'));
dispatch(setCurrentIndex(playQueue.entry[playQueue.player2.index])); dispatch(
setCurrentIndex(playQueue[currentEntryList][playQueue.player2.index])
);
dispatch(setAutoIncremented(true)); dispatch(setAutoIncremented(true));
} }
if (playQueue.entry.length > 1 || playQueue.repeat === 'all') { if (
playQueue[currentEntryList].length > 1 ||
playQueue.repeat === 'all'
) {
dispatch(setCurrentPlayer(2)); dispatch(setCurrentPlayer(2));
dispatch(incrementPlayerIndex(1)); dispatch(incrementPlayerIndex(1));
dispatch(setPlayerVolume({ player: 1, volume: 0 })); dispatch(setPlayerVolume({ player: 1, volume: 0 }));
@ -218,8 +232,8 @@ const Player = ({ children }: any, ref: any) => {
const handleOnEnded2 = () => { const handleOnEnded2 = () => {
if (cacheSongs) { if (cacheSongs) {
cacheSong( cacheSong(
`${playQueue.entry[playQueue.player2.index].id}.mp3`, `${playQueue[currentEntryList][playQueue.player2.index].id}.mp3`,
playQueue.entry[playQueue.player2.index].streamUrl.replace( playQueue[currentEntryList][playQueue.player2.index].streamUrl.replace(
/stream/, /stream/,
'download' 'download'
) )
@ -237,10 +251,15 @@ const Player = ({ children }: any, ref: any) => {
} else { } else {
if (!playQueue.autoIncremented) { if (!playQueue.autoIncremented) {
dispatch(incrementCurrentIndex('none')); dispatch(incrementCurrentIndex('none'));
dispatch(setCurrentIndex(playQueue.entry[playQueue.player1.index])); dispatch(
setCurrentIndex(playQueue[currentEntryList][playQueue.player1.index])
);
dispatch(setAutoIncremented(true)); dispatch(setAutoIncremented(true));
} }
if (playQueue.entry.length > 1 || playQueue.repeat === 'all') { if (
playQueue[currentEntryList].length > 1 ||
playQueue.repeat === 'all'
) {
dispatch(setCurrentPlayer(1)); dispatch(setCurrentPlayer(1));
dispatch(incrementPlayerIndex(2)); dispatch(incrementPlayerIndex(2));
dispatch(setPlayerVolume({ player: 1, volume: playQueue.volume })); dispatch(setPlayerVolume({ player: 1, volume: playQueue.volume }));
@ -260,17 +279,19 @@ const Player = ({ children }: any, ref: any) => {
useEffect(() => { useEffect(() => {
const playStatus = const playStatus =
player.status !== 'PLAYING' && playQueue.entry.length > 0 player.status !== 'PLAYING' && playQueue[currentEntryList].length > 0
? '(Paused)' ? '(Paused)'
: ''; : '';
const songTitle = playQueue.entry[playQueue.currentIndex]?.title const songTitle = playQueue[currentEntryList][playQueue.currentIndex]?.title
? `(${playQueue.currentIndex + 1} / ${playQueue.entry.length}) ~ ${ ? `(${playQueue.currentIndex + 1} / ${
playQueue.entry[playQueue.currentIndex]?.title playQueue[currentEntryList].length
} ~ ${playQueue.entry[playQueue.currentIndex]?.artist} ` }) ~ ${playQueue[currentEntryList][playQueue.currentIndex]?.title} ~ ${
playQueue[currentEntryList][playQueue.currentIndex]?.artist
} `
: 'sonixd'; : 'sonixd';
setTitle(`${playStatus} ${songTitle}`); setTitle(`${playStatus} ${songTitle}`);
}, [playQueue.currentIndex, playQueue.entry, player.status]); }, [currentEntryList, playQueue, playQueue.currentIndex, player.status]);
return ( return (
<> <>
@ -282,10 +303,14 @@ const Player = ({ children }: any, ref: any) => {
ref={player1Ref} ref={player1Ref}
src={ src={
isCached( isCached(
`${cachePath}/${playQueue.entry[playQueue.player1.index]?.id}.mp3` `${cachePath}/${
playQueue[currentEntryList][playQueue.player1.index]?.id
}.mp3`
) )
? `${cachePath}/${playQueue.entry[playQueue.player1.index]?.id}.mp3` ? `${cachePath}/${
: playQueue.entry[playQueue.player1.index]?.streamUrl playQueue[currentEntryList][playQueue.player1.index]?.id
}.mp3`
: playQueue[currentEntryList][playQueue.player1.index]?.streamUrl
} }
listenInterval={150} listenInterval={150}
preload="auto" preload="auto"
@ -302,10 +327,14 @@ const Player = ({ children }: any, ref: any) => {
ref={player2Ref} ref={player2Ref}
src={ src={
isCached( isCached(
`${cachePath}/${playQueue.entry[playQueue.player2.index]?.id}.mp3` `${cachePath}/${
playQueue[currentEntryList][playQueue.player2.index]?.id
}.mp3`
) )
? `${cachePath}/${playQueue.entry[playQueue.player2.index]?.id}.mp3` ? `${cachePath}/${
: playQueue.entry[playQueue.player2.index]?.streamUrl playQueue[currentEntryList][playQueue.player2.index]?.id
}.mp3`
: playQueue[currentEntryList][playQueue.player2.index]?.streamUrl
} }
listenInterval={150} listenInterval={150}
preload="auto" preload="auto"

77
src/components/player/PlayerBar.tsx

@ -22,6 +22,7 @@ import {
toggleDisplayQueue, toggleDisplayQueue,
setStar, setStar,
shufflePlayQueue, shufflePlayQueue,
toggleShuffle,
} from '../../redux/playQueueSlice'; } from '../../redux/playQueueSlice';
import { setStatus, resetPlayer } from '../../redux/playerSlice'; import { setStatus, resetPlayer } from '../../redux/playerSlice';
import { useAppDispatch, useAppSelector } from '../../redux/hooks'; import { useAppDispatch, useAppSelector } from '../../redux/hooks';
@ -43,6 +44,7 @@ const PlayerBar = () => {
const [seek, setSeek] = useState(0); const [seek, setSeek] = useState(0);
const [isDragging, setIsDragging] = useState(false); const [isDragging, setIsDragging] = useState(false);
const [manualSeek, setManualSeek] = useState(0); const [manualSeek, setManualSeek] = useState(0);
const [currentEntryList, setCurrentEntryList] = useState('entry');
const [seekForwardInterval] = useState<number>( const [seekForwardInterval] = useState<number>(
Number(settings.getSync('seekForwardInterval')) || 5 Number(settings.getSync('seekForwardInterval')) || 5
); );
@ -52,6 +54,14 @@ const PlayerBar = () => {
const playersRef = useRef<any>(); const playersRef = useRef<any>();
const history = useHistory(); const history = useHistory();
useEffect(() => {
if (playQueue.shuffle) {
setCurrentEntryList('shuffledEntry');
} else {
setCurrentEntryList('entry');
}
}, [playQueue.shuffle]);
useEffect(() => { useEffect(() => {
setSeek(player.currentSeek); setSeek(player.currentSeek);
}, [player.currentSeek]); }, [player.currentSeek]);
@ -214,6 +224,7 @@ const PlayerBar = () => {
const handleShuffle = () => { const handleShuffle = () => {
dispatch(shufflePlayQueue()); dispatch(shufflePlayQueue());
dispatch(toggleShuffle());
}; };
const handleDisplayQueue = () => { const handleDisplayQueue = () => {
@ -221,11 +232,11 @@ const PlayerBar = () => {
}; };
const handleFavorite = async () => { const handleFavorite = async () => {
if (!playQueue.entry[playQueue.currentIndex].starred) { if (!playQueue[currentEntryList][playQueue.currentIndex].starred) {
star(playQueue.entry[playQueue.currentIndex].id, 'song'); star(playQueue[currentEntryList][playQueue.currentIndex].id, 'song');
dispatch( dispatch(
setStar({ setStar({
id: playQueue.entry[playQueue.currentIndex].id, id: playQueue[currentEntryList][playQueue.currentIndex].id,
type: 'star', type: 'star',
}) })
); );
@ -234,10 +245,10 @@ const PlayerBar = () => {
exact: true, exact: true,
}); });
} else { } else {
unstar(playQueue.entry[playQueue.currentIndex].id, 'song'); unstar(playQueue[currentEntryList][playQueue.currentIndex].id, 'song');
dispatch( dispatch(
setStar({ setStar({
id: playQueue.entry[playQueue.currentIndex].id, id: playQueue[currentEntryList][playQueue.currentIndex].id,
type: 'unstar', type: 'unstar',
}) })
); );
@ -266,10 +277,13 @@ const PlayerBar = () => {
}} }}
> >
<Col xs={2} style={{ height: '100%', width: '80px' }}> <Col xs={2} style={{ height: '100%', width: '80px' }}>
{playQueue.entry.length >= 1 && ( {playQueue[currentEntryList].length >= 1 && (
<LazyLoadImage <LazyLoadImage
tabIndex={0} tabIndex={0}
src={playQueue.entry[playQueue.currentIndex].image} src={
playQueue[currentEntryList][playQueue.currentIndex]
.image
}
alt="trackImg" alt="trackImg"
effect="opacity" effect="opacity"
width="65" width="65"
@ -293,11 +307,11 @@ const PlayerBar = () => {
alignItems: 'flex-end', alignItems: 'flex-end',
}} }}
> >
{playQueue.entry.length >= 1 && ( {playQueue[currentEntryList].length >= 1 && (
<CustomTooltip <CustomTooltip
text={ text={
playQueue.entry[playQueue.currentIndex]?.title || playQueue[currentEntryList][playQueue.currentIndex]
'Unknown title' ?.title || 'Unknown title'
} }
placement="topStart" placement="topStart"
> >
@ -306,14 +320,15 @@ const PlayerBar = () => {
onClick={() => onClick={() =>
history.push( history.push(
`/library/album/${ `/library/album/${
playQueue.entry[playQueue.currentIndex] playQueue[currentEntryList][
?.albumId playQueue.currentIndex
]?.albumId
}` }`
) )
} }
> >
{playQueue.entry[playQueue.currentIndex]?.title || {playQueue[currentEntryList][playQueue.currentIndex]
'Unknown title'} ?.title || 'Unknown title'}
</LinkButton> </LinkButton>
</CustomTooltip> </CustomTooltip>
)} )}
@ -326,11 +341,11 @@ const PlayerBar = () => {
width: '50%', width: '50%',
}} }}
> >
{playQueue.entry.length >= 1 && ( {playQueue[currentEntryList].length >= 1 && (
<CustomTooltip <CustomTooltip
text={ text={
playQueue.entry[playQueue.currentIndex]?.artist || playQueue[currentEntryList][playQueue.currentIndex]
'Unknown artist' ?.artist || 'Unknown artist'
} }
placement="topStart" placement="topStart"
> >
@ -347,14 +362,16 @@ const PlayerBar = () => {
onClick={() => { onClick={() => {
history.push( history.push(
`/library/artist/${ `/library/artist/${
playQueue.entry[playQueue.currentIndex] playQueue[currentEntryList][
?.artistId playQueue.currentIndex
]?.artistId
}` }`
); );
}} }}
> >
{playQueue.entry[playQueue.currentIndex] {playQueue[currentEntryList][
?.artist || 'Unknown artist'} playQueue.currentIndex
]?.artist || 'Unknown artist'}
</LinkButton> </LinkButton>
</span> </span>
</CustomTooltip> </CustomTooltip>
@ -479,7 +496,10 @@ const PlayerBar = () => {
defaultValue={0} defaultValue={0}
value={isDragging ? manualSeek : seek} value={isDragging ? manualSeek : seek}
tooltip={false} tooltip={false}
max={playQueue.entry[playQueue.currentIndex]?.duration || 0} max={
playQueue[currentEntryList][playQueue.currentIndex]
?.duration || 0
}
onChange={handleSeekSlider} onChange={handleSeekSlider}
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
@ -493,8 +513,8 @@ const PlayerBar = () => {
}} }}
> >
{format( {format(
playQueue.entry[playQueue.currentIndex]?.duration * 1000 || playQueue[currentEntryList][playQueue.currentIndex]
0 ?.duration * 1000 || 0
)} )}
</FlexboxGrid.Item> </FlexboxGrid.Item>
</FlexboxGrid> </FlexboxGrid>
@ -514,21 +534,23 @@ const PlayerBar = () => {
justifyContent: 'flex-end', justifyContent: 'flex-end',
}} }}
> >
{playQueue.entry.length >= 1 && ( {playQueue[currentEntryList].length >= 1 && (
<> <>
{/* Favorite Button */} {/* Favorite Button */}
<CustomTooltip text="Favorite"> <CustomTooltip text="Favorite">
<PlayerControlIcon <PlayerControlIcon
tabIndex={0} tabIndex={0}
icon={ icon={
playQueue.entry[playQueue.currentIndex].starred playQueue[currentEntryList][playQueue.currentIndex]
.starred
? 'heart' ? 'heart'
: 'heart-o' : 'heart-o'
} }
size="lg" size="lg"
fixedWidth fixedWidth
active={ active={
playQueue.entry[playQueue.currentIndex].starred playQueue[currentEntryList][playQueue.currentIndex]
.starred
? 'true' ? 'true'
: 'false' : 'false'
} }
@ -583,6 +605,7 @@ const PlayerBar = () => {
handleShuffle(); handleShuffle();
} }
}} }}
active={playQueue.shuffle ? 'true' : 'false'}
/> />
</CustomTooltip> </CustomTooltip>
{/* Display Queue Button */} {/* Display Queue Button */}

45
src/components/settings/Config.tsx

@ -15,6 +15,8 @@ import {
Message, Message,
Whisper, Whisper,
Popover, Popover,
RadioGroup,
Radio,
} from 'rsuite'; } from 'rsuite';
import { ConfigPanel } from './styled'; import { ConfigPanel } from './styled';
import { startScan, getScanStatus } from '../../api/api'; import { startScan, getScanStatus } from '../../api/api';
@ -186,6 +188,49 @@ const Config = () => {
}} }}
style={{ width: '150px' }} style={{ width: '150px' }}
/> />
<br />
<RadioGroup
name="radioList"
inline
appearance="picker"
defaultValue={String(settings.getSync('defaultRepeat'))}
onChange={(e) => settings.setSync('defaultRepeat', e)}
>
<span
style={{
padding: '8px 2px 8px 10px',
display: 'inline-block',
verticalAlign: 'middle',
}}
>
Repeat (default):{' '}
</span>
<Radio value="all">All</Radio>
<Radio value="one">One</Radio>
<Radio value="none">None</Radio>
</RadioGroup>
<RadioGroup
name="radioList"
inline
appearance="picker"
defaultValue={String(settings.getSync('defaultShuffle'))}
style={{ marginTop: '20px' }}
onChange={(e) => settings.setSync('defaultShuffle', e === 'true')}
>
<span
style={{
padding: '8px 2px 8px 10px',
display: 'inline-block',
verticalAlign: 'middle',
}}
>
Shuffle (default):{' '}
</span>
<Radio value="true">Enabled</Radio>
<Radio value="false">Disabled</Radio>
</RadioGroup>
<br />
</div> </div>
</ConfigPanel> </ConfigPanel>
<ConfigPanel header="Look & Feel" bordered> <ConfigPanel header="Look & Feel" bordered>

14
src/components/shared/setDefaultSettings.ts

@ -11,6 +11,14 @@ const setDefaultSettings = (force: boolean) => {
fs.mkdirSync(getSongCachePath(), { recursive: true }); fs.mkdirSync(getSongCachePath(), { recursive: true });
fs.mkdirSync(getImageCachePath(), { recursive: true }); fs.mkdirSync(getImageCachePath(), { recursive: true });
if (force || !settings.hasSync('defaultRepeat')) {
settings.setSync('defaultRepeat', 'all');
}
if (force || !settings.hasSync('defaultShuffle')) {
settings.setSync('defaultShuffle', false);
}
if (force || !settings.hasSync('scrollWithCurrentSong')) { if (force || !settings.hasSync('scrollWithCurrentSong')) {
settings.setSync('scrollWithCurrentSong', true); settings.setSync('scrollWithCurrentSong', true);
} }
@ -58,7 +66,7 @@ const setDefaultSettings = (force: boolean) => {
dataKey: 'combinedtitle', dataKey: 'combinedtitle',
alignment: 'left', alignment: 'left',
resizable: true, resizable: true,
width: 350, width: 450,
label: 'Title (Combined)', label: 'Title (Combined)',
}, },
{ {
@ -66,7 +74,7 @@ const setDefaultSettings = (force: boolean) => {
dataKey: 'album', dataKey: 'album',
alignment: 'left', alignment: 'left',
resizable: true, resizable: true,
width: 350, width: 450,
label: 'Album', label: 'Album',
}, },
{ {
@ -111,7 +119,7 @@ const setDefaultSettings = (force: boolean) => {
dataKey: 'combinedtitle', dataKey: 'combinedtitle',
alignment: 'left', alignment: 'left',
resizable: true, resizable: true,
width: 350, width: 450,
label: 'Title (Combined)', label: 'Title (Combined)',
}, },
{ {

203
src/redux/playQueueSlice.ts

@ -1,4 +1,5 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import settings from 'electron-settings';
import _ from 'lodash'; import _ from 'lodash';
import arrayMove from 'array-move'; import arrayMove from 'array-move';
import { areConsecutive, consecutiveRanges } from '../shared/utils'; import { areConsecutive, consecutiveRanges } from '../shared/utils';
@ -50,6 +51,7 @@ export interface PlayQueue {
shuffle: boolean; shuffle: boolean;
displayQueue: boolean; displayQueue: boolean;
entry: Entry[]; entry: Entry[];
shuffledEntry: Entry[];
} }
const initialState: PlayQueue = { const initialState: PlayQueue = {
@ -68,10 +70,11 @@ const initialState: PlayQueue = {
autoIncremented: false, autoIncremented: false,
volume: 0.5, volume: 0.5,
isLoading: false, isLoading: false,
repeat: 'none', repeat: String(settings.getSync('defaultRepeat') || 'all'),
shuffle: false, shuffle: Boolean(settings.getSync('defaultShuffle') || false),
displayQueue: false, displayQueue: false,
entry: [], entry: [],
shuffledEntry: [],
}; };
const resetPlayerDefaults = (state: PlayQueue) => { const resetPlayerDefaults = (state: PlayQueue) => {
@ -93,31 +96,105 @@ const removeItem = (array: any, index: any) => {
return [...array.slice(0, index), ...array.slice(index + 1)]; return [...array.slice(0, index), ...array.slice(index + 1)];
}; };
const entrySelect = (state: PlayQueue) =>
state.shuffle ? 'shuffledEntry' : 'entry';
const playQueueSlice = createSlice({ const playQueueSlice = createSlice({
name: 'nowPlaying', name: 'nowPlaying',
initialState, initialState,
reducers: { reducers: {
// ! Reducers need major refactoring and cleanup due to rapid
// ! development/experimentation to get things working
resetPlayQueue: (state) => { resetPlayQueue: (state) => {
const currentEntry = entrySelect(state);
resetPlayerDefaults(state); resetPlayerDefaults(state);
state.currentSongId = state.entry[0].id; state.currentSongId = state[currentEntry][0].id;
}, },
shufflePlayQueue: (state) => { shuffleInPlace: (state) => {
// Remove the current song before shuffling the array if (state.shuffledEntry.length > 0) {
// We do this so that the currently playing song doesn't state.shuffle = true;
// suddenly switch because the index has changed
const shuffledEntriesWithoutCurrent = _.shuffle(
removeItem(state.entry, state.currentIndex)
);
// Readd the current song back into its original index const shuffledEntriesWithoutCurrent = _.shuffle(
const shuffledEntries = insertItem( removeItem(state.shuffledEntry, state.currentIndex)
shuffledEntriesWithoutCurrent, );
state.currentIndex,
state.entry[state.currentIndex] // Readd the current song back into its original index
); const shuffledEntries = insertItem(
shuffledEntriesWithoutCurrent,
state.currentIndex,
state.shuffledEntry[state.currentIndex]
);
state.entry = shuffledEntries; state.shuffledEntry = shuffledEntries;
}
},
shufflePlayQueue: (state) => {
const currentEntry = entrySelect(state);
if (state.shuffledEntry.length < 1) {
// Remove the current song before shuffling the array
// We do this so that the currently playing song doesn't
// suddenly switch because the index has changed
const shuffledEntriesWithoutCurrent = _.shuffle(
removeItem(state.entry, state.currentIndex)
);
// Readd the current song back into its original index
const shuffledEntries = insertItem(
shuffledEntriesWithoutCurrent,
state.currentIndex,
state.entry[state.currentIndex]
);
state.shuffledEntry = shuffledEntries;
state.currentSongId = shuffledEntries[0].id;
} else {
const findIndex = state.entry.findIndex(
(track) => track.id === state.currentSongId
);
if (state[currentEntry].length >= 1 && state.repeat !== 'one') {
if (state.currentIndex < state[currentEntry].length - 1) {
state.currentIndex = findIndex;
state.player1.index = findIndex;
state.currentPlayer = 1;
state.isFading = false;
state.player1.volume = state.volume;
state.player1.index = state.currentIndex;
if (state.currentIndex + 1 >= state[currentEntry].length) {
state.player2.index = 0;
} else {
state.player2.index = state.currentIndex + 1;
}
} else if (state.repeat === 'all') {
state.currentIndex = findIndex;
state.currentPlayer = 1;
state.isFading = false;
state.player1.volume = state.volume;
state.player1.index = state.currentIndex;
if (state.currentIndex + 1 >= state[currentEntry].length) {
state.player2.index = 0;
} else {
state.player2.index = state.currentIndex + 1;
}
} else if (
state[currentEntry].length >= 1 &&
state.repeat === 'one'
) {
state.currentIndex = findIndex;
state.currentPlayer = 1;
state.isFading = false;
state.player1.volume = state.volume;
state.player1.index = state.currentIndex;
state.player2.index = state.currentIndex;
}
}
state.currentSongId = state.entry[findIndex].id;
}
}, },
setAutoIncremented: (state, action: PayloadAction<boolean>) => { setAutoIncremented: (state, action: PayloadAction<boolean>) => {
@ -125,17 +202,21 @@ const playQueueSlice = createSlice({
}, },
setStar: (state, action: PayloadAction<{ id: string; type: string }>) => { setStar: (state, action: PayloadAction<{ id: string; type: string }>) => {
const findIndex = state.entry.findIndex( const currentEntry = entrySelect(state);
const findIndex = state[currentEntry].findIndex(
(track) => track.id === action.payload.id (track) => track.id === action.payload.id
); );
if (action.payload.type === 'unstar') { if (action.payload.type === 'unstar') {
state.entry[findIndex].starred = undefined; state[currentEntry][findIndex].starred = undefined;
} else { } else {
state.entry[findIndex].starred = String(Date.now()); state[currentEntry][findIndex].starred = String(Date.now());
} }
}, },
toggleRepeat: (state) => { toggleRepeat: (state) => {
const currentEntry = entrySelect(state);
if (state.repeat === 'none') { if (state.repeat === 'none') {
state.repeat = 'all'; state.repeat = 'all';
} else if (state.repeat === 'all') { } else if (state.repeat === 'all') {
@ -154,11 +235,11 @@ const playQueueSlice = createSlice({
} }
} }
if (state.player1.index > state.entry.length - 1) { if (state.player1.index > state[currentEntry].length - 1) {
state.player1.index = 0; state.player1.index = 0;
} }
if (state.player2.index > state.entry.length - 1) { if (state.player2.index > state[currentEntry].length - 1) {
state.player2.index = 0; state.player2.index = 0;
} }
}, },
@ -184,8 +265,9 @@ const playQueueSlice = createSlice({
}, },
incrementCurrentIndex: (state, action: PayloadAction<string>) => { incrementCurrentIndex: (state, action: PayloadAction<string>) => {
if (state.entry.length >= 1 && state.repeat !== 'one') { const currentEntry = entrySelect(state);
if (state.currentIndex < state.entry.length - 1) { if (state[currentEntry].length >= 1 && state.repeat !== 'one') {
if (state.currentIndex < state[currentEntry].length - 1) {
// Check that current index isn't on the last track of the queue // Check that current index isn't on the last track of the queue
state.currentIndex += 1; state.currentIndex += 1;
if (action.payload === 'usingHotkey') { if (action.payload === 'usingHotkey') {
@ -193,7 +275,7 @@ const playQueueSlice = createSlice({
state.isFading = false; state.isFading = false;
state.player1.volume = state.volume; state.player1.volume = state.volume;
state.player1.index = state.currentIndex; state.player1.index = state.currentIndex;
if (state.currentIndex + 1 >= state.entry.length) { if (state.currentIndex + 1 >= state[currentEntry].length) {
state.player2.index = 0; state.player2.index = 0;
} else { } else {
state.player2.index = state.currentIndex + 1; state.player2.index = state.currentIndex + 1;
@ -207,15 +289,15 @@ const playQueueSlice = createSlice({
state.isFading = false; state.isFading = false;
state.player1.volume = state.volume; state.player1.volume = state.volume;
state.player1.index = state.currentIndex; state.player1.index = state.currentIndex;
if (state.currentIndex + 1 >= state.entry.length) { if (state.currentIndex + 1 >= state[currentEntry].length) {
state.player2.index = 0; state.player2.index = 0;
} else { } else {
state.player2.index = state.currentIndex + 1; state.player2.index = state.currentIndex + 1;
} }
} }
} }
state.currentSongId = state.entry[state.currentIndex].id; state.currentSongId = state[currentEntry][state.currentIndex].id;
} else if (state.entry.length >= 1 && state.repeat === 'one') { } else if (state[currentEntry].length >= 1 && state.repeat === 'one') {
// If repeating one, then we can just increment to the next track // If repeating one, then we can just increment to the next track
state.currentIndex += 1; state.currentIndex += 1;
if (action.payload === 'usingHotkey') { if (action.payload === 'usingHotkey') {
@ -225,23 +307,25 @@ const playQueueSlice = createSlice({
state.player1.index = state.currentIndex; state.player1.index = state.currentIndex;
state.player2.index = state.currentIndex; state.player2.index = state.currentIndex;
} }
state.currentSongId = state.entry[state.currentIndex].id; state.currentSongId = state[currentEntry][state.currentIndex].id;
} }
}, },
incrementPlayerIndex: (state, action: PayloadAction<number>) => { incrementPlayerIndex: (state, action: PayloadAction<number>) => {
const currentEntry = entrySelect(state);
// If the entry list is greater than two, we don't need to increment, // If the entry list is greater than two, we don't need to increment,
// just keep swapping playback between the tracks [0 <=> 0] or [0 <=> 1] // just keep swapping playback between the tracks [0 <=> 0] or [0 <=> 1]
// without changing the index of either player // without changing the index of either player
if (state.entry.length > 2 && state.repeat !== 'one') { if (state[currentEntry].length > 2 && state.repeat !== 'one') {
if (action.payload === 1) { if (action.payload === 1) {
if ( if (
state.player1.index + 1 === state.entry.length && state.player1.index + 1 === state[currentEntry].length &&
state.repeat === 'none' state.repeat === 'none'
) { ) {
// Reset the player on the end of the playlist if no repeat // Reset the player on the end of the playlist if no repeat
resetPlayerDefaults(state); resetPlayerDefaults(state);
} else if (state.player1.index + 2 >= state.entry.length) { } else if (state.player1.index + 2 >= state[currentEntry].length) {
// If incrementing would be greater than the total number of entries, // If incrementing would be greater than the total number of entries,
// reset it back to 0. Also check if player1 is already set to 0. // reset it back to 0. Also check if player1 is already set to 0.
if (state.player2.index === 0) { if (state.player2.index === 0) {
@ -255,12 +339,12 @@ const playQueueSlice = createSlice({
state.currentPlayer = 2; state.currentPlayer = 2;
} else { } else {
if ( if (
state.player2.index + 1 === state.entry.length && state.player2.index + 1 === state[currentEntry].length &&
state.repeat === 'none' state.repeat === 'none'
) { ) {
// Reset the player on the end of the playlist if no repeat // Reset the player on the end of the playlist if no repeat
resetPlayerDefaults(state); resetPlayerDefaults(state);
} else if (state.player2.index + 2 >= state.entry.length) { } else if (state.player2.index + 2 >= state[currentEntry].length) {
// If incrementing would be greater than the total number of entries, // If incrementing would be greater than the total number of entries,
// reset it back to 0. Also check if player1 is already set to 0. // reset it back to 0. Also check if player1 is already set to 0.
if (state.player1.index === 0) { if (state.player1.index === 0) {
@ -277,7 +361,9 @@ const playQueueSlice = createSlice({
}, },
setPlayerIndex: (state, action: PayloadAction<Entry>) => { setPlayerIndex: (state, action: PayloadAction<Entry>) => {
const findIndex = state.entry.findIndex( const currentEntry = entrySelect(state);
const findIndex = state[currentEntry].findIndex(
(track) => track.id === action.payload.id (track) => track.id === action.payload.id
); );
@ -307,7 +393,9 @@ const playQueueSlice = createSlice({
}, },
decrementCurrentIndex: (state, action: PayloadAction<string>) => { decrementCurrentIndex: (state, action: PayloadAction<string>) => {
if (state.entry.length >= 1) { const currentEntry = entrySelect(state);
if (state[currentEntry].length >= 1) {
if (state.currentIndex > 0) { if (state.currentIndex > 0) {
state.currentIndex -= 1; state.currentIndex -= 1;
if (action.payload === 'usingHotkey') { if (action.payload === 'usingHotkey') {
@ -325,13 +413,19 @@ const playQueueSlice = createSlice({
} }
} }
state.currentSongId = state.entry[state.currentIndex].id; state.currentSongId = state[currentEntry][state.currentIndex].id;
} }
}, },
fixPlayer2Index: (state) => { fixPlayer2Index: (state) => {
if (state.entry.length >= 2 && state.repeat !== 'one') { const currentEntry = entrySelect(state);
state.player2.index = state.currentIndex + 1;
if (state[currentEntry].length >= 2 && state.repeat !== 'one') {
if (state.currentIndex + 1 === state[currentEntry].length) {
state.player2.index = 0;
} else {
state.player2.index = state.currentIndex + 1;
}
} else if (state.repeat === 'one') { } else if (state.repeat === 'one') {
state.player2.index = state.currentIndex; state.player2.index = state.currentIndex;
} else { } else {
@ -340,7 +434,9 @@ const playQueueSlice = createSlice({
}, },
setCurrentIndex: (state, action: PayloadAction<Entry>) => { setCurrentIndex: (state, action: PayloadAction<Entry>) => {
const findIndex = state.entry.findIndex( const currentEntry = entrySelect(state);
const findIndex = state[currentEntry].findIndex(
(track) => track.id === action.payload.id (track) => track.id === action.payload.id
); );
@ -351,18 +447,30 @@ const playQueueSlice = createSlice({
setPlayQueue: (state, action: PayloadAction<Entry[]>) => { setPlayQueue: (state, action: PayloadAction<Entry[]>) => {
// Reset player defaults // Reset player defaults
state.entry = []; state.entry = [];
state.shuffledEntry = [];
resetPlayerDefaults(state); resetPlayerDefaults(state);
state.currentSongId = action.payload[0].id;
action.payload.map((entry: any) => state.entry.push(entry)); action.payload.map((entry: any) => state.entry.push(entry));
if (state.shuffle) {
const shuffledEntries = _.shuffle(action.payload);
shuffledEntries.map((entry: any) => state.shuffledEntry.push(entry));
state.currentSongId = shuffledEntries[0].id;
} else {
state.currentSongId = action.payload[0].id;
}
}, },
appendPlayQueue: (state, action: PayloadAction<Entry[]>) => { appendPlayQueue: (state, action: PayloadAction<Entry[]>) => {
action.payload.map((entry: any) => state.entry.push(entry)); action.payload.map((entry: any) => state.entry.push(entry));
if (state.shuffle) {
const shuffledEntries = _.shuffle(action.payload);
shuffledEntries.map((entry: any) => state.shuffledEntry.push(entry));
}
}, },
clearPlayQueue: (state) => { clearPlayQueue: (state) => {
state.entry = []; state.entry = [];
state.shuffledEntry = [];
resetPlayerDefaults(state); resetPlayerDefaults(state);
}, },
@ -379,8 +487,10 @@ const playQueueSlice = createSlice({
}, },
moveUp: (state, action: PayloadAction<number[]>) => { moveUp: (state, action: PayloadAction<number[]>) => {
const currentEntry = entrySelect(state);
// Create a copy of the queue so we can mutate it in place with arrayMove.mutate // Create a copy of the queue so we can mutate it in place with arrayMove.mutate
const tempQueue = state.entry.slice(); const tempQueue = state[currentEntry].slice();
// Ascending index is needed to move the indexes in order // Ascending index is needed to move the indexes in order
const selectedIndexesAsc = action.payload.sort((a, b) => a - b); const selectedIndexesAsc = action.payload.sort((a, b) => a - b);
@ -406,12 +516,14 @@ const playQueueSlice = createSlice({
}); });
} }
state.entry = tempQueue; state[currentEntry] = tempQueue;
}, },
moveDown: (state, action: PayloadAction<number[]>) => { moveDown: (state, action: PayloadAction<number[]>) => {
const currentEntry = entrySelect(state);
// Create a copy of the queue so we can mutate it in place with arrayMove.mutate // Create a copy of the queue so we can mutate it in place with arrayMove.mutate
const tempQueue = state.entry.slice(); const tempQueue = state[currentEntry].slice();
// Descending index is needed to move the indexes in order // Descending index is needed to move the indexes in order
const cr = consecutiveRanges(action.payload.sort((a, b) => a - b)); const cr = consecutiveRanges(action.payload.sort((a, b) => a - b));
@ -437,7 +549,7 @@ const playQueueSlice = createSlice({
}); });
} }
state.entry = tempQueue; state[currentEntry] = tempQueue;
}, },
}, },
}); });
@ -466,5 +578,6 @@ export const {
resetPlayQueue, resetPlayQueue,
setStar, setStar,
shufflePlayQueue, shufflePlayQueue,
shuffleInPlace,
} = playQueueSlice.actions; } = playQueueSlice.actions;
export default playQueueSlice.reducer; export default playQueueSlice.reducer;

Loading…
Cancel
Save