Skip to content
This repository has been archived by the owner on Oct 4, 2023. It is now read-only.

Commit

Permalink
Fix shuffle and repeat tracks (#65)
Browse files Browse the repository at this point in the history
* Fix shuffle tracks

* Undo comment of log
  • Loading branch information
jowlee authored Apr 10, 2021
1 parent 5e6a804 commit 33800f8
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .eslintcache

Large diffs are not rendered by default.

41 changes: 33 additions & 8 deletions src/components/audio/Audio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@ import {
getSeek,
getIndex,
getQueueLength,
getIsRepeatSingle
getRepeatMode,
getIsShuffleOn,
getShuffleIndex
} from '../../store/audio/selectors'

import { MessageType } from '../../message'
import { logListen } from './listens'
import { postMessage } from '../../utils/postMessage'
import { MessagePostingWebView } from '../../types/MessagePostingWebView'
import { RepeatMode } from '../../store/audio/reducer'

declare global {
interface Global {
Expand Down Expand Up @@ -70,8 +73,10 @@ const Audio = ({
pause,
next,
previous,
repeat,
reset,
repeatMode,
isShuffleOn,
shuffleIndex,
googleCastStatus,
setCastPlayPosition
}: Props) => {
Expand Down Expand Up @@ -225,12 +230,30 @@ const Audio = ({
// Next and Previous handler
useEffect(() => {
if (playing || hasPlayedOnce.current) {
const isPreviousEnabled = index > 0
let isPreviousEnabled
let isNextEnabled
if (repeatMode === RepeatMode.ALL) {
isPreviousEnabled = true
isNextEnabled = true
} else if (isShuffleOn) {
isPreviousEnabled = shuffleIndex > 0
isNextEnabled = shuffleIndex < queueLength - 1
} else {
isPreviousEnabled = index > 0
isNextEnabled = index < queueLength - 1
}
MusicControl.enableControl('previousTrack', isPreviousEnabled)
const isNextEnabled = index < queueLength - 1
MusicControl.enableControl('nextTrack', isNextEnabled)
}
}, [playing, hasPlayedOnce, index, queueLength])
}, [
playing,
hasPlayedOnce,
index,
queueLength,
repeatMode,
isShuffleOn,
shuffleIndex
])

// Seek handler
useEffect(() => {
Expand Down Expand Up @@ -345,7 +368,7 @@ const Audio = ({
setDuration(payload.duration)
}}
onProgress={onProgress}
repeat={repeat}
repeat={repeatMode === RepeatMode.SINGLE}
paused={!playing}
// onBuffer={this.onBuffer}
/>
Expand All @@ -360,8 +383,10 @@ const mapStateToProps = (state: AppState) => ({
queueLength: getQueueLength(state),
playing: getPlaying(state),
seek: getSeek(state),
repeat: getIsRepeatSingle(state),
googleCastStatus: getGoogleCastStatus(state)
repeatMode: getRepeatMode(state),
googleCastStatus: getGoogleCastStatus(state),
isShuffleOn: getIsShuffleOn(state),
shuffleIndex: getShuffleIndex(state)
})

const mapDispatchToProps = (dispatch: Dispatch) => ({
Expand Down
3 changes: 3 additions & 0 deletions src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export enum MessageType {
SET_INFO = 'set-info',
PERSIST_QUEUE = 'persist-queue',
SET_REPEAT_MODE = 'set-repeat-mode',
SHUFFLE = 'shuffle',

// Links
OPEN_LINK = 'open-link',
Expand Down Expand Up @@ -144,6 +145,8 @@ export const handleMessage = async (
return dispatch(audioActions.persistQueue(message))
case MessageType.SET_REPEAT_MODE:
return dispatch(audioActions.repeat(message))
case MessageType.SHUFFLE:
return dispatch(audioActions.shuffle(message))
case MessageType.OPEN_LINK:
Linking.openURL(message.url)
break
Expand Down
11 changes: 11 additions & 0 deletions src/store/audio/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ type RepeatAction = {
message: Message
}

type ShuffleAction = {
type: typeof SHUFFLE
message: Message
}

type ResetAction = {
type: typeof RESET
}
Expand All @@ -60,6 +65,7 @@ export type AudioActions =
| SetInfoAction
| PersistQueueAction
| RepeatAction
| ShuffleAction
| ResetAction

export const play = (): PlayAction => ({
Expand Down Expand Up @@ -98,6 +104,11 @@ export const repeat = (message: Message): RepeatAction => ({
message
})

export const shuffle = (message: Message): ShuffleAction => ({
type: SHUFFLE,
message
})

export const reset = (): ResetAction => ({
type: RESET
})
63 changes: 53 additions & 10 deletions src/store/audio/reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
SEEK,
PERSIST_QUEUE,
REPEAT,
SHUFFLE,
RESET
} from './actions'
import { track, make } from '../../utils/analytics'
Expand Down Expand Up @@ -39,14 +40,20 @@ export type AudioState = {
playing: boolean
seek: number | null
repeatMode: RepeatMode
shuffle: boolean
shuffleIndex: number
shuffleOrder: number[]
}

const initialState: AudioState = {
index: -1,
queue: [],
playing: false,
seek: null,
repeatMode: RepeatMode.OFF
repeatMode: RepeatMode.OFF,
shuffle: false,
shuffleIndex: -1,
shuffleOrder: []
}

const reducer = (
Expand All @@ -66,8 +73,21 @@ const reducer = (
}
case NEXT: {
let newIndex
let newShuffleIndex = state.shuffleIndex
let playing = true
if (state.repeatMode === RepeatMode.SINGLE) {
newIndex = state.index
} else if (state.shuffle) {
newShuffleIndex =
state.shuffleIndex < state.queue.length - 1
? state.shuffleIndex + 1
: state.repeatMode === RepeatMode.ALL
? 0
: -1
newIndex =
newShuffleIndex === -1
? newShuffleIndex
: state.shuffleOrder[newShuffleIndex]
} else {
newIndex =
state.index < state.queue.length - 1
Expand All @@ -76,7 +96,7 @@ const reducer = (
? 0
: -1
}
const playing = newIndex !== -1
playing = newIndex !== -1

// Side-Effect (yes, this shouldn't be in a reducer, but
// maybe not worth including sagas/thunks)
Expand All @@ -89,16 +109,16 @@ const reducer = (
})
)
}

return {
...state,
index: newIndex,
shuffleIndex: newShuffleIndex,
playing
}
}
case PREVIOUS: {
const newIndex = state.index > 0 ? state.index - 1 : -1

let newIndex = state.index > 0 ? state.index - 1 : -1
let newShuffleIndex = state.shuffleIndex
// Side-Effect (yes, this shouldn't be in a reducer, but
// maybe not worth including sagas/thunks)
if (state.playing) {
Expand All @@ -110,35 +130,58 @@ const reducer = (
})
)
}
if (state.shuffle) {
newShuffleIndex =
state.shuffleIndex - 1 > 0
? state.shuffleIndex - 1
: state.repeatMode === RepeatMode.ALL
? state.shuffleOrder.length - 1
: -1
newIndex = state.shuffleOrder[newShuffleIndex]
}

return {
...state,
index: newIndex
index: newIndex,
shuffleIndex: newShuffleIndex
}
}
case SEEK:
return {
...state,
seek: action.message.seconds
}
case REPEAT:
return {
...state,
repeatMode: action.message.repeatMode
}
case PERSIST_QUEUE:
return {
...state,
queue: action.message.tracks,
index: action.message.index
index: action.message.index,
shuffle: action.message.shuffle,
shuffleIndex: action.message.shuffleIndex,
shuffleOrder: action.message.shuffleOrder
}
case REPEAT:
case SHUFFLE:
return {
...state,
repeatMode: action.message.repeatMode
shuffle: action.message.shuffle,
shuffleIndex: action.message.shuffleIndex,
shuffleOrder: action.message.shuffleOrder
}
case RESET:
return {
index: -1,
queue: [],
playing: false,
seek: null,
repeatMode: RepeatMode.OFF
repeatMode: RepeatMode.OFF,
shuffle: false,
shuffleIndex: -1,
shuffleOrder: []
}
default:
return state
Expand Down
4 changes: 4 additions & 0 deletions src/store/audio/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ export const getQueueLength = (state: AppState) =>
export const getSeek = (state: AppState) => getBaseState(state).seek
export const getIsRepeatSingle = (state: AppState) =>
getBaseState(state).repeatMode === RepeatMode.SINGLE
export const getRepeatMode = (state: AppState) => getBaseState(state).repeatMode
export const getIsShuffleOn = (state: AppState) => getBaseState(state).shuffle
export const getShuffleIndex = (state: AppState) =>
getBaseState(state).shuffleIndex

0 comments on commit 33800f8

Please sign in to comment.