- Replace native macOS About menu with custom Svelte dialog via Tauri event - Inline SVG icon in AboutDialog (fixes broken image in webview) - Align cache directory with Tauri $APPDATA, add to asset protocol scope - Fix ffprobe 8.x keyframe parsing (skip_frame nokey, flexible parser) - Copy caption files into cache dir when outside cache path - Add -y flag to ffmpeg thumbnail extraction (prevent hang on re-extract) - Reprocess always uses preview (low-res) file, never HQ export - Prefer cached preview file for analysis even when HQ is cached - Guard upgrade toast when already on HQ Co-authored-by: Cursor <cursoragent@cursor.com>
5.2 KiB
v0.1.2 Polish — Placeholders, Auto-Upgrade, Analysis Cache
Date: 2026-09-22 14:50 ET Duration: ~20 minutes (brainstorm) + ~20 minutes (execution) Version: 0.1.1 → 0.1.2 Commits: 2f81011..925a3fc (11 commits)
Task Description
Three polish features for v0.1.2:
- Fix misleading "Generating Waveform…" / "Generating Thumbnails…" placeholder text shown in the timeline before any video is loaded
- Automatically use cached HQ video files instead of prompting user to "Upgrade" when the export file is already downloaded
- Cache video analysis results (waveforms, keyframes, thumbnails, captions) to avoid reprocessing the same video on reload
Changes Made
Feature 1: Idle-State Placeholder Text
src/lib/timeline/renderer.ts: AddedhasVideoboolean parameter todrawTimeline()andshowLabeltodrawPlaceholderLane(). When no video is loaded, timeline lanes show empty backgrounds without misleading "Generating…" text.src/lib/components/Timeline.svelte: Passessession.status === 'ready'as thehasVideoargument.
Feature 2: Auto-Use Cached HQ Video
src/lib/stores/videoSession.svelte.ts: RestructuredbeginDownload()to check export (HQ) cache before preview cache. When HQ file exists on disk, it's used directly as the active video — no preview download, no upgrade toast. The upgrade toast is preserved for mid-session HQ completions (to avoid jarring video source swaps during playback).
Feature 3: Analysis Cache System
New Rust service (src-tauri/src/services/cache_manager.rs):
- Cache stored at
~/Library/Application Support/gui-video-clipper/cache/ - Videos keyed by SHA-256 URL hash (first 16 hex chars)
- JSON manifest per video with waveform tiers, keyframe positions, thumbnail spritesheets, caption paths
- Functions:
load_manifest,save_manifest,clear_cache_entry,clear_all_cache,get_cache_stats - 5 unit tests for URL hashing and path computation
New IPC commands (src-tauri/src/commands/cache.rs):
load_cached_analysis/save_analysis_to_cache/clear_video_cache/clear_all_cache/get_cache_stats/get_thumbnail_cache_dir/get_caption_cache_dir- Path resolution: manifest stores relative paths, IPC layer resolves to absolute for frontend
Updated extract_thumbnails: Added optional output_dir parameter so thumbnails can be directed to cache directory instead of random temp dir.
TypeScript bindings (src/lib/bindings/cache.ts): Full wrapper layer for all cache IPC commands.
Frontend integration (src/lib/stores/videoSession.svelte.ts):
triggerPostDownloadProcessing()checks cache first — on hit, populates session state instantly and skips ffmpeg. On miss, extracts normally then saves to cache.- Thumbnails directed to cache dir via
getThumbnailCacheDir - New
reprocessCurrentVideo()export: clears cache entry and re-runs extraction
Preferences panel: Cache management section showing total size and entry count with "Clear All Cache" button.
StatusBar: Per-video "↻" reprocess button visible when processing is complete.
Dependency added: sha2 = "0.10" for URL hashing.
Files Changed (15 files)
New Files (3)
src-tauri/src/services/cache_manager.rssrc-tauri/src/commands/cache.rssrc/lib/bindings/cache.ts
Modified Files (12)
src/lib/timeline/renderer.tssrc/lib/components/Timeline.sveltesrc/lib/stores/videoSession.svelte.tssrc-tauri/src/services/mod.rssrc-tauri/src/commands/mod.rssrc-tauri/src/lib.rssrc-tauri/Cargo.toml+Cargo.locksrc-tauri/src/commands/media_analysis.rssrc/lib/bindings/mediaAnalysis.tssrc/lib/components/PreferencesPanel.sveltesrc/lib/components/StatusBar.svelteVERSION,package.json,tauri.conf.json
Test Results
- Rust: 56 tests pass, 0 warnings
- Frontend: svelte-check 0 errors/warnings, vitest 31/31 pass
Follow-Up Items
- HQ+toast edge case: When video loaded with cached HQ file,
triggerPostDownloadProcessingcan still setshowUpgradeToast = trueeven though playback is already HQ. Cosmetic — toast appears but does nothing harmful. Could add a guardactiveVideoPath !== exportFilePathin a future pass. now_iso8601naming: Function incache_manager.rsreturns Unix epoch seconds, not ISO 8601. Cosmetic naming issue.- Caption cache dir:
getCaptionCacheDiris wired but not used yet — captions still go to temp dir. The manifest stores whatever path captions end up at. Could wire caption output to cache dir in a future pass for full persistence. - Project files: Cache manifest structure is designed as forward-looking scaffold for future project file save/load. No UI implemented yet.
Lessons Learned
- Checking export cache before preview cache in
beginDownload()was a clean refactor that simplified the flow — early return avoids duplicate logic. - Inlining waveform/keyframe data in JSON manifests works well for the data sizes involved (~2 MB worst case). No need for binary serialization.
- The
#![allow(dead_code)]at module scope incache_manager.rswas pragmatic but broader than ideal — individual annotations would be more precise. Resolved naturally once Task 5 wired up the commands.