diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-04-28 23:53:28 +0200 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-04-28 23:53:28 +0200 |
| commit | 2d1c367f7754a495cb0caf05779e21ce7ba60354 (patch) | |
| tree | d45ebf42ce5fa4811d04e395763a2928387ef285 /src/buffer | |
| parent | 4a33cd02bef5fba633d99cf0e8f5ca55a25e8384 (diff) | |
| download | mail-2d1c367f7754a495cb0caf05779e21ce7ba60354.tar.gz | |
state -> buffer
Diffstat (limited to 'src/buffer')
| -rw-r--r-- | src/buffer/mod.rs | 47 | ||||
| -rw-r--r-- | src/buffer/threads.rs | 114 |
2 files changed, 161 insertions, 0 deletions
diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs new file mode 100644 index 0000000..fe83a97 --- /dev/null +++ b/src/buffer/mod.rs @@ -0,0 +1,47 @@ +mod threads; + +use std::io::{Stdin, Write}; +use termion::event::Key; +use termion::input::TermRead; + +pub use threads::Threads; + +pub struct Client { + buffers: Vec<Buffer>, +} + +impl Client { + pub fn new(initial_buffer: Buffer) -> Self { + Self { + buffers: vec![initial_buffer], + } + } + + pub fn run<W: Write>(mut self, mut screen: W, stdin: Stdin) { + for c in stdin.keys() { + let c = c.unwrap(); + // Global keybinds + match c { + Key::Char('q') => { + self.buffers.pop().unwrap(); + if self.buffers.is_empty() { + break; + } + }, + _ => () + } + + let next_buffer = match self.buffers.last_mut().unwrap() { + Buffer::Threads(s) => s.tick(&mut screen, c), + }; + + if let Some(next_buffer) = next_buffer { + self.buffers.push(next_buffer); + } + } + } +} + +pub enum Buffer { + Threads(Threads), +} diff --git a/src/buffer/threads.rs b/src/buffer/threads.rs new file mode 100644 index 0000000..ddef067 --- /dev/null +++ b/src/buffer/threads.rs @@ -0,0 +1,114 @@ +use crate::db; +use super::Buffer; + +use notmuch::DatabaseMode; +use std::io::Write; +use termion::{color, event::Key}; + +pub struct Threads { + threads: Vec<Thread>, + i: usize, + + query: String, +} + +pub struct Thread { + subject: String, + authors: Vec<String>, + _id: String, + messages: Vec<String>, +} + +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 reload(&mut self) { + self.threads = db::open(DatabaseMode::ReadOnly) + .unwrap() + .create_query(&self.query) + .unwrap() + .search_threads() + .unwrap() + .map(Thread::new) + .collect(); + } + + pub fn init<W: Write>(&self, out: &mut W) { + self.draw(out); + } + + pub fn tick<W: Write>(&mut self, out: &mut W, key: Key) -> Option<Buffer> { + 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"); + } + Key::Char('s') => { + let sent = Threads::from_query(String::from("tag:sent")); + sent.init(out); + 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.draw(out); + None + } + + fn draw<W: Write>(&self, out: &mut W) { + write!(out, "{}", termion::clear::All).unwrap(); + + for (i, thread) in self.threads.iter().enumerate() { + write!(out, "{}", termion::cursor::Goto(1, (i + 1) as u16)).unwrap(); + let highlight = i == self.i; + if highlight { + write!(out, "{}", color::Fg(color::Red)).unwrap(); + } + write!(out, "thread {:?}, {:?}", thread.subject, thread.authors).unwrap(); + if highlight { + write!(out, "{}", color::Fg(color::Reset)).unwrap(); + } + } + out.flush().unwrap(); + } +} |
