diff --git a/src/components/mail/listing/offline.rs b/src/components/mail/listing/offline.rs index b3102185..5266974a 100644 --- a/src/components/mail/listing/offline.rs +++ b/src/components/mail/listing/offline.rs @@ -26,7 +26,7 @@ use crate::components::utilities::PageMovement; pub struct OfflineListing { cursor_pos: (usize, MailboxHash), _row_updates: SmallVec<[ThreadHash; 8]>, - + dirty: bool, id: ComponentId, } @@ -88,6 +88,7 @@ impl OfflineListing { OfflineListing { cursor_pos, _row_updates: SmallVec::new(), + dirty: true, id: ComponentId::new_v4(), } } @@ -95,6 +96,10 @@ impl OfflineListing { impl Component for OfflineListing { fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { + if !self.dirty { + return; + } + self.dirty = false; let theme_default = conf::value(context, "theme_default"); clear_area(grid, area, theme_default); if let Err(err) = context.is_online(self.cursor_pos.0) { @@ -117,19 +122,53 @@ impl Component for OfflineListing { None, ); } else { + let (_, mut y) = write_string_to_grid( + "loading...", + grid, + Color::Byte(243), + theme_default.bg, + theme_default.attrs, + area, + None, + ); + let mut jobs: SmallVec<[_; 64]> = context.accounts[self.cursor_pos.0] + .active_jobs + .iter() + .collect(); + jobs.sort_by_key(|(j, _)| *j); + for (job_id, j) in jobs { + write_string_to_grid( + &format!("{}: {:?}", job_id, j), + grid, + theme_default.fg, + theme_default.bg, + theme_default.attrs, + (set_y(upper_left!(area), y + 1), bottom_right!(area)), + None, + ); + y += 1; + } + context .replies .push_back(UIEvent::AccountStatusChange(self.cursor_pos.0)); } context.dirty_areas.push_back(area); } - fn process_event(&mut self, _event: &mut UIEvent, _context: &mut Context) -> bool { + fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool { + match event { + UIEvent::AccountStatusChange(idx) if *idx == self.cursor_pos.0 => self.dirty = true, + _ => {} + } false } fn is_dirty(&self) -> bool { - false + self.dirty + } + + fn set_dirty(&mut self, value: bool) { + self.dirty = true; } - fn set_dirty(&mut self, _value: bool) {} fn id(&self) -> ComponentId { self.id diff --git a/src/conf/accounts.rs b/src/conf/accounts.rs index 6302dad3..9fe1505b 100644 --- a/src/conf/accounts.rs +++ b/src/conf/accounts.rs @@ -136,7 +136,7 @@ pub struct Account { pub index: usize, name: String, hash: AccountHash, - pub is_online: bool, + pub is_online: Result<()>, pub(crate) mailbox_entries: HashMap, pub(crate) mailboxes_order: Vec, tree: Vec, @@ -348,7 +348,11 @@ impl Account { index, hash, name, - is_online: !backend.is_remote(), + is_online: if !backend.is_remote() { + Ok(()) + } else { + Err(MeliError::new("Attempting connection.")) + }, mailbox_entries: Default::default(), mailboxes_order: Default::default(), tree: Default::default(), @@ -1410,7 +1414,7 @@ impl Account { } if self.is_async { - if self.is_online { + if self.is_online.is_ok() { return Ok(()); } if !self.active_jobs.values().any(JobRequest::is_online) { @@ -1419,13 +1423,20 @@ impl Account { self.active_jobs.insert(job_id, JobRequest::IsOnline(rcvr)); } } - return Err(MeliError::new("Attempting connection.")); + return self.is_online.clone(); } else { let ret = self.backend.read().unwrap().is_online(); - if ret.is_ok() != self.is_online && ret.is_ok() { - self.init(None)?; + if ret.is_ok() != self.is_online.is_ok() { + if ret.is_ok() { + self.init(None)?; + } + self.sender + .send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange( + self.index, + ))) + .unwrap(); } - self.is_online = ret.is_ok(); + self.is_online = ret.clone(); ret } } @@ -1583,20 +1594,20 @@ impl Account { } JobRequest::IsOnline(mut chan) => { let is_online = chan.try_recv().unwrap(); - if is_online.is_some() { - let is_online = is_online.unwrap(); + if let Some(is_online) = is_online { + self.sender + .send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange( + self.index, + ))) + .unwrap(); if is_online.is_ok() { - if !self.is_online { + if self.is_online.is_err() { self.watch(); } - self.is_online = true; - self.sender - .send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange( - self.index, - ))) - .unwrap(); + self.is_online = Ok(()); return true; } + self.is_online = is_online; } if let Ok(online_job) = self.backend.read().unwrap().is_online_async() { let (rcvr, job_id) = self.job_executor.spawn_specialized(online_job); @@ -1605,11 +1616,18 @@ impl Account { } JobRequest::Refresh(_mailbox_hash, mut chan) => { let r = chan.try_recv().unwrap(); - if r.is_some() && r.unwrap().is_ok() { - if !self.is_online { - self.watch(); + if let Some(r) = r { + if r.is_ok() { + if self.is_online.is_err() { + self.watch(); + } } - self.is_online = true; + self.is_online = Ok(()); + self.sender + .send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange( + self.index, + ))) + .unwrap(); } self.sender .send(ThreadEvent::UIEvent(UIEvent::StatusEvent( diff --git a/src/jobs.rs b/src/jobs.rs index 3f3a8d49..a2f66937 100644 --- a/src/jobs.rs +++ b/src/jobs.rs @@ -59,7 +59,9 @@ fn find_task(local: &Worker, global: &Injector, stealers: &[Stealer] macro_rules! uuid_hash_type { ($n:ident) => { - #[derive(PartialEq, Hash, Eq, Copy, Clone, Serialize, Deserialize, Default)] + #[derive( + PartialEq, Hash, Eq, Copy, Clone, Ord, PartialOrd, Serialize, Deserialize, Default, + )] pub struct $n(Uuid); impl core::fmt::Debug for $n { diff --git a/src/state.rs b/src/state.rs index e34d7176..a1f5b31d 100644 --- a/src/state.rs +++ b/src/state.rs @@ -122,7 +122,7 @@ impl Context { ref mut replies, .. } = self; - let was_online = accounts[account_pos].is_online; + let was_online = accounts[account_pos].is_online.is_ok(); let ret = accounts[account_pos].is_online(); if ret.is_ok() { if !was_online {