diff --git a/melib/src/mailbox/accounts.rs b/melib/src/mailbox/accounts.rs index d9d6cceaa..7cc49497a 100644 --- a/melib/src/mailbox/accounts.rs +++ b/melib/src/mailbox/accounts.rs @@ -57,7 +57,7 @@ impl Account { .position(|x: &Folder| x.name() == settings.sent_folder); for f in ref_folders { folders.push(None); - let mut handle = backend.get(&f); + let handle = backend.get(&f); workers.push(Some(handle)); } Account { @@ -72,6 +72,11 @@ impl Account { backend: backend, } } + pub fn reload(&mut self, idx: usize) { + let ref_folders: Vec = self.backend.folders(); + let handle = self.backend.get(&ref_folders[idx]); + self.workers[idx] = Some(handle); + } pub fn watch(&self, r: RefreshEventConsumer) -> () { self.backend.watch(r).unwrap(); } diff --git a/src/bin.rs b/src/bin.rs index df422ebd4..4aff6265c 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -181,11 +181,9 @@ fn main() { } }, ThreadEvent::RefreshMailbox { hash : h } => { - eprintln!("got refresh mailbox hash {:x}", h); state.hash_to_folder(h); //state.rcv_event(UIEvent { id: 0, event_type: UIEventType::Notification(n.clone())}); state.redraw(); - /* Don't handle this yet. */ }, ThreadEvent::UIEvent(UIEventType::ChangeMode(f)) => { state.mode = f; diff --git a/ui/src/components/mail/compose.rs b/ui/src/components/mail/compose.rs index 0a01eea84..6e55a4376 100644 --- a/ui/src/components/mail/compose.rs +++ b/ui/src/components/mail/compose.rs @@ -36,7 +36,7 @@ impl Component for Composer { context.dirty_areas.push_back(area); } - fn process_event(&mut self, event: &UIEvent, context: &mut Context) {} + fn process_event(&mut self, _event: &UIEvent, _context: &mut Context) {} fn is_dirty(&self) -> bool { true diff --git a/ui/src/components/mail/listing/mod.rs b/ui/src/components/mail/listing/mod.rs index d16228af0..55aebc54e 100644 --- a/ui/src/components/mail/listing/mod.rs +++ b/ui/src/components/mail/listing/mod.rs @@ -692,9 +692,10 @@ impl Component for MailListing { self.view = None; } UIEventType::MailboxUpdate((ref idxa, ref idxf)) => { - if *idxa == self.new_cursor_pos.1 && *idxf == self.new_cursor_pos.0 { - self.refresh_mailbox(context); + if *idxa == self.new_cursor_pos.0 && *idxf == self.new_cursor_pos.1 { self.dirty = true; + self.refresh_mailbox(context); + return; } } UIEventType::ChangeMode(UIMode::Normal) => { diff --git a/ui/src/state.rs b/ui/src/state.rs index 8119b5962..bd4aebbce 100644 --- a/ui/src/state.rs +++ b/ui/src/state.rs @@ -50,7 +50,6 @@ pub struct Context { /// Events queue that components send back to the state pub replies: VecDeque, - backends: Backends, input_thread: chan::Sender, pub temp_files: Vec, @@ -155,7 +154,6 @@ impl State { accounts, mailbox_hashes: FnvHashMap::with_capacity_and_hasher(1, Default::default()), - backends, settings: settings.clone(), runtime_settings: settings, dirty_areas: VecDeque::with_capacity(5), @@ -188,8 +186,41 @@ impl State { } s } - pub fn hash_to_folder(&self, hash: u64) { - eprintln!("got refresh {:?}", self.context.mailbox_hashes[&hash]); + /* + * When we receive a folder hash from a watcher thread, + * we match the hash to the index of the mailbox, request a reload + * and startup a thread to remind us to poll it every now and then till it's finished. + */ + pub fn hash_to_folder(&mut self, hash: u64) { + let (idxa, idxm) = self.context.mailbox_hashes[&hash]; + self.context.accounts[idxa].reload(idxm); + let (startup_tx, startup_rx) = chan::async(); + let startup_thread = { + let sender = self.sender.clone(); + let startup_rx = startup_rx.clone(); + + thread::Builder::new() + .name("startup-thread".to_string()) + .spawn(move || { + let dur = time::Duration::from_millis(100); + loop { + chan_select! { + default => {}, + startup_rx.recv() -> _ => { + sender.send(ThreadEvent::UIEvent(UIEventType::MailboxUpdate((idxa,idxm)))); + sender.send(ThreadEvent::ThreadJoin(thread::current().id())); + return; + } + } + sender.send(ThreadEvent::UIEvent(UIEventType::StartupCheck)); + thread::sleep(dur); + } + }) + .unwrap() + }; + self.startup_thread = Some(startup_tx); + self.threads + .insert(startup_thread.thread().id(), startup_thread); } /// If an owned thread returns a `ThreadEvent::ThreadJoin` event to `State` then it must remove