compose: don't lose draft if Draft folder isn't available

Try saving in INBOX or another folder instead. On complete failure, save
in /tmp/
embed
Manos Pitsidianakis 2019-09-27 13:25:13 +03:00
parent 68c40a2920
commit d8ada69897
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
2 changed files with 73 additions and 37 deletions

View File

@ -547,14 +547,64 @@ impl Component for Composer {
}
('n', _) => {}
('y', ViewMode::Discard(u)) => {
let account = &context.accounts[self.account_cursor];
let mut failure = true;
let draft = std::mem::replace(&mut self.draft, Draft::default());
if let Err(e) = account.save_draft(draft) {
debug!("{:?} could not save draft", e);
let draft = draft.finalise().unwrap();
for folder in &[
&context.accounts[self.account_cursor]
.special_use_folder(SpecialUseMailbox::Drafts),
&context.accounts[self.account_cursor]
.special_use_folder(SpecialUseMailbox::Inbox),
&context.accounts[self.account_cursor]
.special_use_folder(SpecialUseMailbox::Normal),
] {
if folder.is_none() {
continue;
}
let folder = folder.unwrap();
if let Err(e) = context.accounts[self.account_cursor].save(
draft.as_bytes(),
folder,
Some(Flag::SEEN | Flag::DRAFT),
) {
debug!("{:?} could not save draft msg", e);
log(
format!(
"Could not save draft in '{}' folder: {}.",
folder,
e.to_string()
),
ERROR,
);
context.replies.push_back(UIEvent::Notification(
Some(format!("Could not save draft in '{}' folder.", folder)),
e.into(),
Some(NotificationType::ERROR),
));
} else {
failure = false;
break;
}
}
if failure {
let file = create_temp_file(draft.as_bytes(), None, None, false);
debug!("message saved in {}", file.path.display());
log(
format!(
"Message was stored in {} so that you can restore it manually.",
file.path.display()
),
INFO,
);
context.replies.push_back(UIEvent::Notification(
Some("Could not save draft.".into()),
e.into(),
Some(NotificationType::ERROR),
Some("Could not save in any folder".into()),
format!(
"Message was stored in {} so that you can restore it manually.",
file.path.display()
),
Some(NotificationType::INFO),
));
}
context.replies.push_back(UIEvent::Action(Tab(Kill(*u))));
@ -789,10 +839,18 @@ pub fn send_draft(context: &mut Context, account_cursor: usize, draft: Draft) ->
&context.accounts[account_cursor].special_use_folder(SpecialUseMailbox::Inbox),
&context.accounts[account_cursor].special_use_folder(SpecialUseMailbox::Normal),
] {
if folder.is_none() {
continue;
}
let folder = folder.unwrap();
if let Err(e) =
context.accounts[account_cursor].save(draft.as_bytes(), folder, Some(Flag::SEEN))
{
debug!("{:?} could not save sent msg", e);
log(
format!("Could not save in '{}' folder: {}.", folder, e.to_string()),
ERROR,
);
context.replies.push_back(UIEvent::Notification(
Some(format!("Could not save in '{}' folder.", folder)),
e.into(),
@ -807,6 +865,13 @@ pub fn send_draft(context: &mut Context, account_cursor: usize, draft: Draft) ->
if failure {
let file = create_temp_file(draft.as_bytes(), None, None, false);
debug!("message saved in {}", file.path.display());
log(
format!(
"Message was stored in {} so that you can restore it manually.",
file.path.display()
),
INFO,
);
context.replies.push_back(UIEvent::Notification(
Some("Could not save in any folder".into()),
format!(

View File

@ -651,31 +651,6 @@ impl Account {
}
}
pub fn save_draft(&self, draft: Draft) -> Result<()> {
if self.settings.account.read_only() {
return Err(MeliError::new(format!(
"Account {} is read-only.",
self.name.as_str()
)));
}
let draft_folder = self
.settings
.folder_confs
.iter()
.find(|(_, f)| f.usage == Some(SpecialUseMailbox::Drafts));
if draft_folder.is_none() {
return Err(MeliError::new(format!(
"Account {} has no draft folder set.",
self.name.as_str()
)));
}
let draft_folder = draft_folder.unwrap();
let finalize = draft.finalise()?;
self.backend
.save(&finalize.as_bytes(), draft_folder.0, None)
}
pub fn save(&self, bytes: &[u8], folder: &str, flags: Option<Flag>) -> Result<()> {
if self.settings.account.read_only() {
return Err(MeliError::new(format!(
@ -772,17 +747,13 @@ impl Account {
}
}
pub fn special_use_folder(&self, special_use: SpecialUseMailbox) -> &str {
pub fn special_use_folder(&self, special_use: SpecialUseMailbox) -> Option<&str> {
let ret = self
.settings
.folder_confs
.iter()
.find(|(_, f)| f.usage == Some(special_use));
if let Some(ret) = ret.as_ref() {
ret.0
} else {
""
}
ret.as_ref().map(|r| r.0.as_str())
}
}