Spaces:
Sleeping
Sleeping
File size: 2,973 Bytes
ae4ceef | 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 | 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<notify::RecommendedWatcher>,
}
#[tauri::command]
async fn start_watching<R: Runtime>(
app: AppHandle<R>,
path: String,
state: State<'_, Arc<Mutex<WatcherState>>>,
) -> Result<String, String> {
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<Event>| {
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<Mutex<WatcherState>>>,
) -> 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");
}
|