Files
gui-video-clipper/chat-summaries/2026-09-22_19-47-v020-player-mode-bugfixes-summary.md
cottongin 2e36d16bfe fix: QA round 2 — playhead guard, controls position, caption lift, Tauri fullscreen, timeline sync
- Guard drawPlayhead on session.duration > 0 in PlayerTimeline
- Move floating controls pill from bottom: 24px to 48px
- Add playerControlsVisible prop to VideoPlayer; captions slide up 160px when controls visible
- Replace web Fullscreen API with Tauri getCurrentWindow().setFullscreen() (WKWebView compat)
- Add core:window:allow-set-fullscreen and core:window:allow-is-fullscreen permissions
- Tie PlayerTimeline visibility to showPlayerControls; remove unused proximity logic

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 20:16:10 -04:00

2.9 KiB

v0.2.0 Player Mode Bug Fixes — Summary

Task Description

Fixed 8 issues found during QA of the v0.2.0 Player mode implementation. Issues ranged from a Svelte 5 reactivity bug preventing auto-hide from working, to a WKWebView fullscreen incompatibility, to keyboard shortcut mismatches.

Changes Made

3 commits (980f31a..0f2a523), 3 files modified

Commit Description
980f31a Auto-hide timer fix, status bar hidden, </> keyframe shortcuts
c00c215 adjustShuttle reads live rate with 0.25 step, fullscreen targets document.documentElement
0f2a523 QuickTime-style floating pill layout, speed selector stopPropagation, rate sync polling

Issues Fixed

  1. Floating controls layout — Redesigned from full-width bottom-pinned to centered floating pill (bottom: 24px; left: 15%; right: 15%). Reorganized: controls row (top) → seek bar (middle) → timestamps (bottom). Matches QuickTime Player layout.
  2. Controls visible when paused — Removed special paused branch; auto-hide timer always runs regardless of play state.
  3. Controls/toolbar never auto-hide — controlsHideTimer and toolbarHideTimer were $state, causing an infinite reactive loop in the $effect. Changed to plain let.
  4. Status bar visible — Wrapped <StatusBar> in {#if !isPlayerMode}.
  5. JKL skips 1.0x — Changed adjustShuttle to read live rate from video element (not stale shuttleRate) and use 0.25 step (was 0.5).
  6. Speed selector broken — Added e.stopPropagation() on toggle button to prevent immediate close from window click handler.
  7. Fullscreen broken — Changed toggleFullscreen() to target document.documentElement instead of video element (WKWebView doesn't support element-level fullscreen API).
  8. Shift+,/. keyframe shortcuts — Added < and > key cases (Shift produces these characters, not ,/.).

Lessons Learned

  • Svelte 5 $state in timer variables creates reactive loops: If an $effect reads a $state timer ID to clear it, then writes a new one, Svelte re-triggers the effect infinitely. Timer IDs used only in imperative logic should be plain let.
  • Keyboard e.key values change with Shift: Shift+, produces <, not ,. Always check the actual key value produced.
  • WKWebView fullscreen: HTMLVideoElement.requestFullscreen() doesn't work; must target document.documentElement.requestFullscreen() instead.
  • Click-outside handlers and same-click toggles: A <svelte:window onclick> handler fires on the same click event that mounted the component, causing immediate close. Use stopPropagation on the toggle button.

Test Results

  • 8 test files, 54 tests passing (7 new tests for adjustShuttle)
  • svelte-check: 0 errors, 0 warnings

Follow-up

  • Visual QA with npm run tauri dev to verify all 8 fixes work as expected