use serde::{Deserialize, Serialize}; use tauri::{AppHandle, Manager}; use uuid::Uuid; use crate::state::AppState; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct SessionSnapshot { pub id: String, pub name: String, pub tabs: Vec, pub saved_at: i64, pub is_auto: bool, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SessionTab { pub url: String, pub title: String, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] struct SessionStore { sessions: Vec, } #[tauri::command] pub fn sessions_save(app: AppHandle, name: String) -> Result { let tabs = { let state = app.state::(); let tm = state.tabs.lock().map_err(|_| "lock")?; tm.order.iter().filter_map(|id| tm.tabs.get(id)).map(|t| SessionTab { url: t.url.clone(), title: t.title.clone(), }).collect::>() }; let snapshot = SessionSnapshot { id: Uuid::new_v4().to_string(), name, tabs, saved_at: chrono::Utc::now().timestamp(), is_auto: false, }; let mut store: SessionStore = crate::persistence::load_json(&app, "sessions_all.json").unwrap_or_default(); store.sessions.insert(0, snapshot.clone()); store.sessions.retain(|s| !s.is_auto); store.sessions.truncate(20); crate::persistence::save_json(&app, "sessions_all.json", &store)?; crate::persistence::save_json(&app, "session_latest.json", &snapshot)?; Ok(snapshot) } #[tauri::command] pub fn sessions_load(app: AppHandle) -> Result { let store: SessionStore = crate::persistence::load_json(&app, "sessions_all.json").unwrap_or_default(); if let Some(latest) = store.sessions.first() { return Ok(latest.clone()); } crate::persistence::load_json(&app, "session_latest.json") } #[tauri::command] pub fn sessions_list(app: AppHandle) -> Result, String> { let store: SessionStore = crate::persistence::load_json(&app, "sessions_all.json").unwrap_or_default(); Ok(store.sessions) } #[tauri::command] pub fn sessions_auto_save(app: AppHandle) -> Result<(), String> { let tabs = { let state = app.state::(); let tm = state.tabs.lock().map_err(|_| "lock")?; tm.order.iter().filter_map(|id| tm.tabs.get(id)).map(|t| SessionTab { url: t.url.clone(), title: t.title.clone(), }).collect::>() }; let snapshot = SessionSnapshot { id: format!("auto-{}", chrono::Utc::now().timestamp()), name: "Auto-save".to_string(), tabs, saved_at: chrono::Utc::now().timestamp(), is_auto: true, }; crate::persistence::save_json(&app, "session_auto.json", &snapshot) } #[tauri::command] pub fn sessions_delete(app: AppHandle, id: String) -> Result<(), String> { let mut store: SessionStore = crate::persistence::load_json(&app, "sessions_all.json").unwrap_or_default(); store.sessions.retain(|s| s.id != id); crate::persistence::save_json(&app, "sessions_all.json", &store) } #[tauri::command] pub fn sessions_rename(app: AppHandle, id: String, name: String) -> Result { let mut store: SessionStore = crate::persistence::load_json(&app, "sessions_all.json").unwrap_or_default(); let session = store.sessions.iter_mut().find(|s| s.id == id).ok_or("session not found")?; session.name = name; let result = session.clone(); crate::persistence::save_json(&app, "sessions_all.json", &store)?; Ok(result) }