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.
environments/review-front-1108-r6wo61/deployments/6780
Tony Wasserka 2021-03-24 15:46:53 +01:00
rodzic 38f0fd3b60
commit 7900c2d065
4 zmienionych plików z 47 dodań i 14 usunięć

Wyświetl plik

@ -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", {

Wyświetl plik

@ -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",

Wyświetl plik

@ -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)

Wyświetl plik

@ -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,