fix: use per-video caption cache dir to prevent cross-video caption bleed

Subtitle downloads were going to a shared /tmp/video-clipper/subtitles/ dir,
so find_vtt_file could return captions from a previously-loaded video. Now
uses cache_manager::caption_cache_dir (URL-hash-keyed) with pre-download
cleanup, matching the existing per-video caching pattern.

Bump to v0.2.2.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-23 06:00:43 -04:00
parent c1de18715e
commit 1b035c9af6
8 changed files with 73 additions and 11 deletions

2
src-tauri/Cargo.lock generated
View File

@@ -1281,7 +1281,7 @@ dependencies = [
[[package]]
name = "gui-video-clipper"
version = "0.2.1"
version = "0.2.2"
dependencies = [
"axum",
"dirs",

View File

@@ -1,6 +1,6 @@
[package]
name = "gui-video-clipper"
version = "0.2.1"
version = "0.2.2"
description = "A macOS GUI app for clipping online videos"
authors = ["cottongin"]
edition = "2021"

View File

@@ -1,5 +1,5 @@
use crate::models::{CookieSource, VideoMetadata};
use crate::services::{download_manager, subtitle_downloader, video_resolver};
use crate::services::{cache_manager, download_manager, subtitle_downloader, video_resolver};
use serde::Serialize;
use std::io::{BufRead, BufReader};
use tauri::ipc::Channel;
@@ -161,6 +161,9 @@ pub async fn check_cached_download(title: String, variant: String) -> Option<Str
/// Download English VTT subtitles for a video URL.
/// Returns the path to the .vtt file, or an error string.
///
/// Uses a per-video cache directory (keyed by URL hash) so subtitle files
/// from different videos never collide.
#[tauri::command]
pub async fn download_subtitles(
url: String,
@@ -168,12 +171,21 @@ pub async fn download_subtitles(
is_auto: bool,
) -> Result<String, String> {
tokio::task::spawn_blocking(move || {
let output_dir = std::env::temp_dir()
.join("video-clipper")
.join("subtitles")
let output_dir = cache_manager::caption_cache_dir(&url)
.to_string_lossy()
.to_string();
// Clean any stale .vtt files before downloading so find_vtt_file
// can only return a file belonging to *this* video.
if let Ok(entries) = std::fs::read_dir(&output_dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().and_then(|e| e.to_str()) == Some("vtt") {
let _ = std::fs::remove_file(&path);
}
}
}
eprintln!(
"[video-clipper:subtitles] downloading (auto={}) to '{}'",
is_auto, output_dir

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "GUI Video Clipper",
"version": "0.2.1",
"version": "0.2.2",
"identifier": "xyz.cottongin.gui-video-clipper",
"build": {
"beforeDevCommand": "npm run dev",