File size: 4,394 Bytes
6c7e6f1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | use std::fs;
use std::path::PathBuf;
use tauri::{AppHandle, Manager};
pub fn app_file_path(app: &AppHandle, name: &str) -> Result<PathBuf, String> {
let dir = app.path().app_data_dir().map_err(|e| e.to_string())?.join("musealpha");
fs::create_dir_all(&dir).map_err(|e| e.to_string())?;
Ok(dir.join(name))
}
pub fn save_json<T: serde::Serialize>(app: &AppHandle, name: &str, value: &T) -> Result<(), String> {
let path = app_file_path(app, name)?;
let json = serde_json::to_string_pretty(value).map_err(|e| e.to_string())?;
fs::write(path, json).map_err(|e| e.to_string())
}
pub fn load_json<T: serde::de::DeserializeOwned + Default>(app: &AppHandle, name: &str) -> Result<T, String> {
let path = app_file_path(app, name)?;
if !path.exists() {
return Ok(T::default());
}
let json = fs::read_to_string(path).map_err(|e| e.to_string())?;
serde_json::from_str(&json).map_err(|e| e.to_string())
}
/// Storage info for the settings panel
#[derive(serde::Serialize)]
pub struct StorageInfo {
pub data_path: String,
pub total_size_bytes: u64,
pub file_count: usize,
pub project_count: usize,
pub library_count: usize,
pub library_size_bytes: u64,
pub projects_size_bytes: u64,
}
#[tauri::command]
pub fn storage_info(app: AppHandle) -> Result<StorageInfo, String> {
let dir = app.path().app_data_dir().map_err(|e| e.to_string())?.join("musealpha");
let data_path = dir.to_string_lossy().to_string();
if !dir.exists() {
return Ok(StorageInfo { data_path, total_size_bytes: 0, file_count: 0, project_count: 0, library_count: 0, library_size_bytes: 0, projects_size_bytes: 0 });
}
let mut total_size: u64 = 0;
let mut file_count: usize = 0;
let mut projects_size: u64 = 0;
let mut project_count: usize = 0;
let mut library_size: u64 = 0;
if let Ok(entries) = fs::read_dir(&dir) {
for entry in entries.flatten() {
if let Ok(meta) = entry.metadata() {
if meta.is_file() {
let size = meta.len();
total_size += size;
file_count += 1;
let name = entry.file_name().to_string_lossy().to_string();
if name.starts_with("project_") && name.ends_with(".json") {
projects_size += size;
project_count += 1;
}
if name == "library.json" {
library_size = size;
}
}
}
}
}
// Count library items
let library_count = load_json::<Vec<serde_json::Value>>(&app, "library.json").map(|v| v.len()).unwrap_or(0);
Ok(StorageInfo { data_path, total_size_bytes: total_size, file_count, project_count, library_count, library_size_bytes: library_size, projects_size_bytes: projects_size })
}
/// Clear all library data
#[tauri::command]
pub fn storage_clear_library(app: AppHandle) -> Result<(), String> {
let path = app_file_path(&app, "library.json")?;
if path.exists() { fs::write(&path, "[]").map_err(|e| e.to_string())?; }
// Also clear in-memory state
let state = app.state::<crate::library::LibraryState>();
let mut items = state.items.lock().map_err(|_| "lock")?;
items.clear();
Ok(())
}
/// Delete all project files and reset index
#[tauri::command]
pub fn storage_clear_projects(app: AppHandle) -> Result<(), String> {
let dir = app.path().app_data_dir().map_err(|e| e.to_string())?.join("musealpha");
if let Ok(entries) = fs::read_dir(&dir) {
for entry in entries.flatten() {
let name = entry.file_name().to_string_lossy().to_string();
if name.starts_with("project_") && name.ends_with(".json") {
let _ = fs::remove_file(entry.path());
}
}
}
// Reset index
save_json(&app, "projects_index.json", &serde_json::json!({"projects": [], "active_id": null}))?;
Ok(())
}
/// Reveal app data folder in OS file manager
#[tauri::command]
pub fn storage_reveal_folder(app: AppHandle) -> Result<(), String> {
let dir = app.path().app_data_dir().map_err(|e| e.to_string())?.join("musealpha");
fs::create_dir_all(&dir).map_err(|e| e.to_string())?;
opener::open(dir.to_string_lossy().as_ref()).map_err(|e| format!("Could not open folder: {e}"))
}
|