diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2021-01-22 18:41:38 +0100 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2021-01-22 18:41:38 +0100 |
commit | 9008d4bd4643a9e32db9172b2c3b93b0a19a34ce (patch) | |
tree | 45c8e201f80c52016bbc4b67ad25adf74bc8ca37 /src/maillist_view.rs | |
parent | 4988103be43ee441833f71e4467d260c7df70e7c (diff) |
Move views to submodule
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src/maillist_view.rs')
-rw-r--r-- | src/maillist_view.rs | 240 |
1 files changed, 0 insertions, 240 deletions
diff --git a/src/maillist_view.rs b/src/maillist_view.rs deleted file mode 100644 index 3de8e9f..0000000 --- a/src/maillist_view.rs +++ /dev/null @@ -1,240 +0,0 @@ -use std::path::PathBuf; -use std::ops::Deref; - -use anyhow::Result; -use anyhow::Context; -use cursive::Cursive; -use cursive::Printer; -use cursive::Rect; -use cursive::View; -use cursive::XY; -use cursive::direction::Direction; -use cursive::view::Nameable; -use cursive::view::Selector; -use cursive::event::Event; -use cursive::event::EventResult; -use cursive::views::NamedView; -use cursive_table_view::TableView; -use cursive_table_view::TableViewItem; -use chrono::naive::NaiveDateTime; -use notmuch::Message; -use notmuch::MessageOwner; -use getset::Getters; -use cursive::views::ResizedView; -use cursive::view::SizeConstraint; - -use crate::main_view::MainView; -use crate::mail_view::MailView; - -pub struct MaillistView { - view: ResizedView<TableView<MailListingData, MailListingColumn>>, -} - -impl Deref for MaillistView { - type Target = TableView<MailListingData, MailListingColumn>; - fn deref(&self) -> &Self::Target { - self.view.get_inner() - } -} - -impl MaillistView { - pub fn create_for(database_path: PathBuf, query: &str, name: String) -> Result<NamedView<Self>> { - debug!("Getting '{}' from '{}'", query, database_path.display()); - - fn get_header_field_save<'o, O: MessageOwner + 'o>(msg: &Message<'o, O>, field: &str) -> String { - match msg.header(field) { - Err(e) => { - error!("Failed getting '{}' of '{}': {}", field, msg.id(), e); - String::from("---") - }, - - Ok(None) => format!("No Value for {}", field), - Ok(Some(f)) => f.to_string(), - } - } - - let items = notmuch::Database::open(&database_path, notmuch::DatabaseMode::ReadOnly) - .context(format!("Opening database {}", database_path.display()))? - .create_query(query) - .context("Creating the search query")? - .search_messages() - .context(format!("Searching for messages with '{}'", query))? - .map(|msg| { - let mail_id = msg.id().to_string(); - let filename = msg.filename(); - let tags = msg.tags().collect(); - let date = NaiveDateTime::from_timestamp_opt(msg.date(), 0) - .map(|ndt| ndt.to_string()) - .ok_or_else(|| { - error!("Failed to parse timestamp: {}", msg.date()); - anyhow!("Failed to parse timestamp: {}", msg.date()) - }) - .context(format!("Getting the date of message {}", msg.id()))?; - - let from = get_header_field_save(&msg, "From"); - let to = get_header_field_save(&msg, "To"); - let subject = get_header_field_save(&msg, "Subject"); - - Ok(MailListingData { - mail_id, - filename, - tags, - date, - from, - to, - subject, - }) - }) - .collect::<Result<Vec<_>>>() - .context(format!("Creating MaillinglistView for '{}' on {}", query, database_path.display()))?; - - debug!("Found {} entries", items.len()); - let n = name.clone(); - let db_path = database_path.clone(); - let view = TableView::<MailListingData, MailListingColumn>::new() - .column(MailListingColumn::Date, "Date", |c| c.width(20)) - .column(MailListingColumn::Tags, "Tags", |c| c.width(20)) - .column(MailListingColumn::From, "From", |c| c) - .column(MailListingColumn::To, "To", |c| c) - .column(MailListingColumn::Subject, "Subject", |c| c) - .default_column(MailListingColumn::Date) - .items(items) - .selected_item(0) - .on_submit(move |siv: &mut Cursive, row: usize, _: usize| { - let (mail_id, filename) = siv.call_on_name(&n, move |table: &mut MaillistView| { - table.view - .get_inner_mut() - .borrow_item(row) - .map(|data| { - debug!("Opening: {:?}", data); - (data.mail_id.clone(), data.filename.clone()) - }) - }) - .unwrap() - .unwrap(); - - debug!("Showing mail {}", mail_id); - - // Why do I have to do this? This is UGLY! - let n = n.clone(); - let db_path = db_path.clone(); - let name = format!("{}-{}", n, mail_id); - let mv = MailView::create_for(db_path, mail_id, filename, name).unwrap(); - - siv.call_on_name(crate::main_view::MAIN_MUX_NAME, move |mux: &mut cursive_multiplex::Mux| { - mux.add_right_of(mv, mux.root().build().unwrap()); - }); - - // use the mail ID to get the whole thread and open it as a table item - }); - - Ok(MaillistView { view: ResizedView::new(SizeConstraint::Full, SizeConstraint::Full, view )}.with_name(name)) - } - - pub fn borrow_item(&mut self, idx: usize) -> Option<&MailListingData> { - self.view.get_inner_mut().borrow_item(idx) - } -} - -impl View for MaillistView { - fn draw(&self, printer: &Printer) { - self.view.draw(printer) - } - - fn layout(&mut self, xy: XY<usize>) { - self.view.layout(xy) - } - - fn needs_relayout(&self) -> bool { - self.view.needs_relayout() - } - - fn required_size(&mut self, constraint: XY<usize>) -> XY<usize> { - self.view.required_size(constraint) - } - - fn on_event(&mut self, e: Event) -> EventResult { - self.view.on_event(e) - } - - fn call_on_any<'a>(&mut self, s: &Selector, tpl: &'a mut (dyn FnMut(&mut (dyn View + 'static)) + 'a)) { - self.view.call_on_any(s, tpl); - } - - fn focus_view(&mut self, s: &Selector) -> Result<(), ()> { - self.view.focus_view(s) - } - - fn take_focus(&mut self, source: Direction) -> bool { - self.view.take_focus(source) - } - - fn important_area(&self, view_size: XY<usize>) -> Rect { - self.view.important_area(view_size) - } - - fn type_name(&self) -> &'static str { - self.view.type_name() - } - -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub enum MailListingColumn { - Date, - Tags, - From, - To, - Subject, -} - -#[derive(Clone, Debug, Getters)] -pub struct MailListingData { - #[getset(get = "pub")] - mail_id: String, - - #[getset(get = "pub")] - filename: PathBuf, - - #[getset(get = "pub")] - tags: Vec<String>, - - #[getset(get = "pub")] - date: String, - - #[getset(get = "pub")] - from: String, - - #[getset(get = "pub")] - to: String, - - #[getset(get = "pub")] - subject: String, -} - -impl TableViewItem<MailListingColumn> for MailListingData { - - fn to_column(&self, column: MailListingColumn) -> String { - match column { - MailListingColumn::Date => self.date.clone(), - MailListingColumn::Tags => self.tags.join(", "), - MailListingColumn::From => self.from.clone(), - MailListingColumn::To => self.to.clone(), - MailListingColumn::Subject => self.subject.clone(), - } - } - - fn cmp(&self, other: &Self, column: MailListingColumn) -> std::cmp::Ordering - where Self: Sized - { - match column { - MailListingColumn::Date => self.date.cmp(&other.date), - MailListingColumn::Tags => self.tags.cmp(&other.tags), - MailListingColumn::From => self.from.cmp(&other.from), - MailListingColumn::To => self.to.cmp(&other.to), - MailListingColumn::Subject => self.subject.cmp(&other.subject), - } - } - -} - |