feat: Make app fully portable
- Add tauri-plugin-store for portable data storage - Implement portable data directory (TypoGenie-Data/ next to EXE) - Configure Rust backend to use EXE-relative paths - Add store permissions for persistent settings - Update README with portable badges and documentation - Document how to build and use the portable EXE - Zero registry, zero AppData, fully self-contained
This commit is contained in:
@@ -1,26 +1,59 @@
|
||||
use tauri::Manager;
|
||||
use std::path::PathBuf;
|
||||
use tauri::{Manager, path::BaseDirectory};
|
||||
|
||||
/// Gets the portable data directory (next to the executable)
|
||||
fn get_portable_data_dir(app: &tauri::App) -> PathBuf {
|
||||
// Get the directory where the EXE is located
|
||||
if let Ok(exe_dir) = app.path().resolve("", BaseDirectory::Executable) {
|
||||
let portable_dir = exe_dir.join("TypoGenie-Data");
|
||||
// Create the directory if it doesn't exist
|
||||
let _ = std::fs::create_dir_all(&portable_dir);
|
||||
portable_dir
|
||||
} else {
|
||||
// Fallback to app data directory (shouldn't happen)
|
||||
app.path().app_data_dir().unwrap_or_else(|_| PathBuf::from("."))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.setup(|app| {
|
||||
// Show the main window after setup
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(tauri_plugin_store::Builder::default().build())
|
||||
.setup(|app| {
|
||||
// Set up portable data directory
|
||||
let portable_dir = get_portable_data_dir(app);
|
||||
println!("Portable data directory: {:?}", portable_dir);
|
||||
|
||||
// Store the portable path in app state for frontend access
|
||||
app.manage(PortableDataDir(portable_dir));
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
.level(log::LevelFilter::Info)
|
||||
.build(),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
// Show the main window after setup
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
.level(log::LevelFilter::Info)
|
||||
.build(),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![get_data_dir])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
/// Structure to hold the portable data directory path
|
||||
struct PortableDataDir(PathBuf);
|
||||
|
||||
/// Command to get the portable data directory from the frontend
|
||||
#[tauri::command]
|
||||
fn get_data_dir(state: tauri::State<PortableDataDir>) -> String {
|
||||
state.0.to_string_lossy().to_string()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user