| 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<SessionTab>,
|
| 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<SessionSnapshot>,
|
| }
|
|
|
| #[tauri::command]
|
| pub fn sessions_save(app: AppHandle, name: String) -> Result<SessionSnapshot, String> {
|
| let tabs = {
|
| let state = app.state::<AppState>();
|
| 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::<Vec<_>>()
|
| };
|
| 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<SessionSnapshot, String> {
|
| 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<Vec<SessionSnapshot>, 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::<AppState>();
|
| 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::<Vec<_>>()
|
| };
|
| 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<SessionSnapshot, String> {
|
| 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)
|
| }
|
|
|