diff options
Diffstat (limited to 'src/maillist_view.rs')
-rw-r--r-- | src/maillist_view.rs | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/src/maillist_view.rs b/src/maillist_view.rs index aaf36c4..d20c37d 100644 --- a/src/maillist_view.rs +++ b/src/maillist_view.rs @@ -8,20 +8,28 @@ 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::ResizedView; +use cursive::views::NamedView; use cursive_table_view::TableView; use cursive_table_view::TableViewItem; use chrono::naive::NaiveDateTime; use notmuch::Message; use notmuch::MessageOwner; -pub struct MaillistView(TableView<MailListingData, MailListingColumn>); +use crate::main_view::MainView; +use crate::mail_view::MailView; + +pub struct MaillistView { + view: TableView<MailListingData, MailListingColumn>, + database_path: PathBuf, +} impl MaillistView { - pub fn create_for(database_path: &PathBuf, query: &str, name: String) -> Result<Self> { + 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 { @@ -36,16 +44,17 @@ impl MaillistView { } } - let items = notmuch::Database::open(database_path, notmuch::DatabaseMode::ReadOnly) + 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 tags = msg.tags().collect(); - let date = NaiveDateTime::from_timestamp_opt(msg.date(), 0) + 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()); @@ -59,6 +68,7 @@ impl MaillistView { Ok(MailListingData { mail_id, + filename, tags, date, from, @@ -70,6 +80,8 @@ impl MaillistView { .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 tab = TableView::<MailListingData, MailListingColumn>::new() .column(MailListingColumn::Date, "Date", |c| c.width(20)) .column(MailListingColumn::Tags, "Tags", |c| c.width(20)) @@ -80,58 +92,77 @@ impl MaillistView { .items(items) .selected_item(0) .on_submit(move |siv: &mut Cursive, row: usize, _: usize| { - let mail_id = siv.call_on_name(&name, move |table: &mut ResizedView<TableView<MailListingData, MailListingColumn>>| { - table.get_inner_mut() + let (mail_id, filename) = siv.call_on_name(&n, move |table: &mut MaillistView| { + table.view .borrow_item(row) - .map(|data| data.mail_id.clone()) + .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(); + + siv.call_on_name(crate::main_view::MAIN_VIEW_NAME, move |main_view: &mut MainView| { + let name = format!("{}-{}", n, mail_id); + debug!("Creating MailView '{}' for {} ({}) in {}", name, mail_id, filename.display(), db_path.display()); + let mv = MailView::create_for(db_path, mail_id, filename, name.clone()).unwrap(); + + main_view.add_tab(name, mv); }); // use the mail ID to get the whole thread and open it as a table item }); - Ok(MaillistView(tab)) + Ok(MaillistView{ view: tab, database_path }.with_name(name)) } } impl View for MaillistView { fn draw(&self, printer: &Printer) { - self.0.draw(printer) + self.view.draw(printer) } fn layout(&mut self, xy: XY<usize>) { - self.0.layout(xy) + self.view.layout(xy) } fn needs_relayout(&self) -> bool { - self.0.needs_relayout() + self.view.needs_relayout() } fn required_size(&mut self, constraint: XY<usize>) -> XY<usize> { - self.0.required_size(constraint) + self.view.required_size(constraint) } fn on_event(&mut self, e: Event) -> EventResult { - self.0.on_event(e) + 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.0.call_on_any(s, tpl); + self.view.call_on_any(s, tpl); } fn focus_view(&mut self, s: &Selector) -> Result<(), ()> { - self.0.focus_view(s) + self.view.focus_view(s) } fn take_focus(&mut self, source: Direction) -> bool { - self.0.take_focus(source) + self.view.take_focus(source) } fn important_area(&self, view_size: XY<usize>) -> Rect { - self.0.important_area(view_size) + self.view.important_area(view_size) } fn type_name(&self) -> &'static str { - self.0.type_name() + self.view.type_name() } } @@ -148,6 +179,7 @@ pub enum MailListingColumn { #[derive(Clone, Debug)] pub struct MailListingData { mail_id: String, + filename: PathBuf, tags: Vec<String>, date: String, from: String, |