summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-01-14 20:51:49 +0100
committerMatthias Beyer <mail@beyermatthias.de>2021-01-14 21:03:57 +0100
commit041b25f2ec5c28fea1d2f81177a344ee0b74c32d (patch)
tree66671f88830e34397abeb2d0a72c4a9422095a32
parent7df34288b78ffcc324acd74b3c1e0d72fbc20db8 (diff)
Add mail view
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--Cargo.toml2
-rw-r--r--src/mailview.rs80
-rw-r--r--src/main.rs1
-rw-r--r--src/main_view.rs44
4 files changed, 124 insertions, 3 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 8709e72..2a60db3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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))
+ });
+ }
+
}