diff --git a/Cargo.toml b/Cargo.toml index 9a8091625..cd25a38a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,6 +28,7 @@ notify = "4.0.1" termion = "1.5.1" chan = "0.1.21" chan-signal = "0.3.1" +notify-rust = "^3" [profile.release] #lto = true diff --git a/src/bin.rs b/src/bin.rs index 45abefb24..96299f8f7 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -22,6 +22,7 @@ extern crate melib; #[macro_use] extern crate nom; extern crate termion; +extern crate notify_rust; pub mod ui; use ui::*; @@ -69,10 +70,14 @@ fn main() { let menu = Entity {component: Box::new(AccountMenu::new(&state.context.accounts)) }; let listing = MailListing::new(); let b = Entity { component: Box::new(listing) }; - let window = Entity { component: Box::new(VSplit::new(menu,b,90)) }; + let window = Entity { component: Box::new(VSplit::new(menu, b, 80)) }; let status_bar = Entity { component: Box::new(StatusBar::new(window)) }; state.register_entity(status_bar); + + let xdg_notifications = Entity { component: Box::new(ui::components::notifications::XDGNotifications {}) }; + state.register_entity(xdg_notifications); + /* Keep track of the input mode. See ui::UIMode for details */ let mut mode: UIMode = UIMode::Normal; 'main: loop { @@ -94,6 +99,7 @@ fn main() { UIMode::Normal => { match k { Key::Char('q') | Key::Char('Q') => { + drop(state); break 'main; }, Key::Char(';') => { @@ -124,6 +130,8 @@ fn main() { } }, ThreadEvent::RefreshMailbox { name : n } => { + state.rcv_event(UIEvent { id: 0, event_type: UIEventType::Notification(n.clone())}); + state.redraw(); /* Don't handle this yet. */ eprintln!("Refresh mailbox {}", n); }, diff --git a/src/conf/mod.rs b/src/conf/mod.rs index 589cc5284..3f81d13b7 100644 --- a/src/conf/mod.rs +++ b/src/conf/mod.rs @@ -87,7 +87,7 @@ pub struct AccountSettings { pub folders: Vec, format: String, pub sent_folder: String, - threaded: bool, + pub threaded: bool, } impl AccountSettings { @@ -157,8 +157,7 @@ impl Settings { if path.is_dir() { folders.push(Folder::new(path.to_str().unwrap().to_string(), path.file_name().unwrap().to_str().unwrap().to_string(), path_children)); } - //recurse_folders(&mut folders, &x.folders); - eprintln!("folders is {:?}", folders); + //folders.sort_by(|a, b| b.name.cmp(&a.name)); s.insert( id.clone(), AccountSettings { @@ -170,7 +169,6 @@ impl Settings { }, ); } - eprintln!("pager settings are {:?}", fs.pager); Settings { accounts: s, pager: fs.pager } } diff --git a/src/conf/pager.rs b/src/conf/pager.rs index 2b95f5faf..4d8c6032e 100644 --- a/src/conf/pager.rs +++ b/src/conf/pager.rs @@ -13,6 +13,10 @@ fn eighty_percent () -> usize { 80 } +fn none() -> Option { + None +} + /// Settings for the pager function. #[derive(Debug, Deserialize)] pub struct PagerSettings { @@ -35,4 +39,9 @@ pub struct PagerSettings { /// Default: 80 #[serde(default = "eighty_percent")] pub pager_ratio: usize, + + /// A command to pipe mail output through for viewing in pager. + /// Default: None + #[serde(default = "none")] + pub filter: Option, } diff --git a/src/mailbox/accounts.rs b/src/mailbox/accounts.rs index cfb3c2e91..d2a99af6d 100644 --- a/src/mailbox/accounts.rs +++ b/src/mailbox/accounts.rs @@ -31,7 +31,7 @@ pub struct Account { sent_folder: Option, - settings: AccountSettings, + pub settings: AccountSettings, pub backend: Box, } diff --git a/src/mailbox/backends/imap.rs b/src/mailbox/backends/imap.rs index 9dd112b76..b693bc835 100644 --- a/src/mailbox/backends/imap.rs +++ b/src/mailbox/backends/imap.rs @@ -31,7 +31,7 @@ pub struct ImapOp { } impl ImapOp { - pub fn new(path: String) -> Self { + pub fn new(_path: String) -> Self { ImapOp { } } @@ -63,16 +63,16 @@ pub struct ImapType { impl MailBackend for ImapType { - fn get(&self, folder: &Folder) -> Result> { + fn get(&self, _folder: &Folder) -> Result> { unimplemented!(); } - fn watch(&self, sender: RefreshEventConsumer, folders: &[Folder]) -> () { + fn watch(&self, _sender: RefreshEventConsumer, _folders: &[Folder]) -> () { unimplemented!(); } } impl ImapType { - pub fn new(path: &str) -> Self { + pub fn new(_path: &str) -> Self { ImapType { } } diff --git a/src/mailbox/backends/mbox.rs b/src/mailbox/backends/mbox.rs index ad63522f8..4719ab6e3 100644 --- a/src/mailbox/backends/mbox.rs +++ b/src/mailbox/backends/mbox.rs @@ -33,7 +33,7 @@ pub struct MboxOp { } impl MboxOp { - pub fn new(path: String) -> Self { + pub fn new(_path: String) -> Self { MboxOp { } } @@ -65,16 +65,16 @@ pub struct MboxType { impl MailBackend for MboxType { - fn get(&self, folder: &Folder) -> Result> { + fn get(&self, _folder: &Folder) -> Result> { unimplemented!(); } - fn watch(&self, sender: RefreshEventConsumer, folders: &[Folder]) -> () { + fn watch(&self, _sender: RefreshEventConsumer, _folders: &[Folder]) -> () { unimplemented!(); } } impl MboxType { - pub fn new(path: &str) -> Self { + pub fn new(_path: &str) -> Self { MboxType { } } diff --git a/src/ui/components/mail.rs b/src/ui/components/mail.rs index 7831e21a2..1843c6668 100644 --- a/src/ui/components/mail.rs +++ b/src/ui/components/mail.rs @@ -32,7 +32,7 @@ impl MailListing { pub fn new() -> Self { - let mut content = CellBuffer::new(0, 0, Cell::with_char(' ')); + let content = CellBuffer::new(0, 0, Cell::with_char(' ')); MailListing { cursor_pos: (0, 1, 0), new_cursor_pos: (0, 0, 0), @@ -50,11 +50,13 @@ impl MailListing { self.cursor_pos.2 = 0; self.new_cursor_pos.2 = 0; self.cursor_pos.1 = self.new_cursor_pos.1; + self.cursor_pos.0 = self.new_cursor_pos.0; + let threaded = context.accounts[self.cursor_pos.0].settings.threaded; // Get mailbox as a reference. let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap(); // Inform State that we changed the current folder view. - context.replies.push_back(UIEvent { id: 0, event_type: UIEventType::RefreshMailbox(mailbox.clone()) }); + context.replies.push_back(UIEvent { id: 0, event_type: UIEventType::RefreshMailbox((self.cursor_pos.0, self.cursor_pos.1)) }); self.length = mailbox.len(); let mut content = CellBuffer::new(MAX_COLS, self.length+1, Cell::with_char(' ')); @@ -69,43 +71,118 @@ impl MailListing { return; } - // Populate `CellBuffer` with every entry. - // TODO: Lazy load? - let mut idx = 0; - for y in 0..=self.length { - if idx >= self.length { - /* No more entries left, so fill the rest of the area with empty space */ - clear_area(&mut content, - ((0, y), (MAX_COLS-1, self.length))); - break; + + // TODO: Fix the threaded hell and refactor stuff into seperate functions and/or modules. + if threaded { + let mut indentations: Vec = Vec::with_capacity(6); + /* Draw threaded view. */ + let mut iter = mailbox + .threaded_collection + .iter() + .enumerate() + .peekable(); + /* This is just a desugared for loop so that we can use .peek() */ + while let Some((idx, i)) = iter.next() { + let container = mailbox.get_thread(*i); + let indentation = container.get_indentation(); + + assert_eq!(container.has_message(), true); + match iter.peek() { + Some(&(_, x)) + if mailbox.get_thread(*x).get_indentation() == indentation => + { + indentations.pop(); + indentations.push(true); + } + _ => { + indentations.pop(); + indentations.push(false); + } + } + if container.has_sibling() { + indentations.pop(); + indentations.push(true); + } + let envelope : &Envelope = &mailbox.collection[container.get_message().unwrap()]; + let fg_color = if !envelope.is_seen() { + Color::Byte(0) + } else { + Color::Default + }; + let bg_color = if !envelope.is_seen() { + Color::Byte(251) + } else if idx % 2 == 0 { + Color::Byte(236) + } else { + Color::Default + } + let x = write_string_to_grid(&MailListing::make_thread_entry(envelope, idx, indentation, container, idx == self.cursor_pos.2, &indentations), + &mut content, + fg_color, + bg_color, + ((0, idx) , (MAX_COLS-1, idx))); + for x in x..MAX_COLS { + content[(x,idx)].set_ch(' '); + content[(x,idx)].set_bg(bg_color); + } + + match iter.peek() { + Some(&(_, x)) + if mailbox.get_thread(*x).get_indentation() > indentation => + { + indentations.push(false); + } + Some(&(_, x)) + if mailbox.get_thread(*x).get_indentation() < indentation => + { + for _ in 0..(indentation - mailbox.get_thread(*x).get_indentation()) { + indentations.pop(); + } + } + _ => {} + } } - /* Write an entire line for each envelope entry. */ - let envelope: &Envelope = &mailbox.collection[idx]; + } else { - let fg_color = if !envelope.is_seen() { - Color::Byte(0) - } else { - Color::Default - }; - let bg_color = if !envelope.is_seen() { - Color::Byte(251) - } else if idx % 2 == 0 { - Color::Byte(236) - } else { - Color::Default - }; - let x = write_string_to_grid(&MailListing::make_entry_string(envelope, idx), - &mut content, - fg_color, - bg_color, - ((0, y) , (MAX_COLS-1, y))); + // Populate `CellBuffer` with every entry. + // TODO: Lazy load? + let mut idx = 0; + for y in 0..=self.length { + if idx >= self.length { + /* No more entries left, so fill the rest of the area with empty space */ + clear_area(&mut content, + ((0, y), (MAX_COLS-1, self.length))); + break; + } + /* Write an entire line for each envelope entry. */ + let envelope: &Envelope = &mailbox.collection[idx]; - for x in x..MAX_COLS { - content[(x,y)].set_ch(' '); - content[(x,y)].set_bg(bg_color); + let fg_color = if !envelope.is_seen() { + Color::Byte(0) + } else { + Color::Default + }; + let bg_color = if !envelope.is_seen() { + Color::Byte(251) + } else if idx % 2 == 0 { + Color::Byte(236) + } else { + Color::Default + }; + let x = write_string_to_grid(&MailListing::make_entry_string(envelope, idx), + &mut content, + fg_color, + bg_color, + ((0, y) , (MAX_COLS-1, y))); + + for x in x..MAX_COLS { + content[(x,y)].set_ch(' '); + content[(x,y)].set_bg(bg_color); + } + + idx+=1; } - idx+=1; } self.content = content; @@ -180,13 +257,69 @@ impl MailListing { /// Create a pager for the `Envelope` currently under the cursor. fn draw_mail_view(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { { + let threaded = context.accounts[self.cursor_pos.0].settings.threaded; let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap(); - let envelope: &Envelope = &mailbox.collection[self.cursor_pos.2]; + let envelope: &Envelope = if threaded { + let i = mailbox.get_threaded_mail(self.cursor_pos.2); + &mailbox.collection[i] + } else { + &mailbox.collection[self.cursor_pos.2] + }; - self.pager = Some(Pager::new(envelope)); + let pager_filter = context.settings.pager.filter.clone(); + self.pager = Some(Pager::new(&envelope, pager_filter)); } self.pager.as_mut().map(|p| p.draw(grid, area, context)); } + fn make_thread_entry(envelope: &Envelope, idx: usize, indent: usize, + container: &Container, highlight: bool, indentations: &Vec) -> String { + let has_sibling = container.has_sibling(); + let has_parent = container.has_parent(); + let show_subject = container.get_show_subject(); + + let fg_color = if !envelope.is_seen() { + Color::Byte(0) + } else { + Color::Default + }; + let bg_color = if highlight { + if !envelope.is_seen() { + Color::Byte(252) + } else if idx % 2 == 0 { + Color::Byte(236) + } else { + Color::Default + } + } else { + Color::Byte(246) + }; + let mut s = format!("{} {} ", idx, &envelope.get_datetime().format("%Y-%m-%d %H:%M:%S").to_string()); // {} {:.85}",idx,),e.get_subject()) + for i in 0..indent { + if indentations.len() > i && indentations[i] + { + s.push('│'); + } else { + s.push(' '); + } + if i > 0 { + s.push(' '); + } + } + if indent > 0 { + if has_sibling && has_parent { + s.push('├'); + } else if has_sibling { + s.push('┬'); + } else { + s.push('└'); + } + s.push('─'); s.push('>'); + } + if show_subject { + s.push_str(&format!("{:.85}", envelope.get_subject())); + } + s + } } impl Component for MailListing { @@ -255,8 +388,14 @@ impl Component for MailListing { /* Draw header */ { + let threaded = context.accounts[self.cursor_pos.0].settings.threaded; let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap(); - let envelope: &Envelope = &mailbox.collection[self.cursor_pos.2]; + let envelope: &Envelope = if threaded { + let i = mailbox.get_threaded_mail(self.cursor_pos.2); + &mailbox.collection[i] + } else { + &mailbox.collection[self.cursor_pos.2] + }; let x = write_string_to_grid(&format!("Date: {}", envelope.get_date_as_str()), grid, @@ -369,11 +508,13 @@ impl Component for MailListing { match k { 'h' if accounts_length > 0 && self.new_cursor_pos.0 < accounts_length - 1 => { self.new_cursor_pos.0 = self.cursor_pos.0 + 1; + self.new_cursor_pos.1 = 0; self.dirty = true; self.refresh_mailbox(context); }, 'l' if self.cursor_pos.0 > 0 => { self.new_cursor_pos.0 = self.cursor_pos.0 - 1; + self.new_cursor_pos.1 = 0; self.dirty = true; self.refresh_mailbox(context); }, @@ -438,16 +579,16 @@ impl AccountMenu { cursor: None, } } - fn highlight_folder(&mut self, m: &Mailbox) { - self.dirty = true; - self.cursor = None; - } fn print_account(&self, grid: &mut CellBuffer, area: Area, a: &AccountMenuEntry) -> usize { if !is_valid_area!(area) { eprintln!("BUG: invalid area in print_account"); } let upper_left = upper_left!(area); let bottom_right = bottom_right!(area); + + + let highlight = self.cursor.map(|(x,_)| x == a.index).unwrap_or(false); + let mut parents: Vec> = vec!(None; a.entries.len()); for (idx, e) in a.entries.iter().enumerate() { @@ -461,10 +602,11 @@ impl AccountMenu { roots.push(idx); } } + eprintln!("roots is {:?}", roots); let mut inc = 0; let mut depth = String::from(""); - let mut s = String::from(format!("\n\n {}\n", a.name)); + let mut s = String::from(format!("{}\n", a.name)); fn pop(depth: &mut String) { depth.pop(); depth.pop(); @@ -489,8 +631,8 @@ impl AccountMenu { } for r in roots { print(r, &parents, &mut depth, &a.entries, &mut s, &mut inc); - } + eprintln!("s = {}", s); let lines: Vec<&str> = s.lines().collect(); let lines_len = lines.len(); @@ -504,14 +646,40 @@ impl AccountMenu { } else { format!("{}", lines[idx]) }; - write_string_to_grid(&s, + let color_fg = if highlight { + if idx > 1 && self.cursor.unwrap().1 == idx - 2 { + Color::Byte(233) + } else { + Color::Byte(15) + } + } else { + Color::Default + }; + + let color_bg = if highlight { + if idx > 1 && self.cursor.unwrap().1 == idx - 2 { + Color::Byte(15) + } else { + Color::Byte(233) + } + } else { + Color::Default + }; + + let x = write_string_to_grid(&s, grid, - Color::Byte(30), - Color::Default, + color_fg, + color_bg, (set_y(upper_left, y), bottom_right)); + + if highlight && idx > 1 && self.cursor.unwrap().1 == idx - 2 { + change_colors(grid, ((x, y),(get_x(bottom_right)+1, y)), color_fg , color_bg); + } else { + change_colors(grid, ((x, y),set_y(bottom_right, y)), color_fg , color_bg); + } idx += 1; } - idx + idx - 1 } } @@ -525,19 +693,22 @@ impl Component for AccountMenu { let upper_left = upper_left!(area); let bottom_right = bottom_right!(area); self.dirty = false; - let mut y = get_y(upper_left); + let mut y = get_y(upper_left) + 1; for a in &self.accounts { + eprintln!("\n\naccount: {:?}\n\n", a); y += self.print_account(grid, (set_y(upper_left, y), bottom_right), &a); } + eprintln!("\n\naccountentries: {:?}\n\n", self.accounts); context.dirty_areas.push_back(area); } fn process_event(&mut self, event: &UIEvent, _context: &mut Context) { match event.event_type { - UIEventType::RefreshMailbox(ref m) => { - self.highlight_folder(m); + UIEventType::RefreshMailbox(c) => { + self.cursor = Some(c); + self.dirty = true; }, UIEventType::ChangeMode(UIMode::Normal) => { self.dirty = true; diff --git a/src/ui/components/mod.rs b/src/ui/components/mod.rs index 29247e0fd..569b31e6f 100644 --- a/src/ui/components/mod.rs +++ b/src/ui/components/mod.rs @@ -21,6 +21,7 @@ pub mod utilities; pub mod mail; +pub mod notifications; use super::*; pub use utilities::*; diff --git a/src/ui/components/notifications.rs b/src/ui/components/notifications.rs new file mode 100644 index 000000000..61b01556e --- /dev/null +++ b/src/ui/components/notifications.rs @@ -0,0 +1,24 @@ +use notify_rust::Notification as notify_Notification; + +use ui::*; +use ui::components::*; +pub struct XDGNotifications {} + +impl Component for XDGNotifications { + fn draw(&mut self, _grid: &mut CellBuffer, _area: Area, _context: &mut Context) { + + } + fn process_event(&mut self, event: &UIEvent, _context: &mut Context) { + match event.event_type { + UIEventType::Notification(ref t) => { + notify_Notification::new() + .summary("Refresh Event") + .body(t) + .icon("dialog-information") + .show().unwrap(); + }, + _ => {} + } + } +} + diff --git a/src/ui/components/utilities.rs b/src/ui/components/utilities.rs index ca443b0c1..13c8054fa 100644 --- a/src/ui/components/utilities.rs +++ b/src/ui/components/utilities.rs @@ -126,21 +126,31 @@ pub struct Pager { } impl Pager { - pub fn new(mail: &Envelope) -> Self { - let text = mail.get_body().get_text(); + pub fn new(mail: &Envelope, pager_filter: Option) -> Self { + let mut text = mail.get_body().get_text(); + if let Some(bin) = pager_filter { + use std::io::Write; + use std::process::{Command, Stdio}; + eprintln!("{}", bin); + let mut filter_child = Command::new(bin) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("Failed to start pager filter process"); + { + let mut stdin = + filter_child.stdin.as_mut().expect("failed to open stdin"); + stdin.write_all(text.as_bytes()).expect("Failed to write to stdin"); + } + + + text = String::from_utf8_lossy(&filter_child.wait_with_output().expect("Failed to wait on filter").stdout).to_string(); + } let lines: Vec<&str> = text.trim().split('\n').collect(); let height = lines.len(); let width = lines.iter().map(|l| l.len()).max().unwrap_or(0); let mut content = CellBuffer::new(width, height, Cell::with_char(' ')); - if width > 0 { - for (i, l) in lines.iter().enumerate() { - write_string_to_grid(l, - &mut content, - Color::Default, - Color::Default, - ((0, i), (width -1, i))); - } - } + Pager::print_string(&mut content, &text); Pager { cursor_pos: 0, height: height, @@ -149,6 +159,19 @@ impl Pager { content: content, } } + pub fn print_string(content: &mut CellBuffer, s: &str) { + let lines: Vec<&str> = s.trim().split('\n').collect(); + let width = lines.iter().map(|l| l.len()).max().unwrap_or(0); + if width > 0 { + for (i, l) in lines.iter().enumerate() { + write_string_to_grid(l, + content, + Color::Default, + Color::Default, + ((0, i), (width -1, i))); + } + } + } } impl Component for Pager { @@ -163,6 +186,7 @@ impl Component for Pager { if self.height == 0 || self.height == self.cursor_pos || self.width == 0 { return; } + clear_area(grid, (upper_left, bottom_right)); context.dirty_areas.push_back((upper_left, bottom_right)); @@ -228,18 +252,20 @@ impl StatusBar { clear_area(grid, area); write_string_to_grid(&self.status, grid, - Color::Byte(36), - Color::Default, + Color::Byte(123), + Color::Byte(26), area); + change_colors(grid, area, Color::Byte(123), Color::Byte(26)); context.dirty_areas.push_back(area); } fn draw_execute_bar(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { clear_area(grid, area); write_string_to_grid(&self.ex_buffer, grid, - Color::Byte(124), - Color::Default, + Color::Byte(219), + Color::Byte(88), area); + change_colors(grid, area, Color::Byte(219), Color::Byte(88)); context.dirty_areas.push_back(area); } } @@ -279,7 +305,8 @@ impl Component for StatusBar { fn process_event(&mut self, event: &UIEvent, context: &mut Context) { self.container.rcv_event(event, context); match event.event_type { - UIEventType::RefreshMailbox(ref m) => { + UIEventType::RefreshMailbox((idx_a, idx_f)) => { + let m = &context.accounts[idx_a][idx_f].as_ref().unwrap().as_ref().unwrap(); self.status = format!("{} |Mailbox: {}, Messages: {}, New: {}", self.mode, m.folder.get_name(), m.collection.len(), m.collection.iter().filter(|e| !e.is_seen()).count()); self.dirty = true; diff --git a/src/ui/execute/mod.rs b/src/ui/execute/mod.rs new file mode 100644 index 000000000..3aebe5651 --- /dev/null +++ b/src/ui/execute/mod.rs @@ -0,0 +1,11 @@ +use std; +use nom::digit; + + +named!(usize_c, +map_res!(map_res!(ws!(digit), std::str::from_utf8), std::str::FromStr::from_str)); + +named!(pub goto, + preceded!(tag!("b "), + call!(usize_c)) + ); diff --git a/src/ui/mod.rs b/src/ui/mod.rs index fb4636a2a..d6a25b72d 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -93,12 +93,13 @@ impl From for ThreadEvent { pub enum UIEventType { Input(Key), ExInput(Key), - RefreshMailbox(Mailbox), + RefreshMailbox((usize,usize)), //Quit? Resize, ChangeMailbox(usize), ChangeMode(UIMode), Command(String), + Notification(String), } @@ -123,6 +124,13 @@ impl fmt::Display for UIMode { } } +pub struct Notification { + title: String, + content: String, + + timestamp: std::time::Instant, +} + pub struct Context { pub accounts: Vec, settings: Settings, @@ -140,6 +148,7 @@ impl Context { } } + pub struct State { cols: usize, rows: usize, @@ -169,6 +178,8 @@ impl State { let termrows = termsize.map(|(_,h)| h); let cols = termcols.unwrap_or(0) as usize; let rows = termrows.unwrap_or(0) as usize; + let mut accounts: Vec = settings.accounts.iter().map(|(n, a_s)| { Account::new(n.to_string(), a_s.clone(), &backends) }).collect(); + accounts.sort_by(|a,b| a.get_name().cmp(&b.get_name()) ); let mut s = State { cols: cols, rows: rows, @@ -178,7 +189,7 @@ impl State { entities: Vec::with_capacity(1), context: Context { - accounts: settings.accounts.iter().map(|(n, a_s)| { Account::new(n.to_string(), a_s.clone(), &backends) }).collect(), + accounts: accounts, backends: backends, settings: settings, dirty_areas: VecDeque::with_capacity(5), @@ -197,7 +208,6 @@ impl State { s } pub fn update_size(&mut self) { - /* update dimensions. TODO: Only do that in size change events. ie SIGWINCH */ let termsize = termion::terminal_size().ok(); let termcols = termsize.map(|(w,_)| w); let termrows = termsize.map(|(_,h)| h); @@ -304,17 +314,20 @@ impl State { self.entities[i].rcv_event(&event, &mut self.context); } } + /// Tries to load a mailbox's content pub fn refresh_mailbox(&mut self, account_idx: usize, folder_idx: usize) { - let mailbox = match &mut self.context.accounts[account_idx][folder_idx] { - Some(Ok(v)) => { Some(v.clone()) }, - Some(Err(e)) => { eprintln!("error {:?}", e); None }, - None => { eprintln!("None"); None }, + let flag = match &mut self.context.accounts[account_idx][folder_idx] { + Some(Ok(_)) => { + true + }, + Some(Err(e)) => { eprintln!("error {:?}", e); false }, + None => { eprintln!("None"); false }, }; - if let Some(m) = mailbox { - self.rcv_event(UIEvent { id: 0, event_type: UIEventType::RefreshMailbox(m) }); - } + if flag { + self.rcv_event(UIEvent { id: 0, event_type: UIEventType::RefreshMailbox((account_idx, folder_idx)) }); + } } }