From 4e3d2e63f368f38d86c4f7cfdc593ca42d024d89 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 10 Mar 2021 05:07:08 -0600 Subject: [PATCH] update --- docs/src/intro.md | 3 +-- imap/src/response.rs | 2 +- notes.md | 9 ++++++++- src/mail/metadata.rs | 10 +++++++++- src/ui/mail_tab.rs | 14 +++++++++++--- src/ui/mod.rs | 2 +- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/docs/src/intro.md b/docs/src/intro.md index 988e981..f634e79 100644 --- a/docs/src/intro.md +++ b/docs/src/intro.md @@ -3,8 +3,7 @@ Panorama is a personal information manager. - [rustdoc autogenerated API docs][1] -- [Github repository][3] -- [Issue tracker][4] +- [Github][3] ( [issues][4] ) - [Matrix chat #panorama:mozilla.org][5] ## Quick Start diff --git a/imap/src/response.rs b/imap/src/response.rs index 16faeaf..345d31f 100644 --- a/imap/src/response.rs +++ b/imap/src/response.rs @@ -240,7 +240,7 @@ pub enum MailboxData { }, } -#[derive(Debug, Eq, PartialEq, Clone)] +#[derive(Debug, Eq, PartialEq, Clone, Hash)] pub enum MailboxFlag { Answered, Flagged, diff --git a/notes.md b/notes.md index 89e9daa..640040f 100644 --- a/notes.md +++ b/notes.md @@ -1,12 +1,19 @@ design ideas --- -- instead of dumb search with `/`, have like an omnibar with recency info built in? +- instead of dumb search, have like an omnibar with recency info built in? - this requires some kind of cache and text search +- mail view has like a "filter stack" + - initially, this is empty, but when u do `/` u can add stuff like `acct:personal`, or `date<2020-03` or `has:attachment` or `from:*@gmail.com` + - then, when u hit enter, it gets added to a stack and u can like pop off filters + - example wld be liek `[acct:personal] [is:unread] [subject:"(?i)*github*"]` and then when u pop off the filter u just get `[acct:personal] [is:unread]` - tmux-like windows - maybe some of the familiar commands? `` for split for ex, - gluon for scripting language - hook into some global keybinds/hooks struct + - need commands: + - create dir + - move email to dir - transparent self-updates?? this could work with some kind of deprecation scheme for the config files - for ex: v1 has `{ x: Int }`, v2 has `{ [deprecated] x: Int, x2: Float }` and v3 has `{ x2: Float }` this means v1 -> v2 upgrade can be done automatically but because there are _any_ pending deprecated values being used diff --git a/src/mail/metadata.rs b/src/mail/metadata.rs index 85f29b5..bf657ad 100644 --- a/src/mail/metadata.rs +++ b/src/mail/metadata.rs @@ -1,3 +1,5 @@ +use std::collections::HashSet; + use chrono::{DateTime, Local}; use panorama_imap::response::*; @@ -8,7 +10,7 @@ pub struct EmailMetadata { pub uid: Option, /// Whether or not this message is unread - pub unread: Option, + pub unread: bool, /// Date pub date: Option>, @@ -27,6 +29,12 @@ impl EmailMetadata { for attr in attrs { match attr { + AttributeValue::Flags(flags) => { + let flags = flags.into_iter().collect::>(); + if !flags.contains(&MailboxFlag::Seen) { + meta.unread = true; + } + } AttributeValue::Uid(new_uid) => meta.uid = Some(new_uid), AttributeValue::InternalDate(new_date) => { meta.date = Some(new_date.with_timezone(&Local)); diff --git a/src/ui/mail_tab.rs b/src/ui/mail_tab.rs index d6b8b0b..9b87371 100644 --- a/src/ui/mail_tab.rs +++ b/src/ui/mail_tab.rs @@ -121,13 +121,21 @@ impl MailTabState { .iter() .rev() .map(|meta| { - Row::new(vec![ - "".to_owned(), + let mut row = Row::new(vec![ + String::from(if meta.unread { "\u{2b24}" } else { "" }), meta.uid.map(|u| u.to_string()).unwrap_or_default(), meta.date.map(|d| humanize_timestamp(d)).unwrap_or_default(), meta.from.clone(), meta.subject.clone(), - ]) + ]); + if meta.unread { + row = row.style( + Style::default() + .fg(Color::LightCyan) + .add_modifier(Modifier::BOLD), + ); + } + row }) .collect::>(); diff --git a/src/ui/mod.rs b/src/ui/mod.rs index ef1ae3c..e8e16ff 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -78,7 +78,7 @@ pub async fn run_ui( .split(f.size()); // this is the title bar - let titles = vec!["panorama mail"].into_iter().map(Spans::from).collect(); + let titles = vec!["email"].into_iter().map(Spans::from).collect(); let tabs = Tabs::new(titles); f.render_widget(tabs, chunks[0]);