diff --git a/engines.lock.json b/engines.lock.json index 1b983c3..feccda6 100644 --- a/engines.lock.json +++ b/engines.lock.json @@ -16,10 +16,10 @@ "sha256": "111b2f5ed760f1e1a2ec06117c4e8094fcde336ba16122dda1c5e7209bf1862d" }, "ffmpeg": { - "version": "8.1.1", + "version": "N-125385-ge2e889d9da", "source": "https://ffmpeg.org/", "build": "GPLv3 build identified by binary as https://www.martin-riedl.de", - "sha256": "ef4fe121377039053b0d7bed4a9aa46e7912918f5ba6424a1dd155f4eed625b0" + "sha256": "3027bd75166a596c31a271ce9ae14b5441492b9557011993c0bf873b5a7c6a09" }, "deno": { "version": "2.9.1", diff --git a/package-lock.json b/package-lock.json index 4b67a47..ce8192d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@tauri-apps/plugin-log": "^2.8.0", "@tauri-apps/plugin-notification": "^2.3.3", "@tauri-apps/plugin-opener": "^2", - "lucide-react": "^1.21.0", + "lucide-react": "^1.23.0", "react": "^19.1.0", "react-dom": "^19.1.0", "zustand": "^5.0.14" @@ -32,7 +32,7 @@ "postcss": "^8.5.15", "tailwindcss": "^4.3.1", "typescript": "^6.0.3", - "vite": "^8.1.2", + "vite": "^8.1.3", "vitest": "^4.1.9" }, "engines": { @@ -1650,9 +1650,9 @@ } }, "node_modules/lucide-react": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.22.0.tgz", - "integrity": "sha512-c9o3l0PiNcgOQDW4F31BEYHudE7kgxVt3o30qMl36ZPwTxXlGB4QnLilhERvVM4uh/pl5MDyY1/gzZSYcHDtBg==", + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.23.0.tgz", + "integrity": "sha512-38BpJcD0JhFosxHApP/BYsBetLpQFRoTRzEzstM/XCc3jsAG7wqaY1lgVwxiUe3xqYE+lNxo2PkCmYwXWrwwIw==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1974,9 +1974,9 @@ } }, "node_modules/vite": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.2.tgz", - "integrity": "sha512-6YYPbRXTxx6bRXmOn7XdnQAy5DQNHhDgtjhDHI13oe4pY93kkcdGJWxpGwOm++/Wh0QpQhDrpIoVMrmrsI5AGQ==", + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.3.tgz", + "integrity": "sha512-Ds+gBRbj0lwRO2Y5hwnUBdxSwlAve9LeRyU4sNnAr0ewW0gWF0n5bgXgUzbgZ49MV9BVUAQUFYVcDUcilUExMA==", "license": "MIT", "dependencies": { "lightningcss": "^1.32.0", diff --git a/package.json b/package.json index 1dcc9a3..caf0e65 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@tauri-apps/plugin-log": "^2.8.0", "@tauri-apps/plugin-notification": "^2.3.3", "@tauri-apps/plugin-opener": "^2", - "lucide-react": "^1.21.0", + "lucide-react": "^1.23.0", "react": "^19.1.0", "react-dom": "^19.1.0", "zustand": "^5.0.14" @@ -59,7 +59,7 @@ "postcss": "^8.5.15", "tailwindcss": "^4.3.1", "typescript": "^6.0.3", - "vite": "^8.1.2", + "vite": "^8.1.3", "vitest": "^4.1.9" } } diff --git a/src-tauri/binaries/ffmpeg-aarch64-apple-darwin b/src-tauri/binaries/ffmpeg-aarch64-apple-darwin index 88ecf77..956150c 100755 Binary files a/src-tauri/binaries/ffmpeg-aarch64-apple-darwin and b/src-tauri/binaries/ffmpeg-aarch64-apple-darwin differ diff --git a/src-tauri/src/ipc.rs b/src-tauri/src/ipc.rs index a8b8549..bfed906 100644 --- a/src-tauri/src/ipc.rs +++ b/src-tauri/src/ipc.rs @@ -215,15 +215,13 @@ pub enum ProxyMode { } #[derive(Clone, Debug, Serialize, Deserialize, TS)] -#[serde(rename_all = "lowercase")] #[ts(export, export_to = "../../src/bindings/")] -pub enum MediaCookieSource { - None, - Safari, - Chrome, - Firefox, - Edge, - Brave, +pub struct MediaCookieSource(#[ts(type = "string")] pub String); + +impl Default for MediaCookieSource { + fn default() -> Self { + Self("none".to_string()) + } } #[derive(Clone, Debug, Serialize, Deserialize, TS)] @@ -275,7 +273,7 @@ pub struct PersistedSettings { pub prevents_sleep_while_downloading: bool, pub media_cookie_source: MediaCookieSource, pub site_logins: Vec, - /// The HMAC shared secret for the browser extension. It is persisted in the + /// HMAC shared secret for the browser extension. It is persisted in the /// settings database so that startup never needs to touch the OS keychain. /// The keychain is still used as defence-in-depth — grant_keychain_access /// writes the token there — but the DB copy is the primary read path, diff --git a/src-tauri/src/settings.rs b/src-tauri/src/settings.rs index 8b405aa..b73c4b6 100644 --- a/src-tauri/src/settings.rs +++ b/src-tauri/src/settings.rs @@ -6,7 +6,9 @@ use serde_json::{Map, Value}; use std::collections::HashMap; use tauri::{AppHandle, Manager}; -pub fn load_settings(app_handle: &AppHandle) -> Result { +pub fn load_settings( + app_handle: &AppHandle, +) -> Result { let database = app_handle.state::(); let connection = database.lock()?; let stored = crate::db::load_settings(&connection)? @@ -296,7 +298,7 @@ fn default_settings() -> PersistedSettings { custom_user_agent: String::new(), ask_where_to_save_each_file: false, prevents_sleep_while_downloading: true, - media_cookie_source: MediaCookieSource::None, + media_cookie_source: MediaCookieSource::default(), site_logins: Vec::new(), extension_pairing_token: String::new(), auto_check_updates: true, diff --git a/src/bindings/MediaCookieSource.ts b/src/bindings/MediaCookieSource.ts index 916596f..f4d663d 100644 --- a/src/bindings/MediaCookieSource.ts +++ b/src/bindings/MediaCookieSource.ts @@ -1,3 +1,3 @@ // This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -export type MediaCookieSource = "none" | "safari" | "chrome" | "firefox" | "edge" | "brave"; +export type MediaCookieSource = string; diff --git a/src/bindings/PersistedSettings.ts b/src/bindings/PersistedSettings.ts index c05dad7..8f1f9f4 100644 --- a/src/bindings/PersistedSettings.ts +++ b/src/bindings/PersistedSettings.ts @@ -10,7 +10,7 @@ import type { Theme } from "./Theme"; export type PersistedSettings = { theme: Theme, baseDownloadFolder: string, categorySubfolders: { [key in string]: string }, categoryDirectoryOverrides: { [key in string]: string }, approvedDownloadRoots: Array, maxConcurrentDownloads: number, globalSpeedLimit: string, isSidebarVisible: boolean, activeSettingsTab: SettingsTab, scheduler: SchedulerSettings, schedulerRunning: boolean, schedulerActiveDownloadIds: Array, schedulerLastStartKey: string, schedulerLastStopKey: string, lastCustomSpeedLimitKiB: number, perServerConnections: number, maxAutomaticRetries: number, showNotifications: boolean, playCompletionSound: boolean, appFontSize: AppFontSize, listRowDensity: ListRowDensity, showDockBadge: boolean, showMenuBarIcon: boolean, proxyMode: ProxyMode, proxyHost: string, proxyPort: number, customUserAgent: string, askWhereToSaveEachFile: boolean, preventsSleepWhileDownloading: boolean, mediaCookieSource: MediaCookieSource, siteLogins: Array, /** - * The HMAC shared secret for the browser extension. It is persisted in the + * HMAC shared secret for the browser extension. It is persisted in the * settings database so that startup never needs to touch the OS keychain. * The keychain is still used as defence-in-depth — grant_keychain_access * writes the token there — but the DB copy is the primary read path, diff --git a/src/components/SettingsView.tsx b/src/components/SettingsView.tsx index 6f95ada..afcb2f4 100644 --- a/src/components/SettingsView.tsx +++ b/src/components/SettingsView.tsx @@ -47,6 +47,24 @@ const engineChecks = [ { kind: 'deno', name: 'Deno', command: 'get_deno_engine_status' }, ] as const; +const browserCookieSourceOptions = [ + { value: 'none', label: 'None' }, + { value: 'safari', label: 'Safari' }, + { value: 'chrome', label: 'Chrome' }, + { value: 'chromium', label: 'Chromium' }, + { value: 'firefox', label: 'Firefox' }, + { value: 'edge', label: 'Edge' }, + { value: 'brave', label: 'Brave' }, + { value: 'opera', label: 'Opera' }, + { value: 'vivaldi', label: 'Vivaldi' }, + { value: 'whale', label: 'Whale' }, +] as const; + +const normalizeBrowserCookieSource = (source: string) => { + const trimmed = source.trim(); + return trimmed.length > 0 ? trimmed : 'none'; +}; + type EngineCheck = typeof engineChecks[number]; const engineStatusCache = new Map(); @@ -1103,24 +1121,33 @@ className="app-button px-3 py-1.5 text-[12px] flex items-center gap-1.5 disabled ))} -
- +
+ +
+ settings.setMediaCookieSource(normalizeBrowserCookieSource(e.target.value))} + placeholder="firefox:/path/to/profile or chrome:Profile 1" + className="app-control w-full px-3 py-1.5 bg-surface-overlay/50 border-border-color/50 focus:border-accent-color focus:bg-surface-overlay text-[13px]" + aria-label="Custom yt-dlp browser cookie source" + />
-

yt-dlp reads browser cookies to bypass video download limits or access restricted media. Firelink does not save browser cookies.

+
+

yt-dlp reads browser cookies to bypass video download limits or access restricted media. Firelink does not save browser cookies.

);