Files
gui-video-clipper/chat-summaries/2026-09-23_06-32-v021-polish-icons-cut-clip-summary.md

56 lines
3.8 KiB
Markdown
Raw Permalink Normal View History

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
# 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.