diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/app.rs | 32 |
1 files changed, 30 insertions, 2 deletions
@@ -1,15 +1,17 @@ | |||
1 | use std::default::Default; | 1 | use std::default::Default; |
2 | use std::f64; | 2 | use std::f64; |
3 | use std::time::Duration; | ||
3 | use std::fs::{File, OpenOptions}; | 4 | use std::fs::{File, OpenOptions}; |
4 | use std::io::prelude::*; | 5 | use std::io::prelude::*; |
5 | use std::path::PathBuf; | 6 | use std::path::PathBuf; |
7 | use std::sync::mpsc::{channel, Receiver}; | ||
6 | 8 | ||
9 | use chrono::Local; | ||
7 | use cursive::direction::{Absolute, Direction}; | 10 | use cursive::direction::{Absolute, Direction}; |
8 | use cursive::event::{Event, EventResult, Key}; | 11 | use cursive::event::{Event, EventResult, Key}; |
9 | use cursive::view::View; | 12 | use cursive::view::View; |
10 | use cursive::{Printer, Vec2}; | 13 | use cursive::{Printer, Vec2}; |
11 | 14 | use notify::{watcher, RecursiveMode, Watcher, DebouncedEvent, INotifyWatcher}; | |
12 | use chrono::Local; | ||
13 | 15 | ||
14 | use crate::habit::{Bit, Count, HabitWrapper, TrackEvent, ViewMode}; | 16 | use crate::habit::{Bit, Count, HabitWrapper, TrackEvent, ViewMode}; |
15 | use crate::utils; | 17 | use crate::utils; |
@@ -22,6 +24,8 @@ pub struct App { | |||
22 | // holds app data | 24 | // holds app data |
23 | habits: Vec<Box<dyn HabitWrapper>>, | 25 | habits: Vec<Box<dyn HabitWrapper>>, |
24 | 26 | ||
27 | _file_watcher: INotifyWatcher, | ||
28 | file_event_recv: Receiver<DebouncedEvent>, | ||
25 | focus: usize, | 29 | focus: usize, |
26 | view_month_offset: u32, | 30 | view_month_offset: u32, |
27 | } | 31 | } |
@@ -34,9 +38,16 @@ impl Default for App { | |||
34 | 38 | ||
35 | impl App { | 39 | impl App { |
36 | pub fn new() -> Self { | 40 | pub fn new() -> Self { |
41 | let (tx, rx) = channel(); | ||
42 | let mut watcher = watcher(tx, Duration::from_secs(1)).unwrap(); | ||
43 | watcher.watch(utils::auto_habit_file(), RecursiveMode::Recursive).unwrap_or_else(|e| { | ||
44 | panic!("Unable to start file watcher: {}", e); | ||
45 | }); | ||
37 | return App { | 46 | return App { |
38 | habits: vec![], | 47 | habits: vec![], |
39 | focus: 0, | 48 | focus: 0, |
49 | _file_watcher: watcher, | ||
50 | file_event_recv: rx, | ||
40 | view_month_offset: 0, | 51 | view_month_offset: 0, |
41 | }; | 52 | }; |
42 | } | 53 | } |
@@ -303,6 +314,23 @@ impl View for App { | |||
303 | } | 314 | } |
304 | 315 | ||
305 | fn on_event(&mut self, e: Event) -> EventResult { | 316 | fn on_event(&mut self, e: Event) -> EventResult { |
317 | match self.file_event_recv.try_recv() { | ||
318 | Ok(DebouncedEvent::Write(_)) => { | ||
319 | let read_from_file = |file: PathBuf| -> Vec<Box<dyn HabitWrapper>> { | ||
320 | if let Ok(ref mut f) = File::open(file) { | ||
321 | let mut j = String::new(); | ||
322 | f.read_to_string(&mut j); | ||
323 | return serde_json::from_str(&j).unwrap(); | ||
324 | } else { | ||
325 | return Vec::new(); | ||
326 | } | ||
327 | }; | ||
328 | let auto = read_from_file(utils::auto_habit_file()); | ||
329 | self.habits.retain(|x| !x.is_auto()); | ||
330 | self.habits.extend(auto); | ||
331 | } | ||
332 | _ => {} | ||
333 | }; | ||
306 | match e { | 334 | match e { |
307 | Event::Key(Key::Right) | Event::Key(Key::Tab) | Event::Char('l') => { | 335 | Event::Key(Key::Right) | Event::Key(Key::Tab) | Event::Char('l') => { |
308 | self.set_focus(Absolute::Right); | 336 | self.set_focus(Absolute::Right); |