Files
gui-video-clipper/chat-summaries/2026-09-23_06-32-v021-polish-icons-cut-clip-summary.md
cottongin c1de18715e feat: v0.2.1 — Player controls polish, screenshot capture, quit shortcut
v0.2.0 introduced Player mode with floating controls, auto-hide UI,
PiP, fullscreen, JKL shuttle, speed selector, captions, and cut-clip.

v0.2.1 builds on that with extensive UI polish and new features:

Player Controls Polish:
- Enlarged center playback icons (Play 48, Rewind/FF 36) with filled SVGs
- Moved Cut Clip scissors into center group with hidden cut-before button
- Narrowed floating panel from 70% to 60% width
- Custom-styled volume slider matching seek bar (linear-gradient fill)
- Pure opacity fade animation (0.35s) replacing slide-in
- Tinted panel background (rgba(53,54,80,0.75)) visible on black canvas
- Drop shadow on center transport controls
- Scissors buttons dimmed via color (not opacity) with single-property transitions
- ScissorsLineDashed icon for cut-before variant
- Timestamps in single seek row (time | bar | duration) with sans-serif font
- Milliseconds shown at smaller size, revealed on hover

Screenshot Capture (S / Shift+S):
- Canvas compositing at native video resolution with optional caption burn-in
- Caption rendering matches CSS preview (font, background, outline, word highlight)
- New Rust save_screenshot command using existing filename pattern
- Output: {title} - {ms}ms-screenshot.png
- crossorigin=anonymous on video element for untainted canvas

Other:
- Q keyboard shortcut to quit via Tauri process plugin
- formatTimeParts() utility for split timestamp rendering
- Updated About dialog shortcuts list
- Version bump to 0.2.1

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-23 05:30:45 -04:00

3.8 KiB
Raw Permalink Blame History

v0.2.1 — Polish, Icons, Cut Clip & Shortcuts Reference

Task Description

Design, plan, and implement v0.2.1 of the GUI Video Clipper app. Six items: raise floating controls position, replace emoji icons with Lucide SVGs, fix blur pop-in animation, make C/P shortcuts bidirectional toggles, add "cut clip" feature from Player mode, and add keyboard shortcuts reference in a tabbed About dialog.

Changes Made

Commits (d8a6e0e → d7a2071)

  1. 646f2e5 — fix: raise controls to 64px, smooth blur via ::before pseudo-element

    • src/lib/components/PlayerControls.svelte: Changed bottom: 48px → 64px, moved background + backdrop-filter from .player-controls-panel to a ::before pseudo-element with its own opacity transition
  2. be27b1b — feat: replace emoji icons with Lucide SVG components

    • Installed @lucide/svelte dependency
    • src/lib/components/PlayerControls.svelte: Replaced 🔇/🔉/🔊, ⏪, ❚❚/▶, ⏩, CC, ⧉, ⛶/⤓ with Lucide components (VolumeX/Volume1/Volume2, Rewind, Pause/Play, FastForward, Captions, PictureInPicture2, Maximize/Minimize)
    • src/lib/components/TransportControls.svelte: Replaced ◄K/K►, ◄|/|►, ❚❚/▶, 🔇/🔉/🔊 with ChevronFirst/ChevronLast, SkipBack/SkipForward, Pause/Play, VolumeX/Volume1/Volume2
    • src/App.svelte: Replaced ⬒/⬓, ℹ, ⚙ with PanelLeft/PanelBottom, Info, Settings
  3. d964c97 — feat: C and P both toggle between Clipper/Player modes

    • src/App.svelte: Combined 'p'/'P'/'c'/'C' cases to all call toggleMode()
  4. ac7cb70 — feat: cut clip from Player mode (X/Z keys, scissors button)

    • Created src/lib/utils/clipRange.ts with computeQuickClipRange() utility
    • Created tests/lib/utils/clipRange.test.ts (8 tests)
    • src/lib/components/PlayerControls.svelte: Added scissors button with onCutClip prop
    • src/App.svelte: Added cutClip() function, X/Z keyboard shortcuts (Player mode only)
  5. 507e3b7 — feat: tabbed About dialog with keyboard shortcuts reference

    • Rewrote src/lib/components/AboutDialog.svelte with "About" / "Shortcuts" tabs
    • Created tests/lib/components/AboutDialog.test.ts (5 tests)
    • Dialog dynamically sizes: ~360px for About, ~520px for Shortcuts
  6. d7a2071 — fix: guard against zero-length clip at EOF

    • src/lib/utils/clipRange.ts: Added start >= end guard returning null
    • Added test for computeQuickClipRange(120, 120, 'at') → null

Test Results

  • 69/69 tests passing across 10 test files
  • svelte-check: 0 errors, 0 warnings

Follow-Up Items

  • Remaining non-Lucide glyphs in ClipList, VideoPlayer, TimelineContextMenu (visual consistency for v0.2.2)
  • Icon-only buttons could benefit from aria-label for screen reader accessibility
  • Shortcuts reference in AboutDialog is static — could extract to shared source of truth with keyboard handler
  • No role="tabpanel" / aria-controls wiring on About dialog tabs (full WAI-ARIA tabs pattern)

Lessons Learned

  • WebKit backdrop-filter + opacity compositing: WebKit doesn't smoothly composite backdrop-filter through an ancestor opacity transition. The fix is to isolate the blur into a ::before pseudo-element with its own opacity transition.
  • @lucide/svelte is the official package name (not lucide-svelte). Uses tree-shakable named imports: import { Play } from '@lucide/svelte'.
  • Svelte component testing text collisions: When testing components with duplicate visible text (e.g., "Play / Pause" appears twice in a shortcuts table), use getAllByText or getByRole with name filters instead of getByText.
  • Edge case: zero-length clips: When clamping clip ranges to video bounds, always guard against start >= end after clamping to prevent zero-duration clips.