87 lines
5.2 KiB
Markdown
87 lines
5.2 KiB
Markdown
|
|
# 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:
|
||
|
|
1. Fix misleading "Generating Waveform…" / "Generating Thumbnails…" placeholder text shown in the timeline before any video is loaded
|
||
|
|
2. Automatically use cached HQ video files instead of prompting user to "Upgrade" when the export file is already downloaded
|
||
|
|
3. 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`**: Added `hasVideo` boolean parameter to `drawTimeline()` and `showLabel` to `drawPlaceholderLane()`. When no video is loaded, timeline lanes show empty backgrounds without misleading "Generating…" text.
|
||
|
|
- **`src/lib/components/Timeline.svelte`**: Passes `session.status === 'ready'` as the `hasVideo` argument.
|
||
|
|
|
||
|
|
### Feature 2: Auto-Use Cached HQ Video
|
||
|
|
- **`src/lib/stores/videoSession.svelte.ts`**: Restructured `beginDownload()` 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.rs`
|
||
|
|
- `src-tauri/src/commands/cache.rs`
|
||
|
|
- `src/lib/bindings/cache.ts`
|
||
|
|
|
||
|
|
### Modified Files (12)
|
||
|
|
- `src/lib/timeline/renderer.ts`
|
||
|
|
- `src/lib/components/Timeline.svelte`
|
||
|
|
- `src/lib/stores/videoSession.svelte.ts`
|
||
|
|
- `src-tauri/src/services/mod.rs`
|
||
|
|
- `src-tauri/src/commands/mod.rs`
|
||
|
|
- `src-tauri/src/lib.rs`
|
||
|
|
- `src-tauri/Cargo.toml` + `Cargo.lock`
|
||
|
|
- `src-tauri/src/commands/media_analysis.rs`
|
||
|
|
- `src/lib/bindings/mediaAnalysis.ts`
|
||
|
|
- `src/lib/components/PreferencesPanel.svelte`
|
||
|
|
- `src/lib/components/StatusBar.svelte`
|
||
|
|
- `VERSION`, `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, `triggerPostDownloadProcessing` can still set `showUpgradeToast = true` even though playback is already HQ. Cosmetic — toast appears but does nothing harmful. Could add a guard `activeVideoPath !== exportFilePath` in a future pass.
|
||
|
|
- **`now_iso8601` naming**: Function in `cache_manager.rs` returns Unix epoch seconds, not ISO 8601. Cosmetic naming issue.
|
||
|
|
- **Caption cache dir**: `getCaptionCacheDir` is 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 in `cache_manager.rs` was pragmatic but broader than ideal — individual annotations would be more precise. Resolved naturally once Task 5 wired up the commands.
|