Skip to content

Commit 5bf9d70

Browse files
fix(client): add anti-echo guard for video syncing (#166)
Added an anti-echo guard to prevent play/pause event spams. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches client-side video play/pause state synchronization; a small logic change could still cause playback state to get stuck or miss updates on some browsers (notably Safari). > > **Overview** > Prevents play/pause “echo” loops between the Vuex `playing` watcher and the `<video>` element by introducing an `isVideoSyncing` guard. > > When native `playing`/`pause` events fire, the component temporarily marks itself as syncing and defers clearing the flag to the next tick, avoiding Safari timing races where events can precede `video.paused` updates. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit ee912e3. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: Rafael <raf@kernel.sh>
1 parent 2c4de09 commit 5bf9d70

1 file changed

Lines changed: 9 additions & 0 deletions

File tree

  • images/chromium-headful/client/src/components

images/chromium-headful/client/src/components/video.vue

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@
260260
private focused = false
261261
private fullscreen = false
262262
private mutedOverlay = true
263+
private isVideoSyncing = false
263264
264265
get admin() {
265266
return this.$accessor.user.admin
@@ -431,6 +432,10 @@
431432
432433
@Watch('playing')
433434
async onPlayingChanged(playing: boolean) {
435+
// In Safari, native events can fire slightly before the `video.paused` property flips.
436+
// This anti-echo guard prevents the watcher from fighting the video element's own state changes.
437+
if (this.isVideoSyncing) return;
438+
434439
if (this._video && this._video.paused && playing) {
435440
// if autoplay is disabled, play() will throw an error
436441
// and we need to properly save the state otherwise we
@@ -511,11 +516,15 @@
511516
})
512517
513518
this._video.addEventListener('playing', () => {
519+
this.isVideoSyncing = true
514520
this.$accessor.video.play()
521+
this.$nextTick(() => { this.isVideoSyncing = false })
515522
})
516523
517524
this._video.addEventListener('pause', () => {
525+
this.isVideoSyncing = true
518526
this.$accessor.video.pause()
527+
this.$nextTick(() => { this.isVideoSyncing = false })
519528
})
520529
521530
/* Initialize Guacamole Keyboard */

0 commit comments

Comments
 (0)