use crate::action::Action;
use notify_debouncer_mini::{
DebounceEventResult, DebouncedEventKind, Debouncer, new_debouncer, notify::RecommendedWatcher,
};
use std::path::Path;
use std::time::Duration;
use tokio::sync::mpsc;
pub fn spawn_watcher(
root: &Path,
tx: mpsc::UnboundedSender<Action>,
) -> anyhow::Result<Debouncer<RecommendedWatcher>> {
let mut debouncer = new_debouncer(
Duration::from_millis(500),
move |result: DebounceEventResult| {
let Ok(events) = result else { return };
let changed: Vec<_> = events
.iter()
.filter(|e| {
e.kind == DebouncedEventKind::Any
&& e.path
.extension()
.is_some_and(|ext| ext == "md" || ext == "markdown")
})
.map(|e| e.path.clone())
.collect();
if !changed.is_empty() {
let _ = tx.send(Action::FilesChanged(changed));
}
},
)?;
debouncer.watcher().watch(
root,
notify_debouncer_mini::notify::RecursiveMode::Recursive,
)?;
Ok(debouncer)
}