Add edit envelope action back as async
parent
f7c9f21575
commit
53e924eb33
|
@ -24,9 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::components::Component;
|
use crate::components::Component;
|
||||||
use melib::backends::AccountHash;
|
|
||||||
pub use melib::thread::{SortField, SortOrder};
|
pub use melib::thread::{SortField, SortOrder};
|
||||||
use melib::{Draft, EnvelopeHash};
|
|
||||||
|
|
||||||
extern crate uuid;
|
extern crate uuid;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -58,11 +56,9 @@ pub enum ListingAction {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum TabAction {
|
pub enum TabAction {
|
||||||
New(Option<Box<dyn Component>>),
|
|
||||||
NewDraft(AccountHash, Option<Draft>),
|
|
||||||
Close,
|
Close,
|
||||||
Edit(AccountHash, EnvelopeHash), // account_position, envelope hash
|
|
||||||
Kill(Uuid),
|
Kill(Uuid),
|
||||||
|
New(Option<Box<dyn Component>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -642,9 +642,11 @@ impl Component for ContactList {
|
||||||
let mut draft: Draft = Draft::default();
|
let mut draft: Draft = Draft::default();
|
||||||
*draft.headers_mut().get_mut("To").unwrap() =
|
*draft.headers_mut().get_mut("To").unwrap() =
|
||||||
format!("{} <{}>", &card.name(), &card.email());
|
format!("{} <{}>", &card.name(), &card.email());
|
||||||
|
let mut composer = Composer::new(account_hash, context);
|
||||||
|
composer.set_draft(draft);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::Action(Tab(NewDraft(account_hash, Some(draft)))));
|
.push_back(UIEvent::Action(Tab(New(Some(Box::new(composer))))));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -286,6 +286,7 @@ pub trait MailListingTrait: ListingTrait {
|
||||||
name: "message copying".into(),
|
name: "message copying".into(),
|
||||||
handle,
|
handle,
|
||||||
channel,
|
channel,
|
||||||
|
on_finish: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -323,6 +324,7 @@ pub trait MailListingTrait: ListingTrait {
|
||||||
name: "message moving".into(),
|
name: "message moving".into(),
|
||||||
handle,
|
handle,
|
||||||
channel,
|
channel,
|
||||||
|
on_finish: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1099,9 +1101,10 @@ impl Component for Listing {
|
||||||
if shortcut!(k == shortcuts[Listing::DESCRIPTION]["new_mail"]) =>
|
if shortcut!(k == shortcuts[Listing::DESCRIPTION]["new_mail"]) =>
|
||||||
{
|
{
|
||||||
let account_hash = context.accounts[self.cursor_pos.0].hash();
|
let account_hash = context.accounts[self.cursor_pos.0].hash();
|
||||||
|
let composer = Composer::new(account_hash, context);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::Action(Tab(NewDraft(account_hash, None))));
|
.push_back(UIEvent::Action(Tab(New(Some(Box::new(composer))))));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
UIEvent::StartupCheck(_) => {
|
UIEvent::StartupCheck(_) => {
|
||||||
|
|
|
@ -1137,10 +1137,66 @@ impl Component for MailView {
|
||||||
UIEvent::Input(ref key)
|
UIEvent::Input(ref key)
|
||||||
if shortcut!(key == shortcuts[MailView::DESCRIPTION]["edit"]) =>
|
if shortcut!(key == shortcuts[MailView::DESCRIPTION]["edit"]) =>
|
||||||
{
|
{
|
||||||
context.replies.push_back(UIEvent::Action(Tab(Edit(
|
let account_hash = self.coordinates.0;
|
||||||
self.coordinates.0,
|
let env_hash = self.coordinates.2;
|
||||||
self.coordinates.2,
|
let (sender, mut receiver) = crate::jobs::oneshot::channel();
|
||||||
))));
|
let operation = context.accounts[&account_hash].operation(env_hash);
|
||||||
|
let bytes_job = async move {
|
||||||
|
let _ = sender.send(operation?.as_bytes()?.await);
|
||||||
|
Ok(())
|
||||||
|
};
|
||||||
|
let (channel, handle, job_id) = if context.accounts[&account_hash]
|
||||||
|
.backend_capabilities
|
||||||
|
.is_async
|
||||||
|
{
|
||||||
|
context.accounts[&account_hash]
|
||||||
|
.job_executor
|
||||||
|
.spawn_specialized(bytes_job)
|
||||||
|
} else {
|
||||||
|
context.accounts[&account_hash]
|
||||||
|
.job_executor
|
||||||
|
.spawn_blocking(bytes_job)
|
||||||
|
};
|
||||||
|
context.accounts[&account_hash].insert_job(
|
||||||
|
job_id,
|
||||||
|
crate::conf::accounts::JobRequest::Generic {
|
||||||
|
name: "fetch envelope".into(),
|
||||||
|
handle,
|
||||||
|
channel,
|
||||||
|
on_finish: Some(CallbackFn(Box::new(move |context: &mut Context| {
|
||||||
|
let result = receiver.try_recv().unwrap().unwrap();
|
||||||
|
match result.and_then(|bytes| {
|
||||||
|
Composer::edit(account_hash, env_hash, &bytes, context)
|
||||||
|
}) {
|
||||||
|
Ok(composer) => {
|
||||||
|
context.replies.push_back(UIEvent::Action(Tab(New(Some(
|
||||||
|
Box::new(composer),
|
||||||
|
)))));
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
let err_string = format!(
|
||||||
|
"Failed to open envelope {}: {}",
|
||||||
|
context.accounts[&account_hash]
|
||||||
|
.collection
|
||||||
|
.envelopes
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.get(&env_hash)
|
||||||
|
.map(|env| env.message_id_display())
|
||||||
|
.unwrap_or_else(|| "Not found".into()),
|
||||||
|
err.to_string()
|
||||||
|
);
|
||||||
|
log(&err_string, ERROR);
|
||||||
|
context.replies.push_back(UIEvent::Notification(
|
||||||
|
Some("Failed to open e-mail".to_string()),
|
||||||
|
err_string,
|
||||||
|
Some(NotificationType::ERROR),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}))),
|
||||||
|
},
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
UIEvent::Input(ref key)
|
UIEvent::Input(ref key)
|
||||||
|
@ -1538,10 +1594,11 @@ impl Component for MailView {
|
||||||
{
|
{
|
||||||
if let Ok(mailto) = Mailto::try_from(list_post_addr) {
|
if let Ok(mailto) = Mailto::try_from(list_post_addr) {
|
||||||
let draft: Draft = mailto.into();
|
let draft: Draft = mailto.into();
|
||||||
context.replies.push_back(UIEvent::Action(Tab(NewDraft(
|
let mut composer = Composer::new(self.coordinates.0, context);
|
||||||
self.coordinates.0,
|
composer.set_draft(draft);
|
||||||
Some(draft),
|
context.replies.push_back(UIEvent::Action(Tab(New(Some(
|
||||||
))));
|
Box::new(composer),
|
||||||
|
)))));
|
||||||
failure = false;
|
failure = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1662,52 +1662,6 @@ impl Component for Tabbed {
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
UIEvent::Action(Tab(NewDraft(account_hash, ref draft))) => {
|
|
||||||
let mut composer = Composer::new(*account_hash, context);
|
|
||||||
if let Some(draft) = draft {
|
|
||||||
composer.set_draft(draft.clone());
|
|
||||||
}
|
|
||||||
self.add_component(Box::new(composer));
|
|
||||||
self.cursor_pos = self.children.len() - 1;
|
|
||||||
self.children[self.cursor_pos].set_dirty(true);
|
|
||||||
let mut children_maps = self.children[self.cursor_pos].get_shortcuts(context);
|
|
||||||
children_maps.extend(self.get_shortcuts(context));
|
|
||||||
self.help_curr_views = children_maps;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
UIEvent::Action(Tab(Edit(_, _))) => {
|
|
||||||
/* FIXME
|
|
||||||
let composer = match Composer::edit(*account_hash, *msg, context) {
|
|
||||||
Ok(c) => c,
|
|
||||||
Err(e) => {
|
|
||||||
context.replies.push_back(UIEvent::Notification(
|
|
||||||
Some("Failed to open e-mail".to_string()),
|
|
||||||
e.to_string(),
|
|
||||||
Some(NotificationType::ERROR),
|
|
||||||
));
|
|
||||||
log(
|
|
||||||
format!(
|
|
||||||
"Failed to open envelope {}: {}",
|
|
||||||
context.accounts[&*account_hash]
|
|
||||||
.collection
|
|
||||||
.get_env(*msg)
|
|
||||||
.message_id_display(),
|
|
||||||
e.to_string()
|
|
||||||
),
|
|
||||||
ERROR,
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
self.add_component(Box::new(composer));
|
|
||||||
self.cursor_pos = self.children.len() - 1;
|
|
||||||
self.children[self.cursor_pos].set_dirty(true);
|
|
||||||
let mut children_maps = self.children[self.cursor_pos].get_shortcuts(context);
|
|
||||||
children_maps.extend(self.get_shortcuts(context));
|
|
||||||
self.help_curr_views = children_maps;
|
|
||||||
*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
UIEvent::Action(Tab(New(ref mut e))) if e.is_some() => {
|
UIEvent::Action(Tab(New(ref mut e))) if e.is_some() => {
|
||||||
self.add_component(e.take().unwrap());
|
self.add_component(e.take().unwrap());
|
||||||
self.cursor_pos = self.children.len() - 1;
|
self.cursor_pos = self.children.len() - 1;
|
||||||
|
|
|
@ -176,6 +176,7 @@ pub enum JobRequest {
|
||||||
name: Cow<'static, str>,
|
name: Cow<'static, str>,
|
||||||
handle: JoinHandle,
|
handle: JoinHandle,
|
||||||
channel: JobChannel<()>,
|
channel: JobChannel<()>,
|
||||||
|
on_finish: Option<crate::types::CallbackFn>,
|
||||||
},
|
},
|
||||||
IsOnline(JoinHandle, oneshot::Receiver<Result<()>>),
|
IsOnline(JoinHandle, oneshot::Receiver<Result<()>>),
|
||||||
Refresh(MailboxHash, JoinHandle, oneshot::Receiver<Result<()>>),
|
Refresh(MailboxHash, JoinHandle, oneshot::Receiver<Result<()>>),
|
||||||
|
@ -1796,6 +1797,7 @@ impl Account {
|
||||||
ref name,
|
ref name,
|
||||||
ref mut channel,
|
ref mut channel,
|
||||||
handle: _,
|
handle: _,
|
||||||
|
ref mut on_finish,
|
||||||
} => {
|
} => {
|
||||||
let r = channel.try_recv().unwrap();
|
let r = channel.try_recv().unwrap();
|
||||||
match r {
|
match r {
|
||||||
|
@ -1819,6 +1821,13 @@ impl Account {
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
if on_finish.is_some() {
|
||||||
|
self.sender
|
||||||
|
.send(ThreadEvent::UIEvent(UIEvent::Callback(
|
||||||
|
on_finish.take().unwrap(),
|
||||||
|
)))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
self.sender
|
self.sender
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::StatusEvent(
|
.send(ThreadEvent::UIEvent(UIEvent::StatusEvent(
|
||||||
StatusEvent::JobFinished(*job_id),
|
StatusEvent::JobFinished(*job_id),
|
||||||
|
|
|
@ -888,6 +888,7 @@ impl State {
|
||||||
name: "Message index rebuild".into(),
|
name: "Message index rebuild".into(),
|
||||||
handle,
|
handle,
|
||||||
channel,
|
channel,
|
||||||
|
on_finish: None,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
self.context.replies.push_back(UIEvent::Notification(
|
self.context.replies.push_back(UIEvent::Notification(
|
||||||
|
@ -1089,6 +1090,10 @@ impl State {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
UIEvent::Callback(callback_fn) => {
|
||||||
|
(callback_fn.0)(&mut self.context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
UIEvent::GlobalUIDialog(dialog) => {
|
UIEvent::GlobalUIDialog(dialog) => {
|
||||||
self.overlay.push(dialog);
|
self.overlay.push(dialog);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -126,10 +126,19 @@ pub enum UIEvent {
|
||||||
Contacts(ContactEvent),
|
Contacts(ContactEvent),
|
||||||
Compose(ComposeEvent),
|
Compose(ComposeEvent),
|
||||||
FinishedUIDialog(ComponentId, UIMessage),
|
FinishedUIDialog(ComponentId, UIMessage),
|
||||||
|
Callback(CallbackFn),
|
||||||
GlobalUIDialog(Box<dyn Component>),
|
GlobalUIDialog(Box<dyn Component>),
|
||||||
Timer(u8),
|
Timer(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CallbackFn(pub Box<dyn FnOnce(&mut crate::Context) -> () + Send + 'static>);
|
||||||
|
|
||||||
|
impl core::fmt::Debug for CallbackFn {
|
||||||
|
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
|
write!(fmt, "CallbackFn")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<RefreshEvent> for UIEvent {
|
impl From<RefreshEvent> for UIEvent {
|
||||||
fn from(event: RefreshEvent) -> Self {
|
fn from(event: RefreshEvent) -> Self {
|
||||||
UIEvent::RefreshEvent(Box::new(event))
|
UIEvent::RefreshEvent(Box::new(event))
|
||||||
|
|
Loading…
Reference in New Issue