diff --git a/melib/Cargo.toml b/melib/Cargo.toml index edb71bcd4..19c9c0f7f 100644 --- a/melib/Cargo.toml +++ b/melib/Cargo.toml @@ -5,19 +5,19 @@ authors = [] workspace = ".." [dependencies] -notify = "4.0.1" -notify-rust = "^3" -crossbeam = "^0.3.0" -fnv = "1.0.3" -config = "0.6" -xdg = "2.1.0" +bitflags = "1.0" +chan = "0.1.21" chrono = "0.4" -serde_derive = "^1.0.8" -serde = "^1.0.8" -nom = "3.2.0" -memmap = "0.5.2" +config = "0.6" +crossbeam = "^0.3.0" data-encoding = "2.1.1" encoding = "0.2.33" -bitflags = "1.0" +fnv = "1.0.3" +memmap = "0.5.2" +nom = "3.2.0" +notify = "4.0.1" +notify-rust = "^3" +serde = "^1.0.8" +serde_derive = "^1.0.8" termion = "1.5.1" -chan = "0.1.21" +xdg = "2.1.0" diff --git a/src/bin.rs b/src/bin.rs index fdd5f4c11..97552895c 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -215,6 +215,9 @@ fn main() { state.rcv_event(UIEvent { id: 0, event_type: e}); state.render(); }, + ThreadEvent::ThreadJoin(id) => { + state.join(id); + }, } }, signal.recv() -> signal => { diff --git a/ui/Cargo.toml b/ui/Cargo.toml index 972fe4424..dbcf0b535 100644 --- a/ui/Cargo.toml +++ b/ui/Cargo.toml @@ -5,14 +5,14 @@ authors = [] workspace = ".." [dependencies] -melib = { path = "../melib", version = "*" } -termion = "1.5.1" chan = "0.1.21" +chan-signal = "0.3.1" +fnv = "1.0.3" +linkify = "0.3.1" +melib = { path = "../melib", version = "*" } +mime_apps = { path = "../../mime_apps", version = "*" } +nom = "3.2.0" notify = "4.0.1" notify-rust = "^3" -nom = "3.2.0" -chan-signal = "0.3.1" -mime_apps = { path = "../../mime_apps", version = "*" } - +termion = "1.5.1" uuid = { version = "0.6", features = ["serde", "v4"] } -linkify = "0.3.1" diff --git a/ui/src/components/mail/mod.rs b/ui/src/components/mail/mod.rs index c19a1b11a..04d785f6b 100644 --- a/ui/src/components/mail/mod.rs +++ b/ui/src/components/mail/mod.rs @@ -44,7 +44,7 @@ impl AccountMenu { cursor: None, } } - fn print_account(&self, grid: &mut CellBuffer, area: Area, a: &AccountMenuEntry) -> usize { + fn print_account(&self, grid: &mut CellBuffer, area: Area, a: &AccountMenuEntry, context: &mut Context) -> usize { if !is_valid_area!(area) { eprintln!("BUG: invalid area in print_account"); } @@ -86,25 +86,38 @@ impl AccountMenu { entries: &Vec<(usize, Folder)>, s: &mut String, inc: &mut usize, - ) -> () { + index: usize, //account index + context: &mut Context, + ) -> () { let len = s.len(); - s.insert_str(len, &format!("{} {}\n ", *inc, &entries[root].1.name())); + match context.accounts[index].status(root) { + Ok(()) => {}, + Err(_) => { + return; + // TODO: Show progress visually + } + } + let count = context.accounts[index][root].as_ref().unwrap().collection.iter().filter(|e| !e.is_seen()).count(); + s.insert_str(len, &format!("{} {} {}\n ", *inc, &entries[root].1.name(), count)); *inc += 1; let children_no = entries[root].1.children().len(); for (idx, child) in entries[root].1.children().iter().enumerate() { let len = s.len(); s.insert_str(len, &format!("{}├─", depth)); push(depth, if idx == children_no - 1 { '│' } else { ' ' }); - print(*child, parents, depth, entries, s, inc); + print(*child, parents, depth, entries, s, inc, index, context); pop(depth); } } for r in roots { - print(r, &parents, &mut depth, &a.entries, &mut s, &mut inc); + print(r, &parents, &mut depth, &a.entries, &mut s, &mut inc, a.index, context); } let lines: Vec<&str> = s.lines().collect(); let lines_len = lines.len(); + if lines_len < 2 { + return 0; + } let mut idx = 0; for y in get_y(upper_left)..get_y(bottom_right) { if idx == lines_len { @@ -115,24 +128,14 @@ impl AccountMenu { } else { format!("{}", lines[idx]) }; - let color_fg = if highlight { + let (color_fg, color_bg) = if highlight { if idx > 1 && self.cursor.unwrap().1 == idx - 2 { - Color::Byte(233) + (Color::Byte(233), Color::Byte(15)) } else { - Color::Byte(15) + (Color::Byte(15), Color::Byte(233)) } } 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 + (Color::Default, Color::Default) }; let (x, _) = write_string_to_grid( @@ -175,7 +178,7 @@ impl Component for AccountMenu { self.dirty = false; let mut y = get_y(upper_left); for a in &self.accounts { - y += self.print_account(grid, (set_y(upper_left, y), bottom_right), &a); + y += self.print_account(grid, (set_y(upper_left, y), bottom_right), &a, context); } context.dirty_areas.push_back(area); diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 1aa5f1270..3fe6ea021 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -57,6 +57,8 @@ use std::fmt; use std::io::Write; use std::thread; use std::time; +extern crate fnv; +use self::fnv::FnvHashMap; extern crate termion; use termion::event::Key as TermionKey; use termion::input::TermRead; @@ -73,6 +75,7 @@ use chan::Sender; /// to the main process. #[derive(Debug)] pub enum ThreadEvent { + ThreadJoin(thread::ThreadId), /// User input. Input(Key), /// A watched folder has been refreshed. @@ -191,7 +194,9 @@ pub struct State { entities: Vec, pub context: Context, - startup_thread: Option<(chan::Sender, thread::JoinHandle<()>)>, + startup_thread: Option>, + + threads: FnvHashMap>, } impl Drop for State { @@ -231,6 +236,8 @@ impl State { let (startup_tx, startup_rx) = chan::async(); let startup_thread = { let sender = sender.clone(); + let startup_rx = startup_rx.clone(); + thread::Builder::new() .name("startup-thread".to_string()) .spawn(move || { @@ -239,6 +246,7 @@ impl State { chan_select! { default => {}, startup_rx.recv() -> _ => { + sender.send(ThreadEvent::ThreadJoin(thread::current().id())); return; } } @@ -267,8 +275,10 @@ impl State { input_thread: input_thread, }, - startup_thread: Some((startup_tx, startup_thread)), + startup_thread: Some(startup_tx), + threads: FnvHashMap::with_capacity_and_hasher(1, Default::default()), }; + s.threads.insert(startup_thread.thread().id(), startup_thread); write!( s.stdout(), "{}{}{}", @@ -284,6 +294,12 @@ impl State { }))); } s + } + pub fn join(&mut self, id: thread::ThreadId) { + let handle = self.threads.remove(&id).unwrap(); + handle.join().unwrap(); + + } pub fn finish_startup(&mut self) { // TODO: Encode startup process with the type system if possible @@ -291,9 +307,8 @@ impl State { return; } { - let (tx, handle) = self.startup_thread.take().unwrap(); + let tx = self.startup_thread.take().unwrap(); tx.send(true); - handle.join().unwrap(); } } pub fn to_main_screen(&mut self) {