From 71f599d58e8641678b11f6cf8511a1f5e96d1b1d Mon Sep 17 00:00:00 2001 From: Benedikt Terhechte Date: Fri, 10 Dec 2021 21:54:23 +0100 Subject: [PATCH] Display number of mails --- README.md | 5 +++-- src/gui/app_state/import.rs | 15 ++++++++++++--- src/gui/app_state/main.rs | 9 ++++++--- src/gui/app_state/mod.rs | 13 ++++++++++--- src/gui/navigation_bar.rs | 11 ++++++++++- src/importer/message_adapter.rs | 2 ++ 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index af3ec02..d1d17f3 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,14 @@ Update: It currently parses 632115 emails in ~56 seconds, so roughly `11.000` em - [x] try re-opening a database... - [x] save config into sqlite - [x] store last opened sqlite file -- [ ] check if we get any values for the to_sender to_domain fields etc +- [x] check if we get any values for the to_sender to_domain fields etc (only to_group seemingly has no data for my mails) - [x] update to egui 15 -- [ ] add more tests +- [x] add more tests - [ ] build static linux binary via docker - [ ] try to build a static windows binary - [ ] update metadata in Cargo.toml - [ ] add app platform icons +- [ ] for many mails, the segmentations don't work correctly due to async issues ## Linux Issues diff --git a/src/gui/app_state/import.rs b/src/gui/app_state/import.rs index 7f3698a..a778f48 100644 --- a/src/gui/app_state/import.rs +++ b/src/gui/app_state/import.rs @@ -40,6 +40,8 @@ pub struct ImporterUI { progress_divisions: usize, /// we're done importing pub done_importing: bool, + /// Total amount of mails we imported + pub total_mails: usize, /// Any errors during importing pub importer_error: Option, /// On macOS, we lack the permission to the mail folder. This can be @@ -95,6 +97,7 @@ impl ImporterUI { progress_blocks, progress_divisions, done_importing: false, + total_mails: 0, importer_error: None, missing_permissions: false, }) @@ -115,6 +118,7 @@ impl StateUIVariant for ImporterUI { }, (_, true) => StateUIAction::ImportDone { config: self.config.clone(), + total: 0, }, (_, false) => StateUIAction::Nothing, } @@ -129,7 +133,7 @@ impl ImporterUI { let available = ui.available_size(); - let (label, progress, writing, done) = match self.handle_adapter() { + let (label, progress, writing, done, written) = match self.handle_adapter() { Ok(state) => { #[cfg(target_os = "macos")] if state.missing_permissions { @@ -140,14 +144,15 @@ impl ImporterUI { label, progress, writing, + written, done, .. } = state; - (label, progress, writing, done) + (label, progress, writing, done, written) } Err(e) => { // Generate a response signifying we're done - as there was an error - let response = (format!("Error {}", &e), 1.0, false, true); + let response = (format!("Error {}", &e), 1.0, false, true, 0); self.importer_error = Some(e); response } @@ -163,6 +168,7 @@ impl ImporterUI { self.importer_error = handle.join().ok().map(|e| e.err()).flatten(); } self.done_importing = true; + self.total_mails = written; } let n = (self.progress_blocks.len() as f32 * progress) as usize; @@ -280,6 +286,7 @@ struct InternalAdapterState { label: String, progress: f32, writing: bool, + written: usize, done: bool, #[cfg(target_os = "macos")] missing_permissions: bool, @@ -309,6 +316,7 @@ impl ImporterUI { let State { done, finishing, + written, #[cfg(target_os = "macos")] missing_permissions, } = self.adapter.finished()?; @@ -320,6 +328,7 @@ impl ImporterUI { label, progress, writing, + written, done, #[cfg(target_os = "macos")] missing_permissions, diff --git a/src/gui/app_state/main.rs b/src/gui/app_state/main.rs index 09cb5ac..b133ede 100644 --- a/src/gui/app_state/main.rs +++ b/src/gui/app_state/main.rs @@ -22,10 +22,11 @@ pub struct MainUI { error: Option, state: UIState, filter_state: FilterState, + total: usize, } impl MainUI { - pub fn new(config: Config) -> Result { + pub fn new(config: Config, total: usize) -> Result { let mut engine = Engine::new(&config)?; engine.start()?; Ok(Self { @@ -34,6 +35,7 @@ impl MainUI { error: None, state: UIState::default(), filter_state: FilterState::new(), + total, }) } } @@ -55,7 +57,7 @@ impl StateUIVariant for MainUI { .fill(platform_colors.window_background) .stroke(Stroke::none()); - egui::TopBottomPanel::top("my_panel") + egui::TopBottomPanel::top("panel") .frame(frame) .show(ctx, |ui| { ui.add(super::super::navigation_bar::NavigationBar::new( @@ -63,11 +65,12 @@ impl StateUIVariant for MainUI { &mut self.error, &mut self.state, &mut self.filter_state, + self.total, )); }); if self.state.show_emails { - egui::SidePanel::right("my_left_panel") + egui::SidePanel::right("left_panel") .default_width(500.0) .show(ctx, |ui| { ui.add(super::super::mail_panel::MailPanel::new( diff --git a/src/gui/app_state/mod.rs b/src/gui/app_state/mod.rs index fa084b5..a0f0da4 100644 --- a/src/gui/app_state/mod.rs +++ b/src/gui/app_state/mod.rs @@ -27,6 +27,7 @@ pub enum StateUIAction { }, ImportDone { config: Config, + total: usize, }, Close { config: Config, @@ -77,8 +78,8 @@ impl StateUI { StateUIAction::OpenDatabase { database_path } => { *self = self.open_database(database_path) } - StateUIAction::ImportDone { config } => { - *self = match main::MainUI::new(config.clone()) { + StateUIAction::ImportDone { config, total } => { + *self = match main::MainUI::new(config.clone(), total) { Ok(n) => StateUI::Main(n), Err(e) => StateUI::Error(ErrorUI::new(e, Some(config.clone()))), }; @@ -122,7 +123,13 @@ impl StateUI { Err(report) => return StateUI::Error(error::ErrorUI::new(report, None)), }; - match main::MainUI::new(config.clone()) { + let total = + match crate::database::Database::new(&database_path).and_then(|db| db.total_mails()) { + Ok(config) => config, + Err(report) => return StateUI::Error(error::ErrorUI::new(report, None)), + }; + + match main::MainUI::new(config.clone(), total) { Ok(n) => StateUI::Main(n), Err(e) => StateUI::Error(ErrorUI::new(e, Some(config.clone()))), } diff --git a/src/gui/navigation_bar.rs b/src/gui/navigation_bar.rs index cbec696..e170ca4 100644 --- a/src/gui/navigation_bar.rs +++ b/src/gui/navigation_bar.rs @@ -1,6 +1,7 @@ use crate::model::Engine; -use eframe::egui::{self, Color32, Widget}; +use eframe::egui::{self, Color32, Label, Widget}; use eyre::Report; +use num_format::{Locale, ToFormattedString}; use super::app_state::UIState; use super::platform::navigation_button; @@ -12,6 +13,7 @@ pub struct NavigationBar<'a> { error: &'a mut Option, state: &'a mut UIState, filter_state: &'a mut FilterState, + total_mails: usize, } impl<'a> NavigationBar<'a> { @@ -20,12 +22,14 @@ impl<'a> NavigationBar<'a> { error: &'a mut Option, state: &'a mut UIState, filter_state: &'a mut FilterState, + total_mails: usize, ) -> Self { NavigationBar { engine, error, state, filter_state, + total_mails, } } } @@ -58,6 +62,11 @@ impl<'a> Widget for NavigationBar<'a> { ui.add(FilterPanel::new(self.engine, self.filter_state, self.error)); }); + ui.add(Label::new(format!( + "{} Mails", + self.total_mails.to_formatted_string(&Locale::en) + ))); + // This is a hack to get right-alignment. // we can't size the button, we can only size text. We will size text // and then use ~that for these buttons diff --git a/src/importer/message_adapter.rs b/src/importer/message_adapter.rs index e1a0690..1b31672 100644 --- a/src/importer/message_adapter.rs +++ b/src/importer/message_adapter.rs @@ -30,6 +30,7 @@ pub struct Progress { pub struct State { pub finishing: bool, pub done: bool, + pub written: usize, #[cfg(target_os = "macos")] pub missing_permissions: bool, } @@ -129,6 +130,7 @@ impl Adapter { Ok(State { finishing: item.finishing, done: item.done, + written: item.total_write, #[cfg(target_os = "macos")] missing_permissions: item.missing_permissions, })