diff --git a/changes/changelog.d/86.bugfix b/changes/changelog.d/86.bugfix new file mode 100644 index 000000000..c02a1997c --- /dev/null +++ b/changes/changelog.d/86.bugfix @@ -0,0 +1 @@ +skip to next track properly on 40X errors (#86) diff --git a/front/src/components/audio/Track.vue b/front/src/components/audio/Track.vue index d8dcaff9b..e3f1c18b3 100644 --- a/front/src/components/audio/Track.vue +++ b/front/src/components/audio/Track.vue @@ -7,7 +7,11 @@ @timeupdate="updateProgress" @ended="ended" preload> - + @@ -25,6 +29,11 @@ export default { startTime: {type: Number, default: 0}, autoplay: {type: Boolean, default: false} }, + data () { + return { + sourceErrors: 0 + } + }, computed: { ...mapState({ playing: state => state.player.playing, @@ -65,11 +74,19 @@ export default { errored: function () { this.$store.dispatch('player/trackErrored') }, + sourceErrored: function () { + this.sourceErrors += 1 + if (this.sourceErrors >= this.srcs.length) { + // all sources failed + this.errored() + } + }, updateDuration: function (e) { this.$store.commit('player/duration', this.$refs.audio.duration) }, loaded: function () { this.$refs.audio.volume = this.volume + this.$store.commit('player/resetErrorCount') if (this.isCurrent) { this.$store.commit('player/duration', this.$refs.audio.duration) if (this.startTime) { diff --git a/front/src/store/player.js b/front/src/store/player.js index d1de34d38..2dc3a7402 100644 --- a/front/src/store/player.js +++ b/front/src/store/player.js @@ -5,6 +5,8 @@ import time from '@/utils/time' export default { namespaced: true, state: { + maxConsecutiveErrors: 5, + errorCount: 0, playing: false, volume: 0.5, duration: 0, @@ -25,6 +27,12 @@ export default { value = Math.max(value, 0) state.volume = value }, + incrementErrorCount (state) { + state.errorCount += 1 + }, + resetErrorCount (state) { + state.errorCount = 0 + }, duration (state, value) { state.duration = value }, @@ -89,8 +97,9 @@ export default { dispatch('queue/next', null, {root: true}) dispatch('queue/next', null, {root: true}) }, - trackErrored ({commit, dispatch}) { + trackErrored ({commit, dispatch, state}) { commit('errored', true) + commit('incrementErrorCount') dispatch('queue/next', null, {root: true}) }, updateProgress ({commit}, t) { diff --git a/front/src/store/radios.js b/front/src/store/radios.js index 922083d88..e95db5126 100644 --- a/front/src/store/radios.js +++ b/front/src/store/radios.js @@ -53,10 +53,13 @@ export default { commit('current', null) commit('running', false) }, - populateQueue ({state, dispatch}) { + populateQueue ({rootState, state, dispatch}) { if (!state.running) { return } + if (rootState.player.errorCount >= rootState.player.maxConsecutiveErrors - 1) { + return + } var params = { session: state.current.session } diff --git a/front/test/unit/specs/store/player.spec.js b/front/test/unit/specs/store/player.spec.js index f87b83cd3..b55fb010d 100644 --- a/front/test/unit/specs/store/player.spec.js +++ b/front/test/unit/specs/store/player.spec.js @@ -74,6 +74,16 @@ describe('store/player', () => { store.mutations.toggleLooping(state) expect(state.looping).to.equal(0) }) + it('increment error count', () => { + const state = { errorCount: 0 } + store.mutations.incrementErrorCount(state) + expect(state.errorCount).to.equal(1) + }) + it('reset error count', () => { + const state = { errorCount: 10 } + store.mutations.resetErrorCount(state) + expect(state.errorCount).to.equal(0) + }) }) describe('getters', () => { it('durationFormatted', () => { @@ -145,8 +155,10 @@ describe('store/player', () => { testAction({ action: store.actions.trackErrored, payload: {test: 'track'}, + params: {state: {errorCount: 0, maxConsecutiveErrors: 5}}, expectedMutations: [ - { type: 'errored', payload: true } + { type: 'errored', payload: true }, + { type: 'incrementErrorCount' } ], expectedActions: [ { type: 'queue/next', payload: null, options: {root: true} } diff --git a/front/test/unit/specs/store/radios.spec.js b/front/test/unit/specs/store/radios.spec.js index 3ff8a05ed..6de6b8dd9 100644 --- a/front/test/unit/specs/store/radios.spec.js +++ b/front/test/unit/specs/store/radios.spec.js @@ -69,7 +69,11 @@ describe('store/radios', () => { }) testAction({ action: store.actions.populateQueue, - params: {state: {running: true, current: {session: 1}}}, + params: { + state: {running: true, current: {session: 1}}, + rootState: {player: {errorCount: 0, maxConsecutiveErrors: 5}} + + }, expectedActions: [ { type: 'queue/append', payload: {track: {id: 1}}, options: {root: true} } ] @@ -82,5 +86,17 @@ describe('store/radios', () => { expectedActions: [] }, done) }) + it('populateQueue does nothing when too much errors', (done) => { + testAction({ + action: store.actions.populateQueue, + payload: {test: 'track'}, + params: { + rootState: {player: {errorCount: 5, maxConsecutiveErrors: 5}}, + state: {running: true} + }, + expectedActions: [] + }, done) + }) + }) })