aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer/threads.rs
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-04-28 23:53:28 +0200
committerGustav Sörnäs <gustav@sornas.net>2021-04-28 23:53:28 +0200
commit2d1c367f7754a495cb0caf05779e21ce7ba60354 (patch)
treed45ebf42ce5fa4811d04e395763a2928387ef285 /src/buffer/threads.rs
parent4a33cd02bef5fba633d99cf0e8f5ca55a25e8384 (diff)
downloadmail-2d1c367f7754a495cb0caf05779e21ce7ba60354.tar.gz
state -> buffer
Diffstat (limited to 'src/buffer/threads.rs')
-rw-r--r--src/buffer/threads.rs114
1 files changed, 114 insertions, 0 deletions
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();
+ }
+}