use notify::{RecursiveMode, Watcher, Config, Event}; use std::sync::{Arc, Mutex}; use tauri::{AppHandle, Emitter, Runtime, State}; #[derive(serde::Serialize, Clone)] struct FileChangeEvent { path: String, filename: String, action: String, } struct WatcherState { watcher: Option, } #[tauri::command] async fn start_watching( app: AppHandle, path: String, state: State<'_, Arc>>, ) -> Result { let mut watcher_state = state.lock().map_err(|e| e.to_string())?; // Stop previous watcher if any if let Some(mut w) = watcher_state.watcher.take() { let _ = w.unwatch(std::path::Path::new(&path)); } let app_clone = app.clone(); let path_buf = std::path::PathBuf::from(&path); // Create directory if not exists if !path_buf.exists() { std::fs::create_dir_all(&path_buf).map_err(|e| e.to_string())?; } let mut watcher = notify::RecommendedWatcher::new( move |res: notify::Result| { if let Ok(event) = res { if event.kind.is_create() || event.kind.is_modify() { for p in event.paths { let filename = p.file_name() .and_then(|f| f.to_str()) .unwrap_or("") .to_string(); let _ = app_clone.emit("file-changed", FileChangeEvent { path: p.to_string_lossy().to_string(), filename, action: if event.kind.is_create() { "create".to_string() } else { "modify".to_string() }, }); } } } }, Config::default(), ).map_err(|e| e.to_string())?; watcher.watch(&path_buf, RecursiveMode::NonRecursive).map_err(|e| e.to_string())?; watcher_state.watcher = Some(watcher); Ok(path) } #[tauri::command] async fn stop_watching( state: State<'_, Arc>>, ) -> Result<(), String> { let mut watcher_state = state.lock().map_err(|e| e.to_string())?; watcher_state.watcher.take(); Ok(()) } #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { let watcher_state = Arc::new(Mutex::new(WatcherState { watcher: None })); tauri::Builder::default() .manage(watcher_state) .invoke_handler(tauri::generate_handler![start_watching, stop_watching]) .setup(|app| { 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"); }