wasm: add support for reload events

Manos Pitsidianakis 2020-07-25 00:54:46 +03:00
parent 4789a0e825
commit ebf95e00d9
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 83 additions and 17 deletions

View File

@ -119,14 +119,14 @@ impl BackendMailbox for DemoMailbox {
pub struct DemoOp {
hash: EnvelopeHash,
index: Arc<HashMap<EnvelopeHash, &'static str>>,
flags: Arc<RwLock<HashMap<EnvelopeHash, (Vec<u64>, Flag)>>>,
flags: Arc<RwLock<HashMap<EnvelopeHash, (Flag, Vec<u64>)>>>,
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
}
impl DemoOp {
pub fn new(
hash: EnvelopeHash,
flags: Arc<RwLock<HashMap<EnvelopeHash, (Vec<u64>, Flag)>>>,
flags: Arc<RwLock<HashMap<EnvelopeHash, (Flag, Vec<u64>)>>>,
index: Arc<HashMap<EnvelopeHash, &'static str>>,
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
) -> Self {
@ -146,21 +146,23 @@ impl BackendOp for DemoOp {
}
fn fetch_flags(&self) -> ResultFuture<Flag> {
let ret = self.flags.read().unwrap()[&self.hash].1;
let ret = self.flags.read().unwrap()[&self.hash].0;
Ok(Box::pin(async move { Ok(ret) }))
}
}
/// Demo backend
#[derive(Debug, Default)]
#[derive(Debug)]
pub struct DemoType {
account_name: String,
account_hash: AccountHash,
root_mailbox: String,
mailboxes: Arc<Mutex<HashMap<MailboxHash, DemoMailbox>>>,
envelopes: HashMap<EnvelopeHash, Envelope>,
index: Arc<HashMap<EnvelopeHash, &'static str>>,
flags: Arc<RwLock<HashMap<EnvelopeHash, (Vec<u64>, Flag)>>>,
flags: Arc<RwLock<HashMap<EnvelopeHash, (Flag, Vec<u64>)>>>,
tag_index: Arc<RwLock<BTreeMap<u64, String>>>,
event_consumer: BackendEventConsumer,
}
impl MailBackend for DemoType {
@ -201,7 +203,7 @@ impl MailBackend for DemoType {
}
fn refresh(&mut self, _mailbox_hash: MailboxHash) -> ResultFuture<()> {
Err(MeliError::new("Unimplemented."))
Ok(Box::pin(async { Ok(()) }))
}
fn mailboxes(&self) -> ResultFuture<HashMap<MailboxHash, Mailbox>> {
@ -248,25 +250,53 @@ impl MailBackend for DemoType {
fn set_flags(
&mut self,
env_hashes: EnvelopeHashBatch,
_mailbox_hash: MailboxHash,
mailbox_hash: MailboxHash,
flags: SmallVec<[(std::result::Result<Flag, String>, bool); 8]>,
) -> ResultFuture<()> {
for hash in env_hashes.iter() {
let mut tag_lck = self.tag_index.write().unwrap();
let mut flags_lck = self.flags.write().unwrap();
for env_hash in env_hashes.iter() {
let mut env_flags = flags_lck.get_mut(&env_hash).unwrap();
for set in flags.iter() {
match set {
(Ok(flag), value) => {
let mut flags = self.flags.read().unwrap()[&hash].1;
let mut flags = env_flags.0;
flags.set(*flag, *value);
self.flags.write().unwrap().get_mut(&hash).unwrap().1 = flags;
env_flags.0 = flags;
}
(Err(tag), value) => {
let hash = tag_hash!(tag);
if *value {
self.tag_index.write().unwrap().insert(hash, tag.into());
tag_lck.insert(hash, tag.into());
if !env_flags.1.contains(&hash) {
env_flags.1.push(hash);
}
} else {
if let Some(pos) = env_flags.1.iter().position(|h| *h == hash) {
env_flags.1.remove(pos);
}
}
}
}
}
(self.event_consumer)(
self.account_hash,
BackendEvent::Refresh(RefreshEvent {
mailbox_hash,
account_hash: self.account_hash,
kind: RefreshEventKind::NewFlags(
env_hash,
(
env_flags.0,
env_flags
.1
.iter()
.map(|tag_hash| tag_lck[tag_hash].to_string())
.collect::<Vec<String>>(),
),
),
}),
);
}
Ok(Box::pin(async { Ok(()) }))
}
@ -292,12 +322,25 @@ impl DemoType {
pub fn new(
s: &AccountSettings,
_is_subscribed: Box<dyn Fn(&str) -> bool>,
_event_consumer: BackendEventConsumer,
event_consumer: BackendEventConsumer,
) -> Result<Box<dyn MailBackend>> {
let account_hash = {
use std::collections::hash_map::DefaultHasher;
use std::hash::Hasher;
let mut hasher = DefaultHasher::new();
hasher.write(s.name().as_bytes());
hasher.finish()
};
let mut ret = DemoType {
account_name: s.name().to_string(),
account_hash,
root_mailbox: s.root_mailbox.to_string(),
..Default::default()
event_consumer,
mailboxes: Default::default(),
envelopes: Default::default(),
index: Default::default(),
flags: Default::default(),
tag_index: Default::default(),
};
{
let mut mbox_lck = ret.mailboxes.lock().unwrap();
@ -331,7 +374,7 @@ impl DemoType {
for bytes in *envelopes {
let env = Envelope::from_bytes(bytes.as_bytes(), None).unwrap();
index_lck.insert(env.hash(), bytes);
flags_lck.insert(env.hash(), (vec![], env.flags()));
flags_lck.insert(env.hash(), (env.flags(), vec![]));
mbox.envs.push(env.hash());
ret.envelopes.insert(env.hash(), env);
}

View File

@ -235,6 +235,27 @@ pub trait MailListingTrait: ListingTrait {
}
}
}
ListingAction::Delete => {
let job = account
.backend
.write()
.unwrap()
.delete_messages(env_hashes.clone(), mailbox_hash);
match job {
Err(err) => {
context.replies.push_back(UIEvent::StatusEvent(
StatusEvent::DisplayMessage(err.to_string()),
));
}
Ok(fut) => {
let handle = account.job_executor.spawn_specialized(fut);
account.insert_job(
handle.job_id,
JobRequest::DeleteMessages { env_hashes, handle },
);
}
}
}
ListingAction::Tag(Add(ref tag_str)) => {
let job = account.backend.write().unwrap().set_flags(
env_hashes.clone(),

View File

@ -143,7 +143,7 @@ impl MailboxEntry {
#[derive(Debug)]
pub struct Account {
name: String,
hash: AccountHash,
pub hash: AccountHash,
pub is_online: Result<()>,
pub(crate) mailbox_entries: IndexMap<MailboxHash, MailboxEntry>,
pub(crate) mailboxes_order: Vec<MailboxHash>,

View File

@ -393,7 +393,6 @@ impl State {
* and startup a thread to remind us to poll it every now and then till it's finished.
*/
pub fn refresh_event(&mut self, event: RefreshEvent) {
/*
let account_hash = event.account_hash;
let mailbox_hash = event.mailbox_hash;
if self.context.accounts[&account_hash]
@ -422,7 +421,6 @@ impl State {
debug!(err);
}
}
*/
}
/// Switch back to the terminal's main screen (The command line the user sees before opening
@ -1564,6 +1562,10 @@ impl State {
self.overlay.push(dialog);
return;
}
UIEvent::RefreshEvent(ev) => {
self.refresh_event(*ev);
return;
}
_ => {}
}
let Self {