2022-07-04 22:52:53 +00:00
|
|
|
import type { Module } from 'vuex'
|
|
|
|
import type { RootState } from '~/store/index'
|
|
|
|
|
2018-01-11 20:35:51 +00:00
|
|
|
import axios from 'axios'
|
2022-04-23 07:37:43 +00:00
|
|
|
import time from '~/utils/time'
|
2022-04-30 18:40:57 +00:00
|
|
|
import useLogger from '~/composables/useLogger'
|
2022-05-03 00:30:43 +00:00
|
|
|
|
|
|
|
export interface State {
|
|
|
|
maxConsecutiveErrors: number
|
|
|
|
errorCount: number
|
|
|
|
playing: boolean
|
|
|
|
isLoadingAudio: boolean
|
|
|
|
volume: number
|
|
|
|
tempVolume: number
|
|
|
|
duration: number
|
|
|
|
currentTime: number
|
|
|
|
errored: boolean
|
|
|
|
bufferProgress: number
|
2022-07-20 22:44:19 +00:00
|
|
|
looping: 0 | 1 | 2 // 0 -> no, 1 -> on track, 2 -> on queue
|
2022-05-03 00:30:43 +00:00
|
|
|
}
|
2022-04-30 18:40:57 +00:00
|
|
|
|
|
|
|
const logger = useLogger()
|
2017-12-23 15:41:19 +00:00
|
|
|
|
2022-05-03 00:30:43 +00:00
|
|
|
const store: Module<State, RootState> = {
|
2017-12-23 15:41:19 +00:00
|
|
|
namespaced: true,
|
|
|
|
state: {
|
2018-02-27 20:29:07 +00:00
|
|
|
maxConsecutiveErrors: 5,
|
|
|
|
errorCount: 0,
|
2017-12-23 15:41:19 +00:00
|
|
|
playing: false,
|
2018-10-23 18:24:36 +00:00
|
|
|
isLoadingAudio: false,
|
2019-12-26 10:38:26 +00:00
|
|
|
volume: 1,
|
2018-09-06 17:38:30 +00:00
|
|
|
tempVolume: 0.5,
|
2017-12-23 15:41:19 +00:00
|
|
|
duration: 0,
|
|
|
|
currentTime: 0,
|
|
|
|
errored: false,
|
2018-10-23 18:24:36 +00:00
|
|
|
bufferProgress: 0,
|
2022-07-20 22:44:19 +00:00
|
|
|
looping: 0
|
2017-12-23 15:41:19 +00:00
|
|
|
},
|
|
|
|
mutations: {
|
2018-04-19 20:15:13 +00:00
|
|
|
reset (state) {
|
|
|
|
state.errorCount = 0
|
|
|
|
state.playing = false
|
|
|
|
},
|
2017-12-23 15:41:19 +00:00
|
|
|
volume (state, value) {
|
|
|
|
value = parseFloat(value)
|
|
|
|
value = Math.min(value, 1)
|
|
|
|
value = Math.max(value, 0)
|
|
|
|
state.volume = value
|
|
|
|
},
|
2018-09-06 17:38:30 +00:00
|
|
|
tempVolume (state, value) {
|
|
|
|
value = parseFloat(value)
|
|
|
|
value = Math.min(value, 1)
|
|
|
|
value = Math.max(value, 0)
|
|
|
|
state.tempVolume = value
|
|
|
|
},
|
2017-12-23 15:41:19 +00:00
|
|
|
incrementVolume (state, value) {
|
|
|
|
value = parseFloat(state.volume + value)
|
|
|
|
value = Math.min(value, 1)
|
|
|
|
value = Math.max(value, 0)
|
|
|
|
state.volume = value
|
|
|
|
},
|
2018-02-27 20:29:07 +00:00
|
|
|
incrementErrorCount (state) {
|
|
|
|
state.errorCount += 1
|
|
|
|
},
|
|
|
|
resetErrorCount (state) {
|
|
|
|
state.errorCount = 0
|
|
|
|
},
|
2017-12-23 15:41:19 +00:00
|
|
|
duration (state, value) {
|
|
|
|
state.duration = value
|
|
|
|
},
|
|
|
|
errored (state, value) {
|
|
|
|
state.errored = value
|
|
|
|
},
|
|
|
|
currentTime (state, value) {
|
|
|
|
state.currentTime = value
|
|
|
|
},
|
|
|
|
looping (state, value) {
|
|
|
|
state.looping = value
|
|
|
|
},
|
|
|
|
playing (state, value) {
|
|
|
|
state.playing = value
|
|
|
|
},
|
2018-10-23 18:24:36 +00:00
|
|
|
bufferProgress (state, value) {
|
|
|
|
state.bufferProgress = value
|
|
|
|
},
|
2017-12-23 15:41:19 +00:00
|
|
|
toggleLooping (state) {
|
|
|
|
if (state.looping > 1) {
|
|
|
|
state.looping = 0
|
|
|
|
} else {
|
|
|
|
state.looping += 1
|
|
|
|
}
|
2018-10-23 18:24:36 +00:00
|
|
|
},
|
|
|
|
isLoadingAudio (state, value) {
|
|
|
|
state.isLoadingAudio = value
|
2017-12-23 15:41:19 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
getters: {
|
|
|
|
durationFormatted: state => {
|
2022-05-03 00:30:43 +00:00
|
|
|
return time.parse(Math.round(state.duration))
|
2017-12-23 15:41:19 +00:00
|
|
|
},
|
|
|
|
currentTimeFormatted: state => {
|
|
|
|
return time.parse(Math.round(state.currentTime))
|
|
|
|
},
|
|
|
|
progress: state => {
|
2021-10-21 08:22:30 +00:00
|
|
|
return Math.round((state.currentTime / state.duration * 100) * 10) / 10
|
2017-12-23 15:41:19 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
actions: {
|
2021-09-25 19:44:02 +00:00
|
|
|
incrementVolume ({ commit, state }, value) {
|
2018-01-09 21:54:06 +00:00
|
|
|
commit('volume', state.volume + value)
|
2017-12-23 15:41:19 +00:00
|
|
|
},
|
2021-09-25 19:44:02 +00:00
|
|
|
stop ({ commit }) {
|
2018-10-26 13:21:35 +00:00
|
|
|
commit('errored', false)
|
|
|
|
commit('resetErrorCount')
|
2017-12-23 15:41:19 +00:00
|
|
|
},
|
2021-09-25 19:44:02 +00:00
|
|
|
togglePlayback ({ commit, state, dispatch }) {
|
2017-12-23 15:41:19 +00:00
|
|
|
commit('playing', !state.playing)
|
2018-10-26 13:21:35 +00:00
|
|
|
if (state.errored && state.errorCount < state.maxConsecutiveErrors) {
|
|
|
|
setTimeout(() => {
|
|
|
|
if (state.playing) {
|
2021-09-25 19:44:02 +00:00
|
|
|
dispatch('queue/next', null, { root: true })
|
2018-10-26 13:21:35 +00:00
|
|
|
}
|
|
|
|
}, 3000)
|
|
|
|
}
|
2017-12-23 15:41:19 +00:00
|
|
|
},
|
2022-07-20 22:44:19 +00:00
|
|
|
async resumePlayback ({ commit, state, dispatch }) {
|
2021-03-24 14:46:53 +00:00
|
|
|
commit('playing', true)
|
|
|
|
if (state.errored && state.errorCount < state.maxConsecutiveErrors) {
|
2022-07-20 22:44:19 +00:00
|
|
|
await new Promise(resolve => setTimeout(resolve, 3000))
|
|
|
|
if (state.playing) {
|
|
|
|
return dispatch('queue/next', null, { root: true })
|
|
|
|
}
|
2021-03-24 14:46:53 +00:00
|
|
|
}
|
|
|
|
},
|
2021-09-25 19:44:02 +00:00
|
|
|
pausePlayback ({ commit }) {
|
2021-03-24 14:46:53 +00:00
|
|
|
commit('playing', false)
|
|
|
|
},
|
2021-09-25 19:44:02 +00:00
|
|
|
toggleMute ({ commit, state }) {
|
2019-06-25 15:48:01 +00:00
|
|
|
if (state.volume > 0) {
|
|
|
|
commit('tempVolume', state.volume)
|
|
|
|
commit('volume', 0)
|
2021-09-25 19:44:02 +00:00
|
|
|
} else {
|
2019-06-25 15:48:01 +00:00
|
|
|
commit('volume', state.tempVolume)
|
|
|
|
}
|
|
|
|
},
|
2022-05-03 00:30:43 +00:00
|
|
|
trackListened ({ rootState }, track) {
|
2018-05-06 09:18:28 +00:00
|
|
|
if (!rootState.auth.authenticated) {
|
|
|
|
return
|
|
|
|
}
|
2022-07-19 08:09:19 +00:00
|
|
|
|
|
|
|
return axios.post('history/listenings/', { track: track.id }).catch((error) => {
|
|
|
|
logger.error('Could not record track in history', error)
|
2017-12-23 15:41:19 +00:00
|
|
|
})
|
|
|
|
},
|
2022-05-03 00:30:43 +00:00
|
|
|
trackEnded ({ commit, dispatch, rootState }) {
|
2021-09-25 19:44:02 +00:00
|
|
|
const queueState = rootState.queue
|
2018-02-27 18:39:26 +00:00
|
|
|
if (queueState.currentIndex === queueState.tracks.length - 1) {
|
|
|
|
// we've reached last track of queue, trigger a reload
|
|
|
|
// from radio if any
|
2021-09-25 19:44:02 +00:00
|
|
|
dispatch('radios/populateQueue', null, { root: true })
|
2018-02-27 18:39:26 +00:00
|
|
|
}
|
2021-09-25 19:44:02 +00:00
|
|
|
dispatch('queue/next', null, { root: true })
|
2021-04-03 11:15:23 +00:00
|
|
|
if (queueState.ended) {
|
|
|
|
// Reset playback
|
|
|
|
commit('playing', false)
|
|
|
|
dispatch('updateProgress', 0)
|
|
|
|
}
|
2017-12-23 15:41:19 +00:00
|
|
|
},
|
2021-09-25 19:44:02 +00:00
|
|
|
trackErrored ({ commit, dispatch, state }) {
|
2017-12-23 15:41:19 +00:00
|
|
|
commit('errored', true)
|
2018-02-27 20:29:07 +00:00
|
|
|
commit('incrementErrorCount')
|
2018-10-26 13:21:35 +00:00
|
|
|
if (state.errorCount < state.maxConsecutiveErrors) {
|
|
|
|
setTimeout(() => {
|
|
|
|
if (state.playing) {
|
2021-09-25 19:44:02 +00:00
|
|
|
dispatch('queue/next', null, { root: true })
|
2018-10-26 13:21:35 +00:00
|
|
|
}
|
|
|
|
}, 3000)
|
|
|
|
}
|
2017-12-23 15:41:19 +00:00
|
|
|
},
|
2021-09-25 19:44:02 +00:00
|
|
|
updateProgress ({ commit }, t) {
|
2017-12-23 15:41:19 +00:00
|
|
|
commit('currentTime', t)
|
2018-09-06 17:38:30 +00:00
|
|
|
},
|
2021-09-25 19:44:02 +00:00
|
|
|
mute ({ commit, state }) {
|
2018-09-06 17:38:30 +00:00
|
|
|
commit('tempVolume', state.volume)
|
|
|
|
commit('volume', 0)
|
|
|
|
},
|
2021-09-25 19:44:02 +00:00
|
|
|
unmute ({ commit, state }) {
|
2018-09-06 17:38:30 +00:00
|
|
|
commit('volume', state.tempVolume)
|
2017-12-23 15:41:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-05-03 00:30:43 +00:00
|
|
|
|
|
|
|
export default store
|