Files
navidrome/ui/src/audioplayer/queue.js
2020-04-26 19:15:52 -04:00

142 lines
3.0 KiB
JavaScript

import 'react-jinke-music-player/assets/index.css'
import subsonic from '../subsonic'
const PLAYER_ADD_TRACK = 'PLAYER_ADD_TRACK'
const PLAYER_SET_TRACK = 'PLAYER_SET_TRACK'
const PLAYER_SYNC_QUEUE = 'PLAYER_SYNC_QUEUE'
const PLAYER_SCROBBLE = 'PLAYER_SCROBBLE'
const PLAYER_PLAY_ALBUM = 'PLAYER_PLAY_ALBUM'
const mapToAudioLists = (item) => ({
id: item.id,
trackId: item.id,
name: item.title,
singer: item.artist,
cover: subsonic.url('getCoverArt', item.id, { size: 300 }),
musicSrc: subsonic.url('stream', item.id, { ts: true }),
})
const addTrack = (data) => ({
type: PLAYER_ADD_TRACK,
data,
})
const setTrack = (data) => ({
type: PLAYER_SET_TRACK,
data,
})
const shuffle = (data) => {
const ids = Object.keys(data)
for (let i = ids.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1))
;[ids[i], ids[j]] = [ids[j], ids[i]]
}
const shuffled = {}
ids.forEach((id) => (shuffled[id] = data[id]))
return shuffled
}
const shuffleAlbum = (data) => {
const shuffled = shuffle(data)
const firstId = Object.keys(shuffled)[0]
return {
type: PLAYER_PLAY_ALBUM,
id: firstId,
data: shuffled,
}
}
const playAlbum = (id, data) => ({
type: PLAYER_PLAY_ALBUM,
id,
data,
})
const syncQueue = (id, data) => ({
type: PLAYER_SYNC_QUEUE,
id,
data,
})
const scrobble = (id, submit) => ({
type: PLAYER_SCROBBLE,
id,
submit,
})
const playQueueReducer = (
previousState = { queue: [], clear: true, playing: false },
payload
) => {
let queue
const { type, data } = payload
switch (type) {
case PLAYER_ADD_TRACK:
queue = previousState.queue
queue.push(mapToAudioLists(data))
return { ...previousState, queue, clear: false }
case PLAYER_SET_TRACK:
return {
...previousState,
queue: [mapToAudioLists(data)],
clear: true,
playing: true,
current: data.id,
}
case PLAYER_SYNC_QUEUE:
const currentTrack = data.find((item) => item.id === data.id) || {}
return {
...previousState,
queue: data,
clear: false,
current: currentTrack.id,
}
case PLAYER_SCROBBLE:
const newQueue = previousState.queue.map((item) => {
return {
...item,
scrobbled:
item.scrobbled || (item.trackId === payload.id && payload.submit),
}
})
return {
...previousState,
queue: newQueue,
clear: false,
playing: true,
current: payload.id,
}
case PLAYER_PLAY_ALBUM:
queue = []
let match = false
Object.keys(data).forEach((id) => {
if (id === payload.id) {
match = true
}
if (match) {
queue.push(mapToAudioLists(data[id]))
}
})
return {
...previousState,
queue,
clear: true,
playing: true,
current: payload.id,
}
default:
return previousState
}
}
export {
addTrack,
setTrack,
playAlbum,
syncQueue,
scrobble,
shuffleAlbum,
playQueueReducer,
}