feat: persist project selection

This commit is contained in:
Dave
2025-12-24 17:46:27 +00:00
parent 4e2d7416e8
commit e229f2efa8
10 changed files with 192 additions and 7 deletions

View File

@@ -1,8 +1,13 @@
use crate::state::SessionState;
use serde::Serialize;
use serde_json::json;
use std::fs;
use std::path::PathBuf;
use tauri::State;
use tauri::{AppHandle, State};
use tauri_plugin_store::StoreExt;
const STORE_PATH: &str = "store.json";
const KEY_LAST_PROJECT: &str = "last_project_path";
// -----------------------------------------------------------------------------
// Helper Functions
@@ -32,7 +37,11 @@ fn resolve_path(state: &State<'_, SessionState>, relative_path: &str) -> Result<
// -----------------------------------------------------------------------------
#[tauri::command]
pub async fn open_project(path: String, state: State<'_, SessionState>) -> Result<String, String> {
pub async fn open_project(
app: AppHandle,
path: String,
state: State<'_, SessionState>,
) -> Result<String, String> {
let p = PathBuf::from(&path);
// Validate path existence in blocking thread
@@ -49,13 +58,73 @@ pub async fn open_project(path: String, state: State<'_, SessionState>) -> Resul
.await
.map_err(|e| format!("Task failed: {}", e))??;
let mut root = state.project_root.lock().map_err(|e| e.to_string())?;
*root = Some(p.clone());
{
let mut root = state.project_root.lock().map_err(|e| e.to_string())?;
*root = Some(p.clone());
}
// Persist to store
let store = app
.store(STORE_PATH)
.map_err(|e| format!("Failed to access store: {}", e))?;
store.set(KEY_LAST_PROJECT, json!(path));
let _ = store.save();
println!("Project opened: {:?}", p);
Ok(path)
}
#[tauri::command]
pub async fn close_project(app: AppHandle, state: State<'_, SessionState>) -> Result<(), String> {
// Clear session state
{
let mut root = state.project_root.lock().map_err(|e| e.to_string())?;
*root = None;
}
// Clear from store
let store = app
.store(STORE_PATH)
.map_err(|e| format!("Failed to access store: {}", e))?;
store.delete(KEY_LAST_PROJECT);
let _ = store.save();
Ok(())
}
#[tauri::command]
pub async fn get_current_project(
app: AppHandle,
state: State<'_, SessionState>,
) -> Result<Option<String>, String> {
// 1. Check in-memory state
{
let root = state.project_root.lock().map_err(|e| e.to_string())?;
if let Some(path) = &*root {
return Ok(Some(path.to_string_lossy().to_string()));
}
}
// 2. Check store
let store = app
.store(STORE_PATH)
.map_err(|e| format!("Failed to access store: {}", e))?;
if let Some(val) = store.get(KEY_LAST_PROJECT) {
if let Some(path_str) = val.as_str() {
let p = PathBuf::from(path_str);
if p.exists() && p.is_dir() {
// Update session state
let mut root = state.project_root.lock().map_err(|e| e.to_string())?;
*root = Some(p.clone());
return Ok(Some(path_str.to_string()));
}
}
}
Ok(None)
}
#[tauri::command]
pub async fn read_file(path: String, state: State<'_, SessionState>) -> Result<String, String> {
let full_path = resolve_path(&state, &path)?;