diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-01-14 20:51:49 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-01-14 21:03:57 +0100 |
commit | 041b25f2ec5c28fea1d2f81177a344ee0b74c32d (patch) | |
tree | 66671f88830e34397abeb2d0a72c4a9422095a32 | |
parent | 7df34288b78ffcc324acd74b3c1e0d72fbc20db8 (diff) |
Add mail view
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/mailview.rs | 80 | ||||
-rw-r--r-- | src/main.rs | 1 | ||||
-rw-r--r-- | src/main_view.rs | 44 |
4 files changed, 124 insertions, 3 deletions
@@ -19,6 +19,8 @@ env_logger = "0.7" flexi_logger = "*" getset = "0.1" handlebars = "3" +indoc = "1" +itertools = "0.10" log = "0.4" mailparse.git = "https://git.sr.ht/~matthiasbeyer/mailparse" notmuch = "0.6" diff --git a/src/mailview.rs b/src/mailview.rs new file mode 100644 index 0000000..236eea5 --- /dev/null +++ b/src/mailview.rs @@ -0,0 +1,80 @@ +use cursive::Printer; +use cursive::Rect; +use cursive::View; +use cursive::XY; +use cursive::direction::Direction; +use cursive::event::Event; +use cursive::event::EventResult; +use cursive::view::Selector; +use cursive::views::TextView; +use itertools::Itertools; + +use crate::maillist_view::MailListingData; + +pub struct MailView(TextView); + +impl MailView { + pub fn create_for(mldata: MailListingData) -> Self { + let text = indoc::formatdoc!(r#" + Id : {id} + Tags : {tags} + Date : {date} + From : {from} + To : {to} + Subject: {subject} + "#, + id = mldata.mail_id(), + tags = mldata.tags().iter().join(", "), + date = mldata.date(), + from = mldata.from(), + to = mldata.to(), + subject = mldata.subject(), + ); + MailView(TextView::new(text)) + } +} + +impl View for MailView { + fn draw(&self, printer: &Printer) { + self.0.draw(printer) + } + + fn layout(&mut self, xy: XY<usize>) { + self.0.layout(xy) + } + + fn needs_relayout(&self) -> bool { + self.0.needs_relayout() + } + + fn required_size(&mut self, constraint: XY<usize>) -> XY<usize> { + self.0.required_size(constraint) + } + + fn on_event(&mut self, e: Event) -> EventResult { + self.0.on_event(e) + } + + fn call_on_any<'a>(&mut self, s: &Selector, tpl: &'a mut (dyn FnMut(&mut (dyn View + 'static)) + 'a)) { + self.0.call_on_any(s, tpl); + } + + fn focus_view(&mut self, s: &Selector) -> Result<(), ()> { + self.0.focus_view(s) + } + + fn take_focus(&mut self, source: Direction) -> bool { + self.0.take_focus(source) + } + + fn important_area(&self, view_size: XY<usize>) -> Rect { + self.0.important_area(view_size) + } + + fn type_name(&self) -> &'static str { + self.0.type_name() + } + +} + + diff --git a/src/main.rs b/src/main.rs index ee4216e..596f2ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ mod main_view; mod mail_view; mod maillist_view; mod configuration; +mod mailview; mod util; use configuration::Configuration; diff --git a/src/main_view.rs b/src/main_view.rs index d7e7e66..bb5f478 100644 --- a/src/main_view.rs +++ b/src/main_view.rs @@ -15,11 +15,14 @@ use cursive::views::EditView; use cursive::views::NamedView; use cursive::views::ResizedView; use cursive::traits::Resizable; +use cursive_multiplex::Mux; use crate::configuration::Configuration; use crate::maillist_view::MaillistView; +use crate::maillist_view::MailListingData; pub const MAIN_VIEW_NAME: &'static str = "main_view"; +pub const MAIN_MUX_NAME: &'static str = "main_mux"; pub const MAIN_MAIL_LIST_NAME: &'static str = "main_mail_list"; pub struct MainView { @@ -65,6 +68,11 @@ impl View for MainView { } }, + Event::Key(cursive::event::Key::Enter) => { + let muxroot = self.muxroot.clone(); + EventResult::Consumed(Some(Callback::from_fn(move |siv| Self::add_mailview(siv, muxroot)))) + }, + Event::Char('o') => { EventResult::Consumed(Some(Callback::from_fn(MainView::add_notmuch_query_layer))) }, @@ -105,7 +113,7 @@ impl MainView { let dbpath = config.notmuch_database_path(); let dbquery = config.notmuch_default_query(); let mlname = MAIN_MAIL_LIST_NAME.to_string(); - let mlview = MaillistView::create_for(dbpath, dbquery, mlname)?.with_name(MAIN_MAIL_LIST_NAME); + let mlview = MaillistView::create_for(dbpath.to_path_buf(), dbquery, mlname)?.with_name(MAIN_MAIL_LIST_NAME); let view = ResizedView::new(SizeConstraint::Full, SizeConstraint::Full, mlview); let _ = tab.add_right_of(view, muxroot); @@ -114,7 +122,7 @@ impl MainView { let tabs = cursive_tabs::TabPanel::default() .with_bar_alignment(cursive_tabs::Align::Start) .with_bar_placement(cursive_tabs::Placement::HorizontalTop) - .with_tab(config.notmuch_default_query().clone(), tab); + .with_tab(config.notmuch_default_query().clone(), tab.with_name(MAIN_MUX_NAME)); Ok(MainView { config, muxroot, tabs }.with_name(MAIN_VIEW_NAME)) } @@ -137,7 +145,7 @@ impl MainView { main_view.config().notmuch_database_path().clone() }) .map(|dbpath| { - let t = MaillistView::create_for(dbpath, query, query.to_string())? + let t = MaillistView::create_for(dbpath.to_path_buf(), query, query.to_string())? .full_screen() .with_name(format!("{}-view", query)); @@ -167,4 +175,34 @@ impl MainView { }) } + fn add_mailview(siv: &mut Cursive, muxroot: cursive_multiplex::Id) { + siv.call_on_name(MAIN_MAIL_LIST_NAME, |maillist_view: &mut MaillistView| { + if let Some(ml_data) = maillist_view.item().and_then(move |idx| maillist_view.borrow_item(idx)) { + Ok(ml_data.clone()) + } else { + unimplemented!() + } + }) + .map(|maillist_item: Result<MailListingData>| { + if let Ok(mldata) = maillist_item { + let _ = siv.call_on_name(MAIN_MUX_NAME, |mux: &mut Mux| { + let _ = mux.add_right_of(crate::mailview::MailView::create_for(mldata), muxroot); // TODO handle error + }); // TODO handle error. + } else { + // do something + } + + Ok(()) + }) + .unwrap_or_else(|| { + siv.pop_layer(); + siv.add_layer(crate::util::dialog_for("Failed to get database connection set up")); + Ok(()) + }) + .unwrap_or_else(|e: anyhow::Error| { + siv.pop_layer(); + siv.add_layer(crate::util::error_dialog_for(e)) + }); + } + } |