Skip to content

feat(video): add storyboard-based video hover previews (#429) - #455

Open
Captain-Vikram wants to merge 5 commits into
Flow-Tube:mainfrom
Captain-Vikram:feat/issue-429-hover-preview
Open

Captain-Vikram wants to merge 5 commits into
Flow-Tube:mainfrom
Captain-Vikram:feat/issue-429-hover-preview

Conversation

@Captain-Vikram

@Captain-Vikram Captain-Vikram commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Implements Phase 1 of the Video Hover Preview feature (#429) across feed, search, and channel video cards using YouTube storyboard sprite sheets.

1. Backend Storyboard Extraction & Caching (Rust)

  • Added get_video_storyboard Tauri command via InnertubeClient.
  • In-memory bounded LRU cache (capacity: 100 entries, TTL: 1 hour) protecting time-limited cryptographic URL tokens.
  • Deduplication of concurrent requests for identical video IDs via PlayerFlights.
  • Graceful empty vector fallback on unplayable videos or missing specs.

2. Frontend Architecture & Playback Isolation

  • Strict image-based preview layer: never instantiates <video> media tags or touches usePlayerStore, avoiding audio leaks, media session hijacking, or background playback interruption.
  • Global coordinator (useHoverPreviewStore) guarantees strictly one active preview across the entire application.
  • User setting toggle (video_hover_previews_enabled) in Settings > Content with localized strings.
  • 400 ms hover intent debounce; cancels immediately on mouse leave, window blur, or scrolling.

3. High-Fluidity 3-Section Storyboard (24 Frames @ 8 FPS)

  • Timeline Coverage: Preserves Flow's 3-part storyboard architecture (Opening, Middle, Later sections).
    • Opening: 8 frames (1.0s @ 8 FPS)
    • Middle: 8 frames (1.0s @ 8 FPS)
    • Later: 8 frames (1.0s @ 8 FPS)
  • Monotonic Clock Loop Sync: Uses performance.now() elapsed-time indexing (elapsed % totalDurationMs) to permanently eliminate JS timer drift under UI or render load.
  • Section Transition Crossfade: Added a subtle 120 ms crossfade (.animate-section-crossfade) on section boundaries (Opening → Middle → Later), softening scene jumps while preserving crisp 0 ms updates within each 8-frame section.
  • Preview Duration: Exactly 3.0 seconds (24 frames × 125 ms = 3,000 ms).
  • Continuous Looping Playback: Loops seamlessly across the 3 sections while hovered ((frameIdx + 1) % frames.length). Resets immediately when unhovered.
  • Micro Progress Bar: Sleek 2px accent bar (bg-primary) sweeps across the bottom edge of the thumbnail in sync with playback (with 0 ms reset transition on loop restart).

4. Edge Case Handling & Cross-Platform Safeguards

  • Isolated Single-Tile Viewport: Sized strictly to single-tile dimensions (overflow: hidden, centered horizontally). Completely fixes the 3-frame bleed bug for vertical/portrait (9:16) videos while preserving pillarboxing.
  • Double-Buffering: Back buffer + front buffer ensures the static thumbnail never glitches through during sprite sheet swaps.
  • Linux AppImage Support: Routes sheet URLs through proxiedImage(url, proxyBase) via useImageProxyStore to prevent GnuTLS certificate errors.
  • GPU Pre-Decoding: Preloads and decodes sprite sheets (img.decode()) off the main thread before revealing the preview.

Related issue

Closes #429

Change type

  • Bug fix
  • Feature
  • Refactor or maintenance
  • Documentation
  • Build, packaging, or CI

Validation

  • vitest passing (23/23 tests across hover preview suites):
    • src/lib/useHoverPreview.test.ts (8 tests)
    • src/components/video/VideoThumbnailPreview.test.ts (7 tests)
    • src/store/useHoverPreviewStore.test.ts (4 tests)
    • src/lib/seekPreview.test.ts (4 tests — seek scrubber untouched)
  • cargo test --lib storyboard passing (3/3 tests inside src-tauri)
  • pnpm build (tsc && vite build completed with 0 errors)
  • Verified card variants (grid, compact sidebar, list view) and vertical 9:16 videos.

Risk and compatibility

  • No new secrets, telemetry, or unnecessary Tauri permissions.
  • Strict playback isolation: does not mount <video> elements or interfere with background audio.
  • Tested with prefers-reduced-motion to respect accessibility settings.
  • Backward-compatible schema addition in settings defaults.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add Video Hover Previews to Video Thumbnails

1 participant