update
This commit is contained in:
parent
e437d95b9b
commit
4e3d2e63f3
6 changed files with 31 additions and 9 deletions
|
@ -3,8 +3,7 @@
|
||||||
Panorama is a personal information manager.
|
Panorama is a personal information manager.
|
||||||
|
|
||||||
- [rustdoc autogenerated API docs][1]
|
- [rustdoc autogenerated API docs][1]
|
||||||
- [Github repository][3]
|
- [Github][3] ( [issues][4] )
|
||||||
- [Issue tracker][4]
|
|
||||||
- [Matrix chat #panorama:mozilla.org][5]
|
- [Matrix chat #panorama:mozilla.org][5]
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
|
@ -240,7 +240,7 @@ pub enum MailboxData {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||||
pub enum MailboxFlag {
|
pub enum MailboxFlag {
|
||||||
Answered,
|
Answered,
|
||||||
Flagged,
|
Flagged,
|
||||||
|
|
9
notes.md
9
notes.md
|
@ -1,12 +1,19 @@
|
||||||
design ideas
|
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
|
- 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
|
- tmux-like windows
|
||||||
- maybe some of the familiar commands? `<C-b %>` for split for ex,
|
- maybe some of the familiar commands? `<C-b %>` for split for ex,
|
||||||
- gluon for scripting language
|
- gluon for scripting language
|
||||||
- hook into some global keybinds/hooks struct
|
- 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
|
- 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 }`
|
- 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
|
this means v1 -> v2 upgrade can be done automatically but because there are _any_ pending deprecated values being used
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use chrono::{DateTime, Local};
|
use chrono::{DateTime, Local};
|
||||||
use panorama_imap::response::*;
|
use panorama_imap::response::*;
|
||||||
|
|
||||||
|
@ -8,7 +10,7 @@ pub struct EmailMetadata {
|
||||||
pub uid: Option<u32>,
|
pub uid: Option<u32>,
|
||||||
|
|
||||||
/// Whether or not this message is unread
|
/// Whether or not this message is unread
|
||||||
pub unread: Option<bool>,
|
pub unread: bool,
|
||||||
|
|
||||||
/// Date
|
/// Date
|
||||||
pub date: Option<DateTime<Local>>,
|
pub date: Option<DateTime<Local>>,
|
||||||
|
@ -27,6 +29,12 @@ impl EmailMetadata {
|
||||||
|
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
match attr {
|
match attr {
|
||||||
|
AttributeValue::Flags(flags) => {
|
||||||
|
let flags = flags.into_iter().collect::<HashSet<_>>();
|
||||||
|
if !flags.contains(&MailboxFlag::Seen) {
|
||||||
|
meta.unread = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
AttributeValue::Uid(new_uid) => meta.uid = Some(new_uid),
|
AttributeValue::Uid(new_uid) => meta.uid = Some(new_uid),
|
||||||
AttributeValue::InternalDate(new_date) => {
|
AttributeValue::InternalDate(new_date) => {
|
||||||
meta.date = Some(new_date.with_timezone(&Local));
|
meta.date = Some(new_date.with_timezone(&Local));
|
||||||
|
|
|
@ -121,13 +121,21 @@ impl MailTabState {
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.map(|meta| {
|
.map(|meta| {
|
||||||
Row::new(vec![
|
let mut row = Row::new(vec![
|
||||||
"".to_owned(),
|
String::from(if meta.unread { "\u{2b24}" } else { "" }),
|
||||||
meta.uid.map(|u| u.to_string()).unwrap_or_default(),
|
meta.uid.map(|u| u.to_string()).unwrap_or_default(),
|
||||||
meta.date.map(|d| humanize_timestamp(d)).unwrap_or_default(),
|
meta.date.map(|d| humanize_timestamp(d)).unwrap_or_default(),
|
||||||
meta.from.clone(),
|
meta.from.clone(),
|
||||||
meta.subject.clone(),
|
meta.subject.clone(),
|
||||||
])
|
]);
|
||||||
|
if meta.unread {
|
||||||
|
row = row.style(
|
||||||
|
Style::default()
|
||||||
|
.fg(Color::LightCyan)
|
||||||
|
.add_modifier(Modifier::BOLD),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
row
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ pub async fn run_ui(
|
||||||
.split(f.size());
|
.split(f.size());
|
||||||
|
|
||||||
// this is the title bar
|
// 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);
|
let tabs = Tabs::new(titles);
|
||||||
f.render_widget(tabs, chunks[0]);
|
f.render_widget(tabs, chunks[0]);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue