melib,ui: add MailboxEntry enum
Use an enum to describe a mailbox's state in ui::conf::Account instead of Result.embed
parent
5b679be782
commit
8a0e702127
|
@ -106,13 +106,10 @@ impl Collection {
|
|||
}
|
||||
}
|
||||
/* envelope is not in threads, so insert it */
|
||||
let env = self.envelopes.entry(new_hash).or_default() as *mut Envelope;
|
||||
unsafe {
|
||||
self.threads
|
||||
.entry(folder_hash)
|
||||
.or_default()
|
||||
.insert(&mut (*env), &self.envelopes);
|
||||
}
|
||||
self.threads
|
||||
.entry(folder_hash)
|
||||
.or_default()
|
||||
.insert(&mut self.envelopes, new_hash);
|
||||
for (h, t) in self.threads.iter_mut() {
|
||||
if *h == folder_hash {
|
||||
continue;
|
||||
|
@ -127,7 +124,7 @@ impl Collection {
|
|||
&mut self,
|
||||
mut envelopes: FnvHashMap<EnvelopeHash, Envelope>,
|
||||
folder_hash: FolderHash,
|
||||
mailbox: &mut Result<Mailbox>,
|
||||
mailbox: &mut Mailbox,
|
||||
sent_folder: Option<FolderHash>,
|
||||
) {
|
||||
self.sent_folder = sent_folder;
|
||||
|
@ -135,9 +132,7 @@ impl Collection {
|
|||
if self.message_ids.contains_key(e.message_id().raw()) {
|
||||
/* skip duplicates until a better way to handle them is found. */
|
||||
//FIXME
|
||||
if let Ok(mailbox) = mailbox.as_mut() {
|
||||
mailbox.remove(h);
|
||||
}
|
||||
mailbox.remove(h);
|
||||
false
|
||||
} else {
|
||||
self.message_ids.insert(e.message_id().raw().to_vec(), h);
|
||||
|
@ -214,13 +209,10 @@ impl Collection {
|
|||
}
|
||||
}
|
||||
/* envelope is not in threads, so insert it */
|
||||
let env = self.envelopes.entry(new_hash).or_default() as *mut Envelope;
|
||||
unsafe {
|
||||
self.threads
|
||||
.entry(folder_hash)
|
||||
.or_default()
|
||||
.insert(&mut (*env), &self.envelopes);
|
||||
}
|
||||
self.threads
|
||||
.entry(folder_hash)
|
||||
.or_default()
|
||||
.insert(&mut self.envelopes, new_hash);
|
||||
for (h, t) in self.threads.iter_mut() {
|
||||
if *h == folder_hash {
|
||||
continue;
|
||||
|
@ -236,10 +228,17 @@ impl Collection {
|
|||
self.message_ids
|
||||
.insert(envelope.message_id().raw().to_vec(), hash);
|
||||
self.envelopes.insert(hash, envelope);
|
||||
self.threads
|
||||
if !self
|
||||
.threads
|
||||
.entry(folder_hash)
|
||||
.or_default()
|
||||
.insert_reply(&mut self.envelopes, hash);
|
||||
.insert_reply(&mut self.envelopes, hash)
|
||||
{
|
||||
self.threads
|
||||
.entry(folder_hash)
|
||||
.or_default()
|
||||
.insert(&mut self.envelopes, hash);
|
||||
}
|
||||
&self.envelopes[&hash]
|
||||
}
|
||||
pub fn insert_reply(&mut self, env_hash: EnvelopeHash) {
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
use crate::backends::Folder;
|
||||
pub use crate::email::*;
|
||||
use crate::error::Result;
|
||||
use crate::thread::ThreadHash;
|
||||
|
||||
pub use crate::thread::{SortField, SortOrder, ThreadNode, Threads};
|
||||
|
@ -47,19 +46,15 @@ pub struct Mailbox {
|
|||
}
|
||||
|
||||
impl Mailbox {
|
||||
pub fn new(
|
||||
folder: Folder,
|
||||
envelopes: Result<&FnvHashMap<EnvelopeHash, Envelope>>,
|
||||
) -> Result<Mailbox> {
|
||||
let envelopes = envelopes?;
|
||||
pub fn new(folder: Folder, envelopes: &FnvHashMap<EnvelopeHash, Envelope>) -> Mailbox {
|
||||
let name = folder.name().into();
|
||||
let envelopes = envelopes.keys().cloned().collect();
|
||||
Ok(Mailbox {
|
||||
Mailbox {
|
||||
folder,
|
||||
name,
|
||||
envelopes,
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
|
|
|
@ -938,12 +938,7 @@ impl Threads {
|
|||
new_hash_set.difference(&self.hash_set).cloned().collect();
|
||||
for h in difference {
|
||||
debug!("inserting {}", envelopes[&h].subject());
|
||||
let env = envelopes.entry(h).or_default() as *mut Envelope;
|
||||
unsafe {
|
||||
// `envelopes` is borrowed immutably and `insert` only changes the envelope's
|
||||
// `thread` field.
|
||||
self.insert(&mut (*env), envelopes);
|
||||
}
|
||||
self.insert(envelopes, h);
|
||||
}
|
||||
self.create_root_set(envelopes);
|
||||
|
||||
|
@ -953,10 +948,10 @@ impl Threads {
|
|||
tree.retain(|t| root_set.contains(&t.id));
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, envelope: &mut Envelope, envelopes: &Envelopes) {
|
||||
self.link_envelope(envelope);
|
||||
pub fn insert(&mut self, envelopes: &mut Envelopes, env_hash: EnvelopeHash) {
|
||||
self.link_envelope(envelopes.get_mut(&env_hash).unwrap());
|
||||
{
|
||||
let id = self.message_ids[envelope.message_id().raw()];
|
||||
let id = self.message_ids[envelopes[&env_hash].message_id().raw()];
|
||||
self.rebuild_thread(id, envelopes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ impl Composer {
|
|||
context: &Context,
|
||||
) -> Self {
|
||||
let account = &context.accounts[coordinates.0];
|
||||
let mailbox = &account[coordinates.1].as_ref().unwrap();
|
||||
let mailbox = &account[coordinates.1].unwrap();
|
||||
let threads = &account.collection.threads[&mailbox.folder.hash()];
|
||||
let thread_nodes = &threads.thread_nodes();
|
||||
let mut ret = Composer::default();
|
||||
|
|
|
@ -532,12 +532,16 @@ impl Listing {
|
|||
Ok(_) => {
|
||||
let account = &context.accounts[index];
|
||||
let count = account[entries[&folder_idx].hash()]
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.envelopes
|
||||
.iter()
|
||||
.map(|h| &account.collection[&h])
|
||||
.filter(|e| !e.is_seen())
|
||||
.filter_map(|h| {
|
||||
if account.collection[&h].is_seen() {
|
||||
None
|
||||
} else {
|
||||
Some(())
|
||||
}
|
||||
})
|
||||
.count();
|
||||
let len = s.len();
|
||||
s.insert_str(
|
||||
|
|
|
@ -539,13 +539,14 @@ impl CompactListing {
|
|||
// Get mailbox as a reference.
|
||||
//
|
||||
match context.accounts[self.cursor_pos.0].status(folder_hash) {
|
||||
Ok(_) => {}
|
||||
Ok(()) => {}
|
||||
Err(_) => {
|
||||
let message: String = context.accounts[self.cursor_pos.0][folder_hash].to_string();
|
||||
self.data_columns.columns[0] =
|
||||
CellBuffer::new("Loading.".len(), 1, Cell::with_char(' '));
|
||||
CellBuffer::new(message.len(), 1, Cell::with_char(' '));
|
||||
self.length = 0;
|
||||
write_string_to_grid(
|
||||
"Loading.",
|
||||
message.as_str(),
|
||||
&mut self.data_columns.columns[0],
|
||||
Color::Default,
|
||||
Color::Default,
|
||||
|
@ -562,7 +563,7 @@ impl CompactListing {
|
|||
}
|
||||
|
||||
let account = &context.accounts[self.cursor_pos.0];
|
||||
let mailbox = account[self.cursor_pos.1].as_ref().unwrap();
|
||||
let mailbox = &account[self.cursor_pos.1].unwrap();
|
||||
|
||||
let threads = &account.collection.threads[&mailbox.folder.hash()];
|
||||
self.order.clear();
|
||||
|
@ -778,7 +779,11 @@ impl CompactListing {
|
|||
return;
|
||||
}
|
||||
let account = &context.accounts[self.cursor_pos.0];
|
||||
let mailbox = account[self.cursor_pos.1].as_ref().unwrap();
|
||||
let mailbox = if account[self.cursor_pos.1].is_available() {
|
||||
account[self.cursor_pos.1].unwrap()
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
||||
let threads = &account.collection.threads[&mailbox.folder.hash()];
|
||||
self.length = 0;
|
||||
|
@ -913,10 +918,7 @@ impl CompactListing {
|
|||
}
|
||||
fn get_envelope_under_cursor(&self, cursor: usize, context: &Context) -> EnvelopeHash {
|
||||
let account = &context.accounts[self.cursor_pos.0];
|
||||
let folder_hash = account[self.cursor_pos.1]
|
||||
.as_ref()
|
||||
.map(|m| m.folder.hash())
|
||||
.unwrap();
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
let threads = &account.collection.threads[&folder_hash];
|
||||
if self.filtered_selection.is_empty() {
|
||||
let thread_node = threads.root_set(cursor);
|
||||
|
@ -1035,10 +1037,7 @@ impl Component for CompactListing {
|
|||
.thread()
|
||||
.clone()
|
||||
};
|
||||
let folder_hash = account[self.cursor_pos.1]
|
||||
.as_ref()
|
||||
.map(|m| m.folder.hash())
|
||||
.unwrap();
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
let threads = &account.collection.threads[&folder_hash];
|
||||
let root_thread_index = threads.root_iter().position(|t| t == thread_hash);
|
||||
if let Some(pos) = root_thread_index {
|
||||
|
@ -1168,10 +1167,7 @@ impl Component for CompactListing {
|
|||
let i = self.get_envelope_under_cursor(self.cursor_pos.2, context);
|
||||
let account = &mut context.accounts[self.cursor_pos.0];
|
||||
let thread_hash = account.get_env(&i).thread();
|
||||
let folder_hash = account[self.cursor_pos.1]
|
||||
.as_ref()
|
||||
.map(|m| m.folder.hash())
|
||||
.unwrap();
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
let threads = account.collection.threads.entry(folder_hash).or_default();
|
||||
let thread_group = threads.thread_nodes()[&thread_hash].thread_group();
|
||||
let thread_group = threads.find(thread_group);
|
||||
|
|
|
@ -266,10 +266,11 @@ impl PlainListing {
|
|||
match context.accounts[self.cursor_pos.0].status(folder_hash) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
self.content = CellBuffer::new(MAX_COLS, 1, Cell::with_char(' '));
|
||||
let message: String = context.accounts[self.cursor_pos.0][folder_hash].to_string();
|
||||
self.content = CellBuffer::new(message.len(), 1, Cell::with_char(' '));
|
||||
self.length = 0;
|
||||
write_string_to_grid(
|
||||
"Loading.",
|
||||
message.as_str(),
|
||||
&mut self.content,
|
||||
Color::Default,
|
||||
Color::Default,
|
||||
|
@ -280,7 +281,7 @@ impl PlainListing {
|
|||
}
|
||||
}
|
||||
let account = &context.accounts[self.cursor_pos.0];
|
||||
let mailbox = &account[self.cursor_pos.1].as_ref().unwrap();
|
||||
let mailbox = &account[self.cursor_pos.1].unwrap();
|
||||
|
||||
self.length = mailbox.len();
|
||||
self.content = CellBuffer::new(MAX_COLS, self.length + 1, Cell::with_char(' '));
|
||||
|
|
|
@ -137,9 +137,11 @@ impl ListingTrait for ThreadListing {
|
|||
}
|
||||
|
||||
fn highlight_line(&mut self, grid: &mut CellBuffer, area: Area, idx: usize, context: &Context) {
|
||||
let mailbox = &context.accounts[self.cursor_pos.0][self.cursor_pos.1]
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let mailbox = if context.accounts[self.cursor_pos.0][self.cursor_pos.1].is_available() {
|
||||
context.accounts[self.cursor_pos.0][self.cursor_pos.1].unwrap()
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
if mailbox.is_empty() || mailbox.len() <= idx {
|
||||
return;
|
||||
}
|
||||
|
@ -222,10 +224,11 @@ impl ThreadListing {
|
|||
match context.accounts[self.cursor_pos.0].status(folder_hash) {
|
||||
Ok(_) => {}
|
||||
Err(_) => {
|
||||
self.content = CellBuffer::new(MAX_COLS, 1, Cell::with_char(' '));
|
||||
let message: String = context.accounts[self.cursor_pos.0][folder_hash].to_string();
|
||||
self.content = CellBuffer::new(message.len(), 1, Cell::with_char(' '));
|
||||
self.length = 0;
|
||||
write_string_to_grid(
|
||||
"Loading.",
|
||||
message.as_str(),
|
||||
&mut self.content,
|
||||
Color::Default,
|
||||
Color::Default,
|
||||
|
@ -236,7 +239,7 @@ impl ThreadListing {
|
|||
}
|
||||
}
|
||||
let account = &context.accounts[self.cursor_pos.0];
|
||||
let mailbox = account[self.cursor_pos.1].as_ref().unwrap();
|
||||
let mailbox = account[self.cursor_pos.1].unwrap();
|
||||
|
||||
let threads = &account.collection.threads[&mailbox.folder.hash()];
|
||||
self.length = threads.len();
|
||||
|
@ -328,9 +331,11 @@ impl ThreadListing {
|
|||
}
|
||||
|
||||
fn highlight_line_self(&mut self, idx: usize, context: &Context) {
|
||||
let mailbox = &context.accounts[self.cursor_pos.0][self.cursor_pos.1]
|
||||
.as_ref()
|
||||
.unwrap();
|
||||
let mailbox = if context.accounts[self.cursor_pos.0][self.cursor_pos.1].is_available() {
|
||||
context.accounts[self.cursor_pos.0][self.cursor_pos.1].unwrap()
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
if mailbox.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ impl ThreadView {
|
|||
fn initiate(&mut self, expanded_hash: Option<ThreadHash>, context: &Context) {
|
||||
/* stack to push thread messages in order in order to pop and print them later */
|
||||
let account = &context.accounts[self.coordinates.0];
|
||||
let mailbox = &account[self.coordinates.1].as_ref().unwrap();
|
||||
let mailbox = &account[self.coordinates.1].unwrap();
|
||||
let threads = &account.collection.threads[&mailbox.folder.hash()];
|
||||
|
||||
let thread_iter = threads.thread_iter(self.coordinates.2);
|
||||
|
@ -607,7 +607,7 @@ impl ThreadView {
|
|||
/* First draw the thread subject on the first row */
|
||||
let y = if self.dirty {
|
||||
let account = &context.accounts[self.coordinates.0];
|
||||
let mailbox = &account[self.coordinates.1].as_ref().unwrap();
|
||||
let mailbox = &account[self.coordinates.1].unwrap();
|
||||
let threads = &account.collection.threads[&mailbox.folder.hash()];
|
||||
let thread_node = &threads.thread_nodes()[&threads.root_set(self.coordinates.2)];
|
||||
let i = if let Some(i) = thread_node.message() {
|
||||
|
@ -688,7 +688,7 @@ impl ThreadView {
|
|||
/* First draw the thread subject on the first row */
|
||||
let y = {
|
||||
let account = &context.accounts[self.coordinates.0];
|
||||
let mailbox = &account[self.coordinates.1].as_ref().unwrap();
|
||||
let mailbox = &account[self.coordinates.1].unwrap();
|
||||
let threads = &account.collection.threads[&mailbox.folder.hash()];
|
||||
let thread_node = &threads.thread_nodes()[&threads.root_set(self.coordinates.2)];
|
||||
let i = if let Some(i) = thread_node.message() {
|
||||
|
@ -904,7 +904,7 @@ impl Component for ThreadView {
|
|||
UIEvent::Input(Key::Char('e')) => {
|
||||
{
|
||||
let account = &context.accounts[self.coordinates.0];
|
||||
let mailbox = &account[self.coordinates.1].as_ref().unwrap();
|
||||
let mailbox = &account[self.coordinates.1].unwrap();
|
||||
let threads = &account.collection.threads[&mailbox.folder.hash()];
|
||||
let thread_node =
|
||||
&threads.thread_nodes()[&threads.root_set(self.coordinates.2)];
|
||||
|
|
|
@ -921,7 +921,7 @@ impl Component for StatusBar {
|
|||
}
|
||||
}
|
||||
let account = &context.accounts[*idx_a];
|
||||
let m = &account[*idx_f].as_ref().unwrap();
|
||||
let m = &account[*idx_f].unwrap();
|
||||
self.status = format!(
|
||||
"{} | Mailbox: {}, Messages: {}, New: {}",
|
||||
self.mode,
|
||||
|
|
|
@ -46,24 +46,75 @@ use std::ops::{Index, IndexMut};
|
|||
use std::result;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub type Worker = Option<Async<(Result<FnvHashMap<EnvelopeHash, Envelope>>, Result<Mailbox>)>>;
|
||||
pub type Worker = Option<Async<Result<(FnvHashMap<EnvelopeHash, Envelope>, Mailbox)>>>;
|
||||
|
||||
macro_rules! mailbox {
|
||||
($idx:expr, $folders:expr) => {
|
||||
$folders
|
||||
.get_mut(&$idx)
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
$folders.get_mut(&$idx).unwrap().unwrap_mut()
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
pub enum MailboxEntry {
|
||||
Available(Mailbox),
|
||||
Failed(MeliError),
|
||||
/// first argument is done work, and second is total work
|
||||
Parsing(usize, usize),
|
||||
/// first argument is done work, and second is total work
|
||||
Threading(usize, usize),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for MailboxEntry {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
MailboxEntry::Available(ref m) => m.name().to_string(),
|
||||
MailboxEntry::Failed(ref e) => e.to_string(),
|
||||
MailboxEntry::Parsing(done, total) => {
|
||||
format!("Parsing messages. [{}/{}]", done, total)
|
||||
}
|
||||
MailboxEntry::Threading(done, total) => {
|
||||
format!("Calculating threads. [{}/{}]", done, total)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
impl MailboxEntry {
|
||||
pub fn is_available(&self) -> bool {
|
||||
if let MailboxEntry::Available(_) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
pub fn is_parsing(&self) -> bool {
|
||||
if let MailboxEntry::Parsing(_, _) = self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
pub fn unwrap_mut(&mut self) -> &mut Mailbox {
|
||||
match self {
|
||||
MailboxEntry::Available(ref mut m) => m,
|
||||
e => panic!(format!("mailbox is not available! {:#}", e)),
|
||||
}
|
||||
}
|
||||
pub fn unwrap(&self) -> &Mailbox {
|
||||
match self {
|
||||
MailboxEntry::Available(ref m) => m,
|
||||
e => panic!(format!("mailbox is not available! {:#}", e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Account {
|
||||
name: String,
|
||||
pub(crate) folders: FnvHashMap<FolderHash, Option<Result<Mailbox>>>,
|
||||
pub(crate) folders: FnvHashMap<FolderHash, MailboxEntry>,
|
||||
pub(crate) folders_order: Vec<FolderHash>,
|
||||
folder_names: FnvHashMap<FolderHash, String>,
|
||||
tree: Vec<FolderNode>,
|
||||
|
@ -113,31 +164,21 @@ impl Drop for Account {
|
|||
|
||||
pub struct MailboxIterator<'a> {
|
||||
folders_order: &'a [FolderHash],
|
||||
folders: &'a FnvHashMap<FolderHash, Option<Result<Mailbox>>>,
|
||||
folders: &'a FnvHashMap<FolderHash, MailboxEntry>,
|
||||
pos: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for MailboxIterator<'a> {
|
||||
type Item = Option<&'a Mailbox>;
|
||||
type Item = &'a MailboxEntry;
|
||||
|
||||
fn next(&mut self) -> Option<Option<&'a Mailbox>> {
|
||||
fn next(&mut self) -> Option<&'a MailboxEntry> {
|
||||
if self.pos == self.folders.len() {
|
||||
return None;
|
||||
}
|
||||
let fh = &self.folders_order[self.pos];
|
||||
|
||||
if self.pos == self.folders.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.pos += 1;
|
||||
if self.folders[&fh].is_none() {
|
||||
return Some(None);
|
||||
}
|
||||
if let Some(Err(_)) = self.folders[&fh] {
|
||||
return Some(None);
|
||||
}
|
||||
Some(Some(self.folders[&fh].as_ref().unwrap().as_ref().unwrap()))
|
||||
Some(&self.folders[&fh])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +197,7 @@ impl Account {
|
|||
) -> Self {
|
||||
let mut backend = map.get(settings.account().format())(settings.account());
|
||||
let mut ref_folders: FnvHashMap<FolderHash, Folder> = backend.folders();
|
||||
let mut folders: FnvHashMap<FolderHash, Option<Result<Mailbox>>> =
|
||||
let mut folders: FnvHashMap<FolderHash, MailboxEntry> =
|
||||
FnvHashMap::with_capacity_and_hasher(ref_folders.len(), Default::default());
|
||||
let mut folders_order: Vec<FolderHash> = Vec::with_capacity(ref_folders.len());
|
||||
let mut workers: FnvHashMap<FolderHash, Worker> = FnvHashMap::default();
|
||||
|
@ -208,7 +249,7 @@ impl Account {
|
|||
}
|
||||
}
|
||||
}
|
||||
folders.insert(*h, None);
|
||||
folders.insert(*h, MailboxEntry::Parsing(0, 0));
|
||||
workers.insert(
|
||||
*h,
|
||||
Account::new_worker(f.clone(), &mut backend, notify_fn.clone()),
|
||||
|
@ -282,15 +323,19 @@ impl Account {
|
|||
.collect::<FnvHashMap<EnvelopeHash, Envelope>>()
|
||||
});
|
||||
let hash = folder.hash();
|
||||
let m = Mailbox::new(folder, envelopes.as_ref().map_err(Clone::clone));
|
||||
tx.send(AsyncStatus::Payload((envelopes, m)));
|
||||
if envelopes.is_err() {
|
||||
tx.send(AsyncStatus::Payload(Err(envelopes.unwrap_err())));
|
||||
notify_fn.notify(hash);
|
||||
return;
|
||||
}
|
||||
let envelopes = envelopes.unwrap();
|
||||
let m = Mailbox::new(folder, &envelopes);
|
||||
tx.send(AsyncStatus::Payload(Ok((envelopes, m))));
|
||||
notify_fn.notify(hash);
|
||||
})))
|
||||
}
|
||||
pub fn reload(&mut self, event: RefreshEvent, folder_hash: FolderHash) -> Option<UIEvent> {
|
||||
if self.folders[&folder_hash].is_none()
|
||||
|| self.folders[&folder_hash].as_ref().unwrap().is_err()
|
||||
{
|
||||
if !self.folders[&folder_hash].is_available() {
|
||||
self.event_queue.push_back((folder_hash, event));
|
||||
return None;
|
||||
}
|
||||
|
@ -306,15 +351,13 @@ impl Account {
|
|||
}
|
||||
RefreshEventKind::Rename(old_hash, new_hash) => {
|
||||
debug!("rename {} to {}", old_hash, new_hash);
|
||||
let mailbox = mailbox!(&folder_hash, self.folders);
|
||||
mailbox.rename(old_hash, new_hash);
|
||||
mailbox!(&folder_hash, self.folders).rename(old_hash, new_hash);
|
||||
self.collection.rename(old_hash, new_hash, folder_hash);
|
||||
return Some(EnvelopeRename(old_hash, new_hash));
|
||||
}
|
||||
RefreshEventKind::Create(envelope) => {
|
||||
let env_hash = envelope.hash();
|
||||
let mailbox = mailbox!(&folder_hash, self.folders);
|
||||
mailbox.insert(env_hash);
|
||||
mailbox!(&folder_hash, self.folders).insert(env_hash);
|
||||
self.collection.insert(*envelope, folder_hash);
|
||||
if self
|
||||
.sent_folder
|
||||
|
@ -367,7 +410,7 @@ impl Account {
|
|||
pub fn watch(&self, r: RefreshEventConsumer) {
|
||||
self.backend.watch(r).unwrap();
|
||||
}
|
||||
/* This doesn't represent the number of correctly parsed mailboxes though */
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.folders.len()
|
||||
}
|
||||
|
@ -417,17 +460,18 @@ impl Account {
|
|||
fn load_mailbox(
|
||||
&mut self,
|
||||
folder_hash: FolderHash,
|
||||
mailbox: (Result<FnvHashMap<EnvelopeHash, Envelope>>, Result<Mailbox>),
|
||||
payload: (Result<(FnvHashMap<EnvelopeHash, Envelope>, Mailbox)>),
|
||||
) {
|
||||
let (envs, mut mailbox) = mailbox;
|
||||
if envs.is_err() {
|
||||
self.folders.insert(folder_hash, None);
|
||||
if payload.is_err() {
|
||||
self.folders
|
||||
.insert(folder_hash, MailboxEntry::Failed(payload.unwrap_err()));
|
||||
return;
|
||||
}
|
||||
let envs = envs.unwrap();
|
||||
let (envelopes, mut mailbox) = payload.unwrap();
|
||||
self.collection
|
||||
.merge(envs, folder_hash, &mut mailbox, self.sent_folder);
|
||||
self.folders.insert(folder_hash, Some(mailbox));
|
||||
.merge(envelopes, folder_hash, &mut mailbox, self.sent_folder);
|
||||
self.folders
|
||||
.insert(folder_hash, MailboxEntry::Available(mailbox));
|
||||
}
|
||||
|
||||
pub fn status(&mut self, folder_hash: FolderHash) -> result::Result<(), usize> {
|
||||
|
@ -435,12 +479,17 @@ impl Account {
|
|||
None => {
|
||||
return Ok(());
|
||||
}
|
||||
Some(ref mut w) if self.folders[&folder_hash].is_none() => match w.poll() {
|
||||
Some(ref mut w) if self.folders[&folder_hash].is_parsing() => match w.poll() {
|
||||
Ok(AsyncStatus::NoUpdate) => {
|
||||
return Err(0);
|
||||
}
|
||||
Ok(AsyncStatus::Finished) => {}
|
||||
Ok(AsyncStatus::ProgressReport(n)) => {
|
||||
self.folders.entry(folder_hash).and_modify(|f| {
|
||||
if let MailboxEntry::Parsing(ref mut d, _) = f {
|
||||
*d += n;
|
||||
}
|
||||
});
|
||||
return Err(n);
|
||||
}
|
||||
_ => {
|
||||
|
@ -496,7 +545,7 @@ impl Account {
|
|||
}
|
||||
pub fn operation(&self, h: EnvelopeHash) -> Box<BackendOp> {
|
||||
for mailbox in self.folders.values() {
|
||||
if let Some(Ok(m)) = mailbox {
|
||||
if let MailboxEntry::Available(ref m) = mailbox {
|
||||
if m.envelopes.contains(&h) {
|
||||
let operation = self.backend.operation(h, m.folder.hash());
|
||||
if self.settings.account.read_only() {
|
||||
|
@ -542,41 +591,28 @@ impl Account {
|
|||
}
|
||||
|
||||
impl Index<FolderHash> for Account {
|
||||
type Output = Result<Mailbox>;
|
||||
fn index(&self, index: FolderHash) -> &Result<Mailbox> {
|
||||
type Output = MailboxEntry;
|
||||
fn index(&self, index: FolderHash) -> &MailboxEntry {
|
||||
&self.folders[&index]
|
||||
.as_ref()
|
||||
.expect("BUG: Requested mailbox that is not yet available.")
|
||||
}
|
||||
}
|
||||
|
||||
/// Will panic if mailbox hasn't loaded, ask `status()` first.
|
||||
impl IndexMut<FolderHash> for Account {
|
||||
fn index_mut(&mut self, index: FolderHash) -> &mut Result<Mailbox> {
|
||||
self.folders
|
||||
.get_mut(&index)
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
.expect("BUG: Requested mailbox that is not yet available.")
|
||||
fn index_mut(&mut self, index: FolderHash) -> &mut MailboxEntry {
|
||||
self.folders.get_mut(&index).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for Account {
|
||||
type Output = Result<Mailbox>;
|
||||
fn index(&self, index: usize) -> &Result<Mailbox> {
|
||||
type Output = MailboxEntry;
|
||||
fn index(&self, index: usize) -> &MailboxEntry {
|
||||
&self.folders[&self.folders_order[index]]
|
||||
.as_ref()
|
||||
.expect("BUG: Requested mailbox that is not yet available.")
|
||||
}
|
||||
}
|
||||
|
||||
/// Will panic if mailbox hasn't loaded, ask `status()` first.
|
||||
impl IndexMut<usize> for Account {
|
||||
fn index_mut(&mut self, index: usize) -> &mut Result<Mailbox> {
|
||||
self.folders
|
||||
.get_mut(&self.folders_order[index])
|
||||
.unwrap()
|
||||
.as_mut()
|
||||
.expect("BUG: Requested mailbox that is not yet available.")
|
||||
fn index_mut(&mut self, index: usize) -> &mut MailboxEntry {
|
||||
self.folders.get_mut(&self.folders_order[index]).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -276,11 +276,12 @@ impl State {
|
|||
return;
|
||||
}
|
||||
if let Some(notification) = self.context.accounts[idxa].reload(event, hash) {
|
||||
if let UIEvent::Notification(_, _) = notification {
|
||||
self.context
|
||||
.replies
|
||||
.push_back(UIEvent::MailboxUpdate((idxa, hash)));
|
||||
}
|
||||
self.rcv_event(notification);
|
||||
} else {
|
||||
self.context
|
||||
.replies
|
||||
.push_back(UIEvent::MailboxUpdate((idxa, hash)));
|
||||
}
|
||||
} else {
|
||||
debug!(
|
||||
|
|
Loading…
Reference in New Issue