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>
3.8 KiB
3.8 KiB
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)
-
646f2e5—fix: raise controls to 64px, smooth blur via ::before pseudo-elementsrc/lib/components/PlayerControls.svelte: Changedbottom: 48px→64px, movedbackground+backdrop-filterfrom.player-controls-panelto a::beforepseudo-element with its own opacity transition
-
be27b1b—feat: replace emoji icons with Lucide SVG components- Installed
@lucide/sveltedependency 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/Volume2src/App.svelte: Replaced ⬒/⬓, ℹ, ⚙ with PanelLeft/PanelBottom, Info, Settings
- Installed
-
d964c97—feat: C and P both toggle between Clipper/Player modessrc/App.svelte: Combined'p'/'P'/'c'/'C'cases to all calltoggleMode()
-
ac7cb70—feat: cut clip from Player mode (X/Z keys, scissors button)- Created
src/lib/utils/clipRange.tswithcomputeQuickClipRange()utility - Created
tests/lib/utils/clipRange.test.ts(8 tests) src/lib/components/PlayerControls.svelte: Added scissors button withonCutClippropsrc/App.svelte: AddedcutClip()function,X/Zkeyboard shortcuts (Player mode only)
- Created
-
507e3b7—feat: tabbed About dialog with keyboard shortcuts reference- Rewrote
src/lib/components/AboutDialog.sveltewith "About" / "Shortcuts" tabs - Created
tests/lib/components/AboutDialog.test.ts(5 tests) - Dialog dynamically sizes: ~360px for About, ~520px for Shortcuts
- Rewrote
-
d7a2071—fix: guard against zero-length clip at EOFsrc/lib/utils/clipRange.ts: Addedstart >= endguard returningnull- 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-labelfor screen reader accessibility - Shortcuts reference in AboutDialog is static — could extract to shared source of truth with keyboard handler
- No
role="tabpanel"/aria-controlswiring on About dialog tabs (full WAI-ARIA tabs pattern)
Lessons Learned
- WebKit
backdrop-filter+opacitycompositing: WebKit doesn't smoothly compositebackdrop-filterthrough an ancestoropacitytransition. The fix is to isolate the blur into a::beforepseudo-element with its own opacity transition. @lucide/svelteis the official package name (notlucide-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
getAllByTextorgetByRolewith name filters instead ofgetByText. - Edge case: zero-length clips: When clamping clip ranges to video bounds, always guard against
start >= endafter clamping to prevent zero-duration clips.