From d8ada69897d46d298309f672df611aa81e3645fa Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Fri, 27 Sep 2019 13:25:13 +0300 Subject: [PATCH] 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/ --- ui/src/components/mail/compose.rs | 77 ++++++++++++++++++++++++++++--- ui/src/conf/accounts.rs | 33 +------------ 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/ui/src/components/mail/compose.rs b/ui/src/components/mail/compose.rs index 6c268772..7c1fc8ec 100644 --- a/ui/src/components/mail/compose.rs +++ b/ui/src/components/mail/compose.rs @@ -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!( diff --git a/ui/src/conf/accounts.rs b/ui/src/conf/accounts.rs index 1a479565..ca204a91 100644 --- a/ui/src/conf/accounts.rs +++ b/ui/src/conf/accounts.rs @@ -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) -> 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()) } }