mirror of
https://github.com/FliegendeWurst/inboxid.git
synced 2024-11-21 16:34:59 +00:00
browse: mark mails as read or unread
This commit is contained in:
parent
95b6abc572
commit
480987bf6c
@ -1,6 +1,6 @@
|
||||
#![feature(internal_output_capture)]
|
||||
|
||||
use std::{array::IntoIter, cell::RefCell, cmp, collections::{HashMap, HashSet}, env, fmt::Display, io, sync::{Arc, Mutex}};
|
||||
use std::{cell::RefCell, cmp, collections::{HashMap, HashSet}, env, fmt::Display, io, sync::{Arc, Mutex}};
|
||||
|
||||
use cursive::{Cursive, CursiveExt, Vec2};
|
||||
use cursive::align::HAlign;
|
||||
@ -11,6 +11,7 @@ use cursive::views::{Checkbox, LinearLayout, OnEventView, Panel, ResizedView, Se
|
||||
use cursive_tree_view::{Placement, TreeEntry, TreeView};
|
||||
use inboxid::*;
|
||||
use io::Write;
|
||||
use imap::types::Flag;
|
||||
use itertools::Itertools;
|
||||
use log::error;
|
||||
use mailparse::{MailHeaderMap, ParsedMail};
|
||||
@ -41,7 +42,8 @@ fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
fn show_listing(mailbox: &str) -> Result<()> {
|
||||
let maildir = get_maildir(mailbox)?;
|
||||
let maildir = Box::leak(Box::new(get_maildir(mailbox)?));
|
||||
let maildir = &*maildir;
|
||||
|
||||
let mut mails = Vec::new();
|
||||
for x in maildir.list_cur() {
|
||||
@ -51,24 +53,6 @@ fn show_listing(mailbox: &str) -> Result<()> {
|
||||
let mut mails = maildir.get_mails2(mails)?;
|
||||
mails.sort_by_key(|x| x.date);
|
||||
let mails = Box::leak(Box::new(mails.into_iter().map(Box::new).map(Box::leak).collect_vec()));
|
||||
|
||||
let mut rows = Vec::new();
|
||||
for (i, mail) in mails.iter().enumerate() {
|
||||
let flags = &mail.flags;
|
||||
let mut flags_display = String::new();
|
||||
if flags.contains('F') {
|
||||
flags_display.push('+');
|
||||
}
|
||||
if flags.contains('R') {
|
||||
flags_display.push('R');
|
||||
}
|
||||
if flags.contains('S') {
|
||||
flags_display.push(' ');
|
||||
} else {
|
||||
flags_display.push('*');
|
||||
}
|
||||
rows.push(IntoIter::new([(mails.len() - i).to_string(), flags_display, mail.from(), mail.subject.clone(), mail.date_iso.clone()]));
|
||||
}
|
||||
|
||||
let mut mails_by_id = HashMap::new();
|
||||
let mut threads: HashMap<_, Vec<_>> = HashMap::new();
|
||||
@ -179,7 +163,7 @@ fn show_listing(mailbox: &str) -> Result<()> {
|
||||
(false, 0)
|
||||
};
|
||||
let tree_on_select = |siv: &mut Cursive, row| {
|
||||
let item = siv.call_on_name("tree", |tree: &mut TreeView<&EasyMail>| {
|
||||
let item = siv.call_on_name("tree", |tree: &mut MailTreeView| {
|
||||
*tree.borrow_item(row).unwrap()
|
||||
}).unwrap();
|
||||
if item.is_pseudo() {
|
||||
@ -226,13 +210,13 @@ fn show_listing(mailbox: &str) -> Result<()> {
|
||||
}
|
||||
part_to_display
|
||||
}).unwrap() {
|
||||
siv.call_on_name("mail_info", |view: &mut MailInfoView| {
|
||||
view.set(item);
|
||||
});
|
||||
siv.call_on_name("mail", |view: &mut TextView| {
|
||||
view.set_content(mail.get_body().unwrap());
|
||||
});
|
||||
}
|
||||
siv.call_on_name("mail_info", |view: &mut MailInfoView| {
|
||||
view.set(item);
|
||||
});
|
||||
};
|
||||
tree.set_on_select(tree_on_select);
|
||||
tree.set_on_submit(|siv, _row| {
|
||||
@ -240,6 +224,27 @@ fn show_listing(mailbox: &str) -> Result<()> {
|
||||
});
|
||||
let mut tree = tree.with_name("tree").scrollable();
|
||||
tree.set_scroll_strategy(ScrollStrategy::StickToBottom);
|
||||
let tree = OnEventView::new(tree)
|
||||
.on_event('r', move |siv| {
|
||||
siv.call_on_name("tree", |tree: &mut MailTreeView| {
|
||||
if let Some(r) = tree.row() {
|
||||
let mail = tree.borrow_item_mut(r).unwrap();
|
||||
mail.add_flag(Flag::Seen);
|
||||
mail.remove_flag2('U');
|
||||
let _ = mail.save_flags(&maildir);
|
||||
}
|
||||
});
|
||||
})
|
||||
.on_event('u', move |siv| {
|
||||
siv.call_on_name("tree", |tree: &mut MailTreeView| {
|
||||
if let Some(r) = tree.row() {
|
||||
let mail = tree.borrow_item_mut(r).unwrap();
|
||||
mail.remove_flag(Flag::Seen);
|
||||
mail.add_flag2('U');
|
||||
let _ = mail.save_flags(&maildir);
|
||||
}
|
||||
});
|
||||
});
|
||||
let tree_resized = ResizedView::new(SizeConstraint::AtMost(120), SizeConstraint::Free, tree);
|
||||
let mail_info = MailInfoView::new().with_name("mail_info");
|
||||
let mail_content = TextView::new("").with_name("mail").scrollable();
|
||||
@ -321,6 +326,8 @@ fn show_listing(mailbox: &str) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
type MailTreeView<'a> = TreeView<&'a EasyMail<'a>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct MailPart {
|
||||
part: &'static ParsedMail<'static>
|
||||
|
@ -27,7 +27,7 @@ fn show_listing(mailbox: &str) -> Result<()> {
|
||||
|
||||
let mut rows = Vec::new();
|
||||
for (i, mail) in mails.iter().enumerate() {
|
||||
let flags = &mail.flags;
|
||||
let flags = &mail.get_flags();
|
||||
let mut flags_display = String::new();
|
||||
if flags.contains('F') {
|
||||
flags_display.push('+');
|
||||
|
@ -29,7 +29,7 @@ fn main() -> Result<()> {
|
||||
if message_id.is_empty() {
|
||||
message_id = format!("<{}_{}_{}@no-message-id>", mailbox, mail.id.uid_validity, mail.id.uid);
|
||||
}
|
||||
save_mail.execute(params![&mailbox, mail.id.to_i64(), message_id, mail.flags])?;
|
||||
save_mail.execute(params![&mailbox, mail.id.to_i64(), message_id, mail.get_flags()])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
48
src/lib.rs
48
src/lib.rs
@ -105,7 +105,7 @@ impl MaildirID {
|
||||
pub struct EasyMail<'a> {
|
||||
mail: Option<ParsedMail<'a>>,
|
||||
pub id: MaildirID,
|
||||
pub flags: String,
|
||||
flags: RwLock<String>,
|
||||
from: Option<SingleInfo>,
|
||||
from_raw: String,
|
||||
pub subject: String,
|
||||
@ -118,7 +118,7 @@ impl EasyMail<'_> {
|
||||
Self {
|
||||
mail: None,
|
||||
id: MaildirID::new(0, 0),
|
||||
flags: "S".to_owned(),
|
||||
flags: "S".to_owned().into(),
|
||||
from: None,
|
||||
from_raw: String::new(),
|
||||
subject,
|
||||
@ -145,6 +145,36 @@ impl EasyMail<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_flag(&self, flag: &Flag) -> bool {
|
||||
self.flags.read().contains(imap_flag_to_maildir(flag).unwrap())
|
||||
}
|
||||
|
||||
pub fn add_flag(&self, flag: Flag) {
|
||||
self.flags.write().push(imap_flag_to_maildir(&flag).unwrap());
|
||||
}
|
||||
|
||||
pub fn add_flag2(&self, flag: char) {
|
||||
self.flags.write().push(flag);
|
||||
}
|
||||
|
||||
pub fn remove_flag(&self, flag: Flag) {
|
||||
self.remove_flag2(imap_flag_to_maildir(&flag).unwrap());
|
||||
}
|
||||
|
||||
pub fn remove_flag2(&self, flag: char) {
|
||||
let mut f = self.flags.write();
|
||||
*f = f.replace(flag, "");
|
||||
}
|
||||
|
||||
pub fn save_flags(&self, maildir: &Maildir) -> Result<()> {
|
||||
maildir.set_flags(&self.id.to_string(), &self.flags.read())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_flags(&self) -> String {
|
||||
self.flags.read().clone()
|
||||
}
|
||||
|
||||
pub fn get_header(&self, header: &str) -> String {
|
||||
self.get_headers().get_all_values(header).join(" ")
|
||||
}
|
||||
@ -217,7 +247,7 @@ impl TreeEntry for &EasyMail<'_> {
|
||||
line.push(' ');
|
||||
line += &self.date_iso;
|
||||
|
||||
let style = if self.flags.contains('S') { Style::default() } else { CONFIG.get().unwrap().read().browse.unread_style };
|
||||
let style = if self.has_flag(&Flag::Seen) { Style::default() } else { CONFIG.get().unwrap().read().browse.unread_style };
|
||||
let spans = vec![
|
||||
IndexedSpan {
|
||||
content: IndexedCow::Borrowed {
|
||||
@ -341,7 +371,7 @@ impl MaildirExtension for Maildir {
|
||||
)?;
|
||||
mails.push(EasyMail {
|
||||
mail: Some(mail),
|
||||
flags,
|
||||
flags: flags.into(),
|
||||
id,
|
||||
from,
|
||||
from_raw,
|
||||
@ -370,7 +400,7 @@ impl MaildirExtension for Maildir {
|
||||
)?;
|
||||
mails.push(EasyMail {
|
||||
mail: Some(mail),
|
||||
flags,
|
||||
flags: flags.into(),
|
||||
id,
|
||||
from,
|
||||
from_raw,
|
||||
@ -563,3 +593,11 @@ pub fn imap_flags_to_maildir(mut f: String, flags: &[Flag]) -> String {
|
||||
}
|
||||
f
|
||||
}
|
||||
|
||||
pub fn imap_flag_to_maildir(flag: &Flag) -> Option<char> {
|
||||
match flag {
|
||||
Flag::Seen => Some('S'),
|
||||
Flag::Answered => Some('R'),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user