Commit 7900c2d0 authored by Tony Wasserka's avatar Tony Wasserka
Browse files

Properly handle redundant MediaSession play/pause requests

MediaSession pause requests may happen even when Funkwhale is already in a
paused state. Previously FW would flip between play/pause without
consideration for the current state instead of doing nothing when
the playback state matches the requested one.

Notably, this made Funkwhale resume audio playback when entering sleep mode
on my system.
parent 38f0fd3b
......@@ -96,7 +96,7 @@
v-if="!playing"
:title="labels.play"
:aria-label="labels.play"
@click.prevent.stop="togglePlay"
@click.prevent.stop="resumePlayback"
class="control">
<i :class="['ui', 'play', {'disabled': !currentTrack}, 'icon']"></i>
</span>
......@@ -105,7 +105,7 @@
v-else
:title="labels.pause"
:aria-label="labels.pause"
@click.prevent.stop="togglePlay"
@click.prevent.stop="pausePlayback"
class="control">
<i :class="['ui', 'pause', {'disabled': !currentTrack}, 'icon']"></i>
</span>
......@@ -308,7 +308,8 @@ export default {
unmute: "player/unmute",
clean: "queue/clean",
toggleMute: "player/toggleMute",
togglePlay: "player/togglePlay",
resumePlayback: "player/resumePlayback",
pausePlayback: "player/pausePlayback",
}),
reorder: function(event) {
this.$store.commit("queue/reorder", {
......
......@@ -74,7 +74,7 @@
v-if="!playing"
:title="labels.play"
:aria-label="labels.play"
@click.prevent.stop="togglePlay"
@click.prevent.stop="resumePlayback"
class="circular button control">
<i :class="['ui', 'big', 'play', {'disabled': !currentTrack}, 'icon']"></i>
</button>
......@@ -82,7 +82,7 @@
v-else
:title="labels.pause"
:aria-label="labels.pause"
@click.prevent.stop="togglePlay"
@click.prevent.stop="pausePlayback"
class="circular button control">
<i :class="['ui', 'big', 'pause', {'disabled': !currentTrack}, 'icon']"></i>
</button>
......@@ -203,7 +203,7 @@
</div>
</div>
<GlobalEvents
@keydown.p.prevent.exact="togglePlay"
@keydown.p.prevent.exact="togglePlayback"
@keydown.esc.prevent.exact="$store.commit('ui/queueFocused', null)"
@keydown.ctrl.shift.left.prevent.exact="previous"
@keydown.ctrl.shift.right.prevent.exact="next"
......@@ -281,8 +281,8 @@ export default {
}
// Add controls for notification drawer
if ('mediaSession' in navigator) {
navigator.mediaSession.setActionHandler('play', this.togglePlay);
navigator.mediaSession.setActionHandler('pause', this.togglePlay);
navigator.mediaSession.setActionHandler('play', this.resumePlayback);
navigator.mediaSession.setActionHandler('pause', this.pausePlayback);
navigator.mediaSession.setActionHandler('seekforward', this.seekForward);
navigator.mediaSession.setActionHandler('seekbackward', this.seekBackward);
navigator.mediaSession.setActionHandler('nexttrack', this.next);
......@@ -297,7 +297,9 @@ export default {
},
methods: {
...mapActions({
togglePlay: "player/togglePlay",
resumePlayback: "player/resumePlayback",
pausePlayback: "player/pausePlayback",
togglePlayback: "player/togglePlayback",
mute: "player/mute",
unmute: "player/unmute",
clean: "queue/clean",
......
......@@ -99,7 +99,7 @@ export default {
commit('errored', false)
commit('resetErrorCount')
},
togglePlay ({commit, state, dispatch}) {
togglePlayback ({commit, state, dispatch}) {
commit('playing', !state.playing)
if (state.errored && state.errorCount < state.maxConsecutiveErrors) {
setTimeout(() => {
......@@ -109,6 +109,19 @@ export default {
}, 3000)
}
},
resumePlayback ({commit, state, dispatch}) {
commit('playing', true)
if (state.errored && state.errorCount < state.maxConsecutiveErrors) {
setTimeout(() => {
if (state.playing) {
dispatch('queue/next', null, {root: true})
}
}, 3000)
}
},
pausePlayback ({commit}) {
commit('playing', false)
},
toggleMute({commit, state}) {
if (state.volume > 0) {
commit('tempVolume', state.volume)
......
......@@ -112,24 +112,41 @@ describe('store/player', () => {
]
})
})
it('toggle play false', () => {
it('toggle playback false', () => {
testAction({
action: store.actions.togglePlay,
action: store.actions.togglePlayback,
params: {state: {playing: false}},
expectedMutations: [
{ type: 'playing', payload: true }
]
})
})
it('toggle play true', () => {
it('toggle playback true', () => {
testAction({
action: store.actions.togglePlay,
action: store.actions.togglePlayback,
params: {state: {playing: true}},
expectedMutations: [
{ type: 'playing', payload: false }
]
})
})
it('resume playback', () => {
testAction({
action: store.actions.resumePlayback,
params: {state: {}},
expectedMutations: [
{ type: 'playing', payload: true }
]
})
})
it('pause playback', () => {
testAction({
action: store.actions.pausePlayback,
expectedMutations: [
{ type: 'playing', payload: false }
]
})
})
it('trackEnded', () => {
testAction({
action: store.actions.trackEnded,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment