diff options
author | Matthias Beyer <mail@beyermatthias.de> | 2020-07-07 13:36:25 +0200 |
---|---|---|
committer | Matthias Beyer <mail@beyermatthias.de> | 2020-07-07 17:20:11 +0200 |
commit | 757e22b8a78b994431a32114280f7752e4705f74 (patch) | |
tree | ffc0b878de487f69d292fb013eff6ee40e695602 /src | |
parent | 434c66a517f086e24f1885cfff04fe8c00bd98a7 (diff) |
Implement tab with cursive-async-view::AsyncView
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/main_view.rs | 94 | ||||
-rw-r--r-- | src/sidebar.rs | 24 |
2 files changed, 66 insertions, 52 deletions
diff --git a/src/main_view.rs b/src/main_view.rs index 883e9b1..9048fb2 100644 --- a/src/main_view.rs +++ b/src/main_view.rs @@ -1,5 +1,6 @@ use std::path::PathBuf; use std::ffi::OsStr; +use std::result::Result as RResult; use anyhow::Result; use cursive::{View, Printer, XY, direction::Direction, view::Selector, Rect, event::Event, event::EventResult}; use cursive::view::Nameable; @@ -9,7 +10,6 @@ use mailparse::MailHeaderMap; use mailparse::ParsedMail; use async_std::sync::channel; -use crate::loadinglist::list::LoadingList; use crate::mailstore::{ MailStore, Mail }; pub const MAIN_VIEW_NAME: &'static str = "main_view"; @@ -69,57 +69,53 @@ impl MainView { MainView { tabs }.with_name(MAIN_VIEW_NAME) } - pub fn load_maildir(&mut self, pb: PathBuf) -> Result<()> { - use crate::loadinglist::list::RowGenerator; - use crate::loadinglist::list::State; - #[derive(Debug, Clone)] - struct Data { - date: String, - from: String, - to: String, - subject: String, - } - #[derive(Debug)] - struct Generator; - impl RowGenerator<Data> for Generator { - type Output = cursive::views::TextView; - fn generate_row(&self, data: Data) -> Self::Output { - cursive::views::TextView::new(format!("{} {} {} {}", data.date, data.from, data.to, data.subject)) - } - } - - debug!("Loading: {}", pb.display()); - let name = pb.file_name() - .and_then(OsStr::to_str) - .map(String::from) - .ok_or_else(|| anyhow!("UTF8 error"))?; - - let (sender, receiver) = channel(1000); - let generator = Generator; - let list_view = LoadingList::new(receiver, generator); - self.tabs.add_tab(name, list_view.with_name("Tab")); - - async_std::task::spawn(async move { - debug!("Loading: {}", pb.display()); - let r = MailStore::build_from_path(pb.clone()) - .inspect(|mail| { - let mail = mail.as_ref().unwrap(); - debug!("Loaded: {:?}", mail.parsed()); - let date = mail.parsed().headers.get_first_value("Date").unwrap_or_else(|| String::from("No date")); - let from = mail.parsed().headers.get_first_value("From").unwrap_or_else(|| String::from("No From")); - let to = mail.parsed().headers.get_first_value("To").unwrap_or_else(|| String::from("No To")); - let subject = mail.parsed().headers.get_first_value("Subject").unwrap_or_else(|| String::from("No Subject")); - - let maildata = Data { date, from, to, subject }; - let s = sender.clone(); - async_std::task::spawn(async move { s.send(State::processing(maildata)).await; }); - }) - .collect::<Result<MailStore>>(); - }); - Ok(()) + pub fn maildir_loader(&mut self, pb: PathBuf) -> (MaildirLoader, MaildirLoaderPostProcessor) { + debug!("Creating Loader for: {}", pb.display()); + let maildir_loader = MaildirLoader { maildir_path: pb }; + let postprocessor = MaildirLoaderPostProcessor; + (maildir_loader, postprocessor) } + pub fn add_tab<T: View>(&mut self, id: String, view: T) { + self.tabs.add_tab(id, view) + } + +} + +pub struct MaildirLoader { + maildir_path: PathBuf } +impl MaildirLoader { + pub fn load(self) -> RResult<Vec<String>, String> { + debug!("Loading: {}", self.maildir_path.display()); + MailStore::build_from_path(self.maildir_path).collect::<Result<MailStore>>() + .map(|store| { + store.cur_mail() + .iter() + .chain(store.new_mail().iter()) + .map(|mail| { + debug!("Loaded: {:?}", mail.parsed()); + let date = mail.parsed().headers.get_first_value("Date").unwrap_or_else(|| String::from("No date")); + let from = mail.parsed().headers.get_first_value("From").unwrap_or_else(|| String::from("No From")); + let to = mail.parsed().headers.get_first_value("To").unwrap_or_else(|| String::from("No To")); + let subject = mail.parsed().headers.get_first_value("Subject").unwrap_or_else(|| String::from("No Subject")); + + format!("{} {} {} {}", date, from, to, subject) + }) + .collect() + }) + .map_err(|e| e.to_string()) + } +} +pub struct MaildirLoaderPostProcessor; +impl MaildirLoaderPostProcessor { + pub fn postprocess(&self, list: Vec<String>) -> cursive::views::ListView { + list.into_iter() + .fold(cursive::views::ListView::new(), |view, elem| { + view.child("", cursive::views::TextView::new(elem)) + }) + } +} diff --git a/src/sidebar.rs b/src/sidebar.rs index 16627e4..d0427d5 100644 --- a/src/sidebar.rs +++ b/src/sidebar.rs @@ -47,16 +47,34 @@ impl Sidebar { tv.insert_item(item, cursive_tree_view::Placement::After, i); }); - tv.set_on_submit(|siv: &mut Cursive, row: usize| { + tv.set_on_submit(|mut siv: &mut Cursive, row: usize| { let borrow = siv.call_on_name(SIDEBAR_VIEW_NAME, move |tree: &mut TreeView<TreeEntry>| { tree.borrow_item(row).map(|b| b.path.clone()) }) .flatten(); if let Some(path) = borrow { + let (loader, processor) = { + let p = path.clone(); + siv.call_on_name(crate::main_view::MAIN_VIEW_NAME, move |main_view: &mut MainView| { + Some(main_view.maildir_loader(p)) + }) + .unwrap() + .unwrap() + }; + + let list_view = cursive_async_view::AsyncView::new_with_bg_creator(&mut siv, + move || { loader.load() }, + move |list| { processor.postprocess(list) }); + + let name = path.file_name() + .and_then(OsStr::to_str) + .map(String::from) + .ok_or_else(|| anyhow!("UTF8 error")) + .unwrap(); + siv.call_on_name(crate::main_view::MAIN_VIEW_NAME, move |main_view: &mut MainView| { - main_view.load_maildir(path).unwrap(); - None as Option<()> + Some(main_view.add_tab(name, list_view)) }); } }); |