use crate::db; use crate::window::{Line, Window}; use super::Buffer; use notmuch::DatabaseMode; use termion::event::Key; pub struct Threads { threads: Vec, i: usize, query: String, } pub struct Thread { subject: String, authors: Vec, _id: String, messages: Vec, } impl<'d, 'q> Thread { pub fn new(thread: notmuch::Thread<'d, 'q>) -> Self { Self { subject: thread.subject().to_string(), authors: thread.authors().clone(), _id: thread.id().to_string(), messages: thread.messages().map(|m| m.id().to_string()).collect(), } } pub fn remove_tag(&self, tag: &str) { let db = db::open(DatabaseMode::ReadWrite).unwrap(); for m_id in self.messages.iter() { db .find_message(m_id) .unwrap() .unwrap() .remove_tag(tag) .unwrap(); } } } impl Threads { pub fn from_query(query: String) -> Self { let mut res = Self { threads: Vec::new(), i: 0, query, }; res.reload(); res } pub fn name(&self) -> String { format!("threads: '{}'", self.query) } pub fn reload(&mut self) { self.threads = db::open(DatabaseMode::ReadOnly) .unwrap() .create_query(&self.query) .unwrap() .search_threads() .unwrap() .map(Thread::new) .collect(); } pub fn fill_window(&self, window: &mut Window) { println!("filling"); for (i, thread) in self.threads.iter().enumerate() { let s = format!("thread: \'{}\' {:?}", thread.subject, thread.authors); window.lines.push( if self.i == i { Line::Highlight(s) } else { Line::Normal(s) } ); } } pub fn tick(&mut self, window: &mut Window, key: Key) -> Option { match key { Key::Char('j') => self.i += 1, Key::Char('k') => self.i = if self.i == 0 { self.threads.len() } else { self.i - 1 }, Key::Char('i') => { self.threads[self.i].remove_tag("inbox"); self.i += 1; } Key::Char('s') => { let sent = Threads::from_query(String::from("tag:sent")); sent.fill_window(window); return Some(Buffer::Threads(sent)); } Key::Char('r') => self.reload(), _ => (), } if !self.threads.is_empty() { self.i = self.i.rem_euclid(self.threads.len()); } self.fill_window(window); None } }