use serde::{Deserialize, Serialize}; use std::sync::Mutex; use tauri::{AppHandle, Emitter, Manager}; use uuid::Uuid; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DownloadRecord { pub id: String, pub url: String, pub filename: String, pub status: String, pub saved_to_library: bool, pub created_at: i64, } #[derive(Default)] pub struct DownloadState { pub records: Mutex>, } #[tauri::command] pub fn downloads_list(app: AppHandle) -> Result, String> { let state = app.state::(); let records = state.records.lock().map_err(|_| "download lock poisoned")?; Ok(records.clone()) } #[tauri::command] pub fn downloads_clear_completed(app: AppHandle) -> Result<(), String> { let state = app.state::(); let mut records = state.records.lock().map_err(|_| "download lock poisoned")?; records.retain(|r| r.status == "active"); Ok(()) } #[tauri::command] pub async fn download_to_library(app: AppHandle, url: String) -> Result { let filename = url.split('/').last().unwrap_or("download").to_string(); let record = DownloadRecord { id: Uuid::new_v4().to_string(), url: url.clone(), filename: filename.clone(), status: "active".to_string(), saved_to_library: true, created_at: chrono::Utc::now().timestamp(), }; { let state = app.state::(); let mut records = state.records.lock().map_err(|_| "download lock poisoned")?; records.push(record.clone()); } let _ = app.emit("downloads://update", &record); let item = crate::library::library_add_item(app.clone(), url, Some(record.url.clone()), Some(filename)).await?; { let state = app.state::(); let mut records = state.records.lock().map_err(|_| "download lock poisoned")?; if let Some(r) = records.iter_mut().find(|r| r.id == record.id) { r.status = "complete".to_string(); } } let _ = app.emit("downloads://complete", &record.id); Ok(item) } #[tauri::command] pub fn web_clip_page(url: String, title: String) -> DownloadRecord { DownloadRecord { id: Uuid::new_v4().to_string(), url, filename: title, status: "clipped".to_string(), saved_to_library: false, created_at: chrono::Utc::now().timestamp(), } }