NotificationType: add melib::ErrorKind
parent
352f7505fc
commit
fadf20d7b1
|
@ -37,12 +37,30 @@ pub type Result<T> = result::Result<T, MeliError>;
|
||||||
#[derive(Debug, Copy, PartialEq, Clone)]
|
#[derive(Debug, Copy, PartialEq, Clone)]
|
||||||
pub enum ErrorKind {
|
pub enum ErrorKind {
|
||||||
None,
|
None,
|
||||||
|
External,
|
||||||
Authentication,
|
Authentication,
|
||||||
Bug,
|
Bug,
|
||||||
Network,
|
Network,
|
||||||
Timeout,
|
Timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ErrorKind {
|
||||||
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
fmt,
|
||||||
|
"{}",
|
||||||
|
match self {
|
||||||
|
ErrorKind::None => "None",
|
||||||
|
ErrorKind::External => "External",
|
||||||
|
ErrorKind::Authentication => "Authentication",
|
||||||
|
ErrorKind::Bug => "Bug, please report this!",
|
||||||
|
ErrorKind::Network => "Network",
|
||||||
|
ErrorKind::Timeout => "Timeout",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ErrorKind {
|
impl ErrorKind {
|
||||||
pub fn is_network(&self) -> bool {
|
pub fn is_network(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
|
@ -172,17 +190,7 @@ impl fmt::Display for MeliError {
|
||||||
write!(f, "\nCaused by: {}", source)?;
|
write!(f, "\nCaused by: {}", source)?;
|
||||||
}
|
}
|
||||||
if self.kind != ErrorKind::None {
|
if self.kind != ErrorKind::None {
|
||||||
write!(
|
write!(f, "\nKind: {}", self.kind)?;
|
||||||
f,
|
|
||||||
"\nKind: {}",
|
|
||||||
match self.kind {
|
|
||||||
ErrorKind::None => "None",
|
|
||||||
ErrorKind::Authentication => "Authentication",
|
|
||||||
ErrorKind::Bug => "Bug, please report this!",
|
|
||||||
ErrorKind::Network => "Network",
|
|
||||||
ErrorKind::Timeout => "Timeout",
|
|
||||||
}
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -750,7 +750,7 @@ impl Component for Composer {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Sent.".into()),
|
Some("Sent.".into()),
|
||||||
String::new(),
|
String::new(),
|
||||||
Some(NotificationType::INFO),
|
Some(NotificationType::Info),
|
||||||
));
|
));
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
|
@ -760,7 +760,7 @@ impl Component for Composer {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
save_draft(
|
save_draft(
|
||||||
self.draft.clone().finalise().unwrap().as_bytes(),
|
self.draft.clone().finalise().unwrap().as_bytes(),
|
||||||
|
@ -869,7 +869,7 @@ impl Component for Composer {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
self.set_dirty(true);
|
self.set_dirty(true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -980,7 +980,9 @@ impl Component for Composer {
|
||||||
"Subprocess has exited with exit code {}",
|
"Subprocess has exited with exit code {}",
|
||||||
exit_code
|
exit_code
|
||||||
),
|
),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(
|
||||||
|
melib::error::ErrorKind::External,
|
||||||
|
)),
|
||||||
));
|
));
|
||||||
} else if let EmbedStatus::Running(_, f) = embed {
|
} else if let EmbedStatus::Running(_, f) = embed {
|
||||||
let result = f.read_to_string();
|
let result = f.read_to_string();
|
||||||
|
@ -995,12 +997,12 @@ impl Component for Composer {
|
||||||
}
|
}
|
||||||
self.draft = new_draft;
|
self.draft = new_draft;
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
Some("Could not parse draft headers correctly.".to_string()),
|
||||||
"Could not parse draft headers correctly. The invalid text has been set as the body of your draft".to_string(),
|
format!("{}\nThe invalid text has been set as the body of your draft", &err),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::error::ErrorKind::None)),
|
||||||
));
|
));
|
||||||
self.draft.set_body(result);
|
self.draft.set_body(result);
|
||||||
self.has_changes = true;
|
self.has_changes = true;
|
||||||
}
|
}
|
||||||
|
@ -1013,6 +1015,24 @@ impl Component for Composer {
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::ChangeMode(UIMode::Normal));
|
.push_back(UIEvent::ChangeMode(UIMode::Normal));
|
||||||
}
|
}
|
||||||
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
|
Ok(WaitStatus::PtraceEvent(_, _, _))
|
||||||
|
| Ok(WaitStatus::PtraceSyscall(_)) => {
|
||||||
|
drop(embed_guard);
|
||||||
|
match self.embed.take() {
|
||||||
|
Some(EmbedStatus::Running(e, f))
|
||||||
|
| Some(EmbedStatus::Stopped(e, f)) => {
|
||||||
|
self.embed = Some(EmbedStatus::Stopped(e, f));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
self.mode = ViewMode::Edit;
|
||||||
|
context
|
||||||
|
.replies
|
||||||
|
.push_back(UIEvent::ChangeMode(UIMode::Normal));
|
||||||
|
self.dirty = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Ok(WaitStatus::Stopped(_, _)) => {
|
Ok(WaitStatus::Stopped(_, _)) => {
|
||||||
drop(embed_guard);
|
drop(embed_guard);
|
||||||
match self.embed.take() {
|
match self.embed.take() {
|
||||||
|
@ -1035,11 +1055,28 @@ impl Component for Composer {
|
||||||
.push_back(UIEvent::EmbedInput((k.clone(), b.to_vec())));
|
.push_back(UIEvent::EmbedInput((k.clone(), b.to_vec())));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
e => {
|
Ok(WaitStatus::Signaled(_, signal, _)) => {
|
||||||
|
drop(embed_guard);
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
format!("Subprocess has exited with reason {:?}", e),
|
format!("Subprocess was killed by {} signal", signal),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(
|
||||||
|
melib::error::ErrorKind::External,
|
||||||
|
)),
|
||||||
|
));
|
||||||
|
self.embed = None;
|
||||||
|
self.mode = ViewMode::Edit;
|
||||||
|
context
|
||||||
|
.replies
|
||||||
|
.push_back(UIEvent::ChangeMode(UIMode::Normal));
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
context.replies.push_back(UIEvent::Notification(
|
||||||
|
Some("Embed editor crashed.".to_string()),
|
||||||
|
format!("Subprocess has exited with reason {}", &err),
|
||||||
|
Some(NotificationType::Error(
|
||||||
|
melib::error::ErrorKind::External,
|
||||||
|
)),
|
||||||
));
|
));
|
||||||
drop(embed_guard);
|
drop(embed_guard);
|
||||||
self.embed = None;
|
self.embed = None;
|
||||||
|
@ -1083,11 +1120,11 @@ impl Component for Composer {
|
||||||
editor_command.to_string()
|
editor_command.to_string()
|
||||||
} else {
|
} else {
|
||||||
match std::env::var("EDITOR") {
|
match std::env::var("EDITOR") {
|
||||||
Err(e) => {
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some(e.to_string()),
|
Some(err.to_string()),
|
||||||
"$EDITOR is not set. You can change an envvar's value with setenv or set composing.editor_command setting in your configuration.".to_string(),
|
"$EDITOR is not set. You can change an envvar's value with setenv or set composing.editor_command setting in your configuration.".to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::error::ErrorKind::None)),
|
||||||
));
|
));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1150,7 +1187,7 @@ impl Component for Composer {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some(format!("Failed to execute {}: {}", editor, err)),
|
Some(format!("Failed to execute {}: {}", editor, err)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::error::ErrorKind::External)),
|
||||||
));
|
));
|
||||||
context.replies.push_back(UIEvent::Fork(ForkType::Finished));
|
context.replies.push_back(UIEvent::Fork(ForkType::Finished));
|
||||||
context.restore_input();
|
context.restore_input();
|
||||||
|
@ -1167,12 +1204,15 @@ impl Component for Composer {
|
||||||
}
|
}
|
||||||
self.draft = new_draft;
|
self.draft = new_draft;
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
Some("Could not parse draft headers correctly.".to_string()),
|
||||||
"Could not parse draft headers correctly. The invalid text has been set as the body of your draft".to_string(),
|
format!(
|
||||||
Some(NotificationType::ERROR),
|
"{}\nThe invalid text has been set as the body of your draft",
|
||||||
));
|
&err
|
||||||
|
),
|
||||||
|
Some(NotificationType::Error(melib::error::ErrorKind::None)),
|
||||||
|
));
|
||||||
self.draft.set_body(result);
|
self.draft.set_body(result);
|
||||||
self.has_changes = true;
|
self.has_changes = true;
|
||||||
}
|
}
|
||||||
|
@ -1181,125 +1221,127 @@ impl Component for Composer {
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
UIEvent::Action(ref a) => {
|
UIEvent::Action(ref a) => match a {
|
||||||
match a {
|
Action::Compose(ComposeAction::AddAttachmentPipe(ref command)) => {
|
||||||
Action::Compose(ComposeAction::AddAttachmentPipe(ref command)) => {
|
if command.is_empty() {
|
||||||
if command.is_empty() {
|
context.replies.push_back(UIEvent::Notification(
|
||||||
|
None,
|
||||||
|
format!("pipe command value is invalid: {}", command),
|
||||||
|
Some(NotificationType::Error(melib::error::ErrorKind::None)),
|
||||||
|
));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let f = create_temp_file(&[], None, None, true);
|
||||||
|
match std::process::Command::new("sh")
|
||||||
|
.args(&["-c", command])
|
||||||
|
.stdin(std::process::Stdio::null())
|
||||||
|
.stdout(std::process::Stdio::from(f.file()))
|
||||||
|
.spawn()
|
||||||
|
{
|
||||||
|
Ok(child) => {
|
||||||
|
let _ = child
|
||||||
|
.wait_with_output()
|
||||||
|
.expect("failed to launch command")
|
||||||
|
.stdout;
|
||||||
|
let mut attachment =
|
||||||
|
match melib::email::compose::attachment_from_file(f.path()) {
|
||||||
|
Ok(a) => a,
|
||||||
|
Err(err) => {
|
||||||
|
context.replies.push_back(UIEvent::Notification(
|
||||||
|
Some("could not add attachment".to_string()),
|
||||||
|
err.to_string(),
|
||||||
|
Some(NotificationType::Error(
|
||||||
|
melib::error::ErrorKind::None,
|
||||||
|
)),
|
||||||
|
));
|
||||||
|
self.dirty = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Ok(mime_type) = query_mime_info(f.path()) {
|
||||||
|
match attachment.content_type {
|
||||||
|
ContentType::Other { ref mut tag, .. } => {
|
||||||
|
*tag = mime_type;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.draft.attachments_mut().push(attachment);
|
||||||
|
self.dirty = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
format!("pipe command value is invalid: {}", command),
|
format!("could not execute pipe command {}: {}", command, &err),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::error::ErrorKind::External)),
|
||||||
));
|
));
|
||||||
return false;
|
return true;
|
||||||
}
|
|
||||||
let f = create_temp_file(&[], None, None, true);
|
|
||||||
match std::process::Command::new("sh")
|
|
||||||
.args(&["-c", command])
|
|
||||||
.stdin(std::process::Stdio::null())
|
|
||||||
.stdout(std::process::Stdio::from(f.file()))
|
|
||||||
.spawn()
|
|
||||||
{
|
|
||||||
Ok(child) => {
|
|
||||||
let _ = child
|
|
||||||
.wait_with_output()
|
|
||||||
.expect("failed to launch command")
|
|
||||||
.stdout;
|
|
||||||
let mut attachment =
|
|
||||||
match melib::email::attachment_from_file(f.path()) {
|
|
||||||
Ok(a) => a,
|
|
||||||
Err(e) => {
|
|
||||||
context.replies.push_back(UIEvent::Notification(
|
|
||||||
Some("could not add attachment".to_string()),
|
|
||||||
e.to_string(),
|
|
||||||
Some(NotificationType::ERROR),
|
|
||||||
));
|
|
||||||
self.dirty = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Ok(mime_type) = query_mime_info(f.path()) {
|
|
||||||
match attachment.content_type {
|
|
||||||
ContentType::Other { ref mut tag, .. } => {
|
|
||||||
*tag = mime_type;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.draft.attachments_mut().push(attachment);
|
|
||||||
self.dirty = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
context.replies.push_back(UIEvent::Notification(
|
|
||||||
None,
|
|
||||||
format!("could not execute pipe command {}: {}", command, err),
|
|
||||||
Some(NotificationType::ERROR),
|
|
||||||
));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Action::Compose(ComposeAction::AddAttachment(ref path)) => {
|
}
|
||||||
let mut attachment = match melib::email::attachment_from_file(path) {
|
Action::Compose(ComposeAction::AddAttachment(ref path)) => {
|
||||||
Ok(a) => a,
|
let mut attachment = match melib::email::compose::attachment_from_file(path) {
|
||||||
Err(e) => {
|
Ok(a) => a,
|
||||||
context.replies.push_back(UIEvent::Notification(
|
Err(err) => {
|
||||||
Some("could not add attachment".to_string()),
|
context.replies.push_back(UIEvent::Notification(
|
||||||
e.to_string(),
|
Some("could not add attachment".to_string()),
|
||||||
Some(NotificationType::ERROR),
|
err.to_string(),
|
||||||
));
|
Some(NotificationType::Error(melib::error::ErrorKind::None)),
|
||||||
self.dirty = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Ok(mime_type) = query_mime_info(path) {
|
|
||||||
match attachment.content_type {
|
|
||||||
ContentType::Other { ref mut tag, .. } => {
|
|
||||||
*tag = mime_type;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.draft.attachments_mut().push(attachment);
|
|
||||||
self.dirty = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Action::Compose(ComposeAction::RemoveAttachment(idx)) => {
|
|
||||||
if *idx + 1 > self.draft.attachments().len() {
|
|
||||||
context.replies.push_back(UIEvent::StatusEvent(
|
|
||||||
StatusEvent::DisplayMessage(
|
|
||||||
"attachment with given index does not exist".to_string(),
|
|
||||||
),
|
|
||||||
));
|
));
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
self.draft.attachments_mut().remove(*idx);
|
};
|
||||||
|
if let Ok(mime_type) = query_mime_info(path) {
|
||||||
|
match attachment.content_type {
|
||||||
|
ContentType::Other { ref mut tag, .. } => {
|
||||||
|
*tag = mime_type;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.draft.attachments_mut().push(attachment);
|
||||||
|
self.dirty = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Action::Compose(ComposeAction::RemoveAttachment(idx)) => {
|
||||||
|
if *idx + 1 > self.draft.attachments().len() {
|
||||||
context.replies.push_back(UIEvent::StatusEvent(
|
context.replies.push_back(UIEvent::StatusEvent(
|
||||||
StatusEvent::DisplayMessage("attachment removed".to_string()),
|
StatusEvent::DisplayMessage(
|
||||||
|
"attachment with given index does not exist".to_string(),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Action::Compose(ComposeAction::SaveDraft) => {
|
self.draft.attachments_mut().remove(*idx);
|
||||||
save_draft(
|
context
|
||||||
self.draft.clone().finalise().unwrap().as_bytes(),
|
.replies
|
||||||
context,
|
.push_back(UIEvent::StatusEvent(StatusEvent::DisplayMessage(
|
||||||
SpecialUsageMailbox::Drafts,
|
"attachment removed".to_string(),
|
||||||
Flag::SEEN | Flag::DRAFT,
|
)));
|
||||||
self.account_hash,
|
self.dirty = true;
|
||||||
);
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Action::Compose(ComposeAction::ToggleSign) => {
|
|
||||||
let is_true = self.sign_mail.is_true();
|
|
||||||
self.sign_mail = ToggleFlag::from(!is_true);
|
|
||||||
self.dirty = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
Action::Compose(ComposeAction::SaveDraft) => {
|
||||||
|
save_draft(
|
||||||
|
self.draft.clone().finalise().unwrap().as_bytes(),
|
||||||
|
context,
|
||||||
|
SpecialUsageMailbox::Drafts,
|
||||||
|
Flag::SEEN | Flag::DRAFT,
|
||||||
|
self.account_hash,
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Action::Compose(ComposeAction::ToggleSign) => {
|
||||||
|
let is_true = self.sign_mail.is_true();
|
||||||
|
self.sign_mail = ToggleFlag::from(!is_true);
|
||||||
|
self.dirty = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
@ -1469,7 +1511,7 @@ pub fn send_draft(
|
||||||
context.accounts[&account_hash].name()
|
context.accounts[&account_hash].name()
|
||||||
)),
|
)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
@ -1513,12 +1555,15 @@ pub fn save_draft(
|
||||||
) {
|
) {
|
||||||
match context.accounts[&account_hash].save_special(bytes, mailbox_type, flags) {
|
match context.accounts[&account_hash].save_special(bytes, mailbox_type, flags) {
|
||||||
Err(MeliError {
|
Err(MeliError {
|
||||||
summary, details, ..
|
summary,
|
||||||
|
details,
|
||||||
|
kind,
|
||||||
|
..
|
||||||
}) => {
|
}) => {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
summary.map(|s| s.into()),
|
summary.map(|s| s.into()),
|
||||||
details.into(),
|
details.into(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Ok(mailbox_hash) => {
|
Ok(mailbox_hash) => {
|
||||||
|
@ -1528,7 +1573,7 @@ pub fn save_draft(
|
||||||
"Message saved in `{}`",
|
"Message saved in `{}`",
|
||||||
&context.accounts[&account_hash].mailbox_entries[&mailbox_hash].name
|
&context.accounts[&account_hash].mailbox_entries[&mailbox_hash].name
|
||||||
),
|
),
|
||||||
Some(NotificationType::INFO),
|
Some(NotificationType::Info),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -929,7 +929,7 @@ impl Component for Listing {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Could not refresh.".to_string()),
|
Some("Could not refresh.".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::INFO),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1358,13 +1358,13 @@ impl CompactListing {
|
||||||
self.new_cursor_pos.2 = 0;
|
self.new_cursor_pos.2 = 0;
|
||||||
let message = format!(
|
let message = format!(
|
||||||
"Encountered an error while searching for `{}`: {}.",
|
"Encountered an error while searching for `{}`: {}.",
|
||||||
search_term, err
|
search_term, &err
|
||||||
);
|
);
|
||||||
log(message.clone(), ERROR);
|
log(message.clone(), ERROR);
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Could not perform search".to_string()),
|
Some("Could not perform search".to_string()),
|
||||||
message,
|
message,
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1710,7 +1710,7 @@ impl Component for CompactListing {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Could not perform search".to_string()),
|
Some("Could not perform search".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1739,7 +1739,7 @@ impl Component for CompactListing {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Could not perform search".to_string()),
|
Some("Could not perform search".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1567,7 +1567,7 @@ impl Component for ConversationsListing {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Could not perform search".to_string()),
|
Some("Could not perform search".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1348,7 +1348,7 @@ impl Component for PlainListing {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Could not perform search".to_string()),
|
Some("Could not perform search".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub fn verify_signature(a: &Attachment, context: &mut Context) -> Vec<u8> {
|
||||||
Ok((bytes, sig)) => {
|
Ok((bytes, sig)) => {
|
||||||
let bytes_file = create_temp_file(&bytes, None, None, true);
|
let bytes_file = create_temp_file(&bytes, None, None, true);
|
||||||
let signature_file = create_temp_file(sig, None, None, true);
|
let signature_file = create_temp_file(sig, None, None, true);
|
||||||
if let Ok(gpg) = Command::new(
|
match Command::new(
|
||||||
context
|
context
|
||||||
.settings
|
.settings
|
||||||
.pgp
|
.pgp
|
||||||
|
@ -48,29 +48,35 @@ pub fn verify_signature(a: &Attachment, context: &mut Context) -> Vec<u8> {
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
{
|
{
|
||||||
return gpg.wait_with_output().unwrap().stderr;
|
Ok(gpg) => {
|
||||||
} else {
|
return gpg.wait_with_output().unwrap().stderr;
|
||||||
context.replies.push_back(UIEvent::Notification(
|
}
|
||||||
Some(format!(
|
Err(err) => {
|
||||||
"Failed to launch {} to verify PGP signature",
|
context.replies.push_back(UIEvent::Notification(
|
||||||
context
|
Some(format!(
|
||||||
.settings
|
"Failed to launch {} to verify PGP signature",
|
||||||
.pgp
|
context
|
||||||
.gpg_binary
|
.settings
|
||||||
.as_ref()
|
.pgp
|
||||||
.map(String::as_str)
|
.gpg_binary
|
||||||
.unwrap_or("gpg2"),
|
.as_ref()
|
||||||
)),
|
.map(String::as_str)
|
||||||
"see meli.conf(5) for configuration setting pgp.gpg_binary".to_string(),
|
.unwrap_or("gpg2"),
|
||||||
Some(NotificationType::ERROR),
|
)),
|
||||||
));
|
format!(
|
||||||
|
"{}\nsee meli.conf(5) for configuration setting pgp.gpg_binary",
|
||||||
|
&err
|
||||||
|
),
|
||||||
|
Some(NotificationType::Error(melib::error::ErrorKind::External)),
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some(e.to_string()),
|
Some("Could not verify signature.".to_string()),
|
||||||
String::new(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,58 +342,60 @@ impl MailView {
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn();
|
.spawn();
|
||||||
if command_obj.is_err() {
|
match command_obj {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
Err(err) => {
|
||||||
Some(format!(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
"Failed to start html filter process: {}",
|
Some(format!(
|
||||||
filter_invocation,
|
"Failed to start html filter process: {}",
|
||||||
)),
|
filter_invocation,
|
||||||
String::new(),
|
)),
|
||||||
Some(NotificationType::ERROR),
|
err.to_string(),
|
||||||
));
|
Some(NotificationType::Error(melib::ErrorKind::External)),
|
||||||
return;
|
));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
let mut html_filter = command_obj.unwrap();
|
Ok(mut html_filter) => {
|
||||||
html_filter
|
html_filter
|
||||||
.stdin
|
.stdin
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.write_all(&v)
|
.write_all(&v)
|
||||||
.expect("Failed to write to stdin");
|
.expect("Failed to write to stdin");
|
||||||
*v = format!(
|
*v = format!(
|
||||||
"Text piped through `{}`. Press `v` to open in web browser. \n\n",
|
"Text piped through `{}`. Press `v` to open in web browser. \n\n",
|
||||||
filter_invocation
|
filter_invocation
|
||||||
)
|
)
|
||||||
.into_bytes();
|
.into_bytes();
|
||||||
v.extend(html_filter.wait_with_output().unwrap().stdout);
|
v.extend(html_filter.wait_with_output().unwrap().stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Ok(mut html_filter) = Command::new("w3m")
|
match Command::new("w3m")
|
||||||
.args(&["-I", "utf-8", "-T", "text/html"])
|
.args(&["-I", "utf-8", "-T", "text/html"])
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
{
|
{
|
||||||
html_filter
|
Ok(mut html_filter) => {
|
||||||
.stdin
|
html_filter
|
||||||
.as_mut()
|
.stdin
|
||||||
.unwrap()
|
.as_mut()
|
||||||
.write_all(&v)
|
.unwrap()
|
||||||
.expect("Failed to write to html filter stdin");
|
.write_all(&v)
|
||||||
*v = String::from(
|
.expect("Failed to write to html filter stdin");
|
||||||
|
*v = String::from(
|
||||||
"Text piped through `w3m`. Press `v` to open in web browser. \n\n",
|
"Text piped through `w3m`. Press `v` to open in web browser. \n\n",
|
||||||
)
|
)
|
||||||
.into_bytes();
|
.into_bytes();
|
||||||
v.extend(html_filter.wait_with_output().unwrap().stdout);
|
v.extend(html_filter.wait_with_output().unwrap().stdout);
|
||||||
} else {
|
}
|
||||||
context.replies.push_back(UIEvent::Notification(
|
Err(err) => {
|
||||||
Some(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
"Failed to find any application to use as html filter"
|
Some("Failed to launch w3m to use as html filter".to_string()),
|
||||||
.to_string(),
|
err.to_string(),
|
||||||
),
|
Some(NotificationType::Error(melib::ErrorKind::External)),
|
||||||
String::new(),
|
));
|
||||||
Some(NotificationType::ERROR),
|
}
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if a.is_signed() {
|
} else if a.is_signed() {
|
||||||
|
@ -469,7 +471,7 @@ impl MailView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Failed to open e-mail".to_string()),
|
Some("Failed to open e-mail".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
log(
|
log(
|
||||||
format!("Failed to open envelope: {}", err.to_string()),
|
format!("Failed to open envelope: {}", err.to_string()),
|
||||||
|
@ -563,7 +565,7 @@ impl MailView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
s,
|
s,
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::ErrorKind::None)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -877,7 +879,7 @@ impl Component for MailView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Failed to open e-mail".to_string()),
|
Some("Failed to open e-mail".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
log(
|
log(
|
||||||
format!("Failed to open envelope: {}", err.to_string()),
|
format!("Failed to open envelope: {}", err.to_string()),
|
||||||
|
@ -1219,7 +1221,7 @@ impl Component for MailView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Failed to open e-mail".to_string()),
|
Some("Failed to open e-mail".to_string()),
|
||||||
err_string,
|
err_string,
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1414,7 +1416,7 @@ impl Component for MailView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Failed to launch xdg-open".to_string()),
|
Some("Failed to launch xdg-open".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::ErrorKind::External)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1451,7 +1453,7 @@ impl Component for MailView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Failed to open e-mail".to_string()),
|
Some("Failed to open e-mail".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
log(
|
log(
|
||||||
format!("Failed to open envelope: {}", err.to_string()),
|
format!("Failed to open envelope: {}", err.to_string()),
|
||||||
|
@ -1475,7 +1477,7 @@ impl Component for MailView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some(format!("Failed to create file at {}", path.display())),
|
Some(format!("Failed to create file at {}", path.display())),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::ErrorKind::External)),
|
||||||
));
|
));
|
||||||
log(
|
log(
|
||||||
format!(
|
format!(
|
||||||
|
@ -1501,7 +1503,7 @@ impl Component for MailView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
format!("Saved at {}", &path.display()),
|
format!("Saved at {}", &path.display()),
|
||||||
Some(NotificationType::INFO),
|
Some(NotificationType::Info),
|
||||||
));
|
));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1515,17 +1517,17 @@ impl Component for MailView {
|
||||||
| ContentType::PGPSignature => {
|
| ContentType::PGPSignature => {
|
||||||
debug!(path);
|
debug!(path);
|
||||||
let mut f = match std::fs::File::create(path) {
|
let mut f = match std::fs::File::create(path) {
|
||||||
Err(e) => {
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some(format!("Failed to create file at {}", path)),
|
Some(format!("Failed to create file at {}", path)),
|
||||||
e.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::ErrorKind::External)),
|
||||||
));
|
));
|
||||||
log(
|
log(
|
||||||
format!(
|
format!(
|
||||||
"Failed to create file at {}: {}",
|
"Failed to create file at {}: {}",
|
||||||
path,
|
path,
|
||||||
e.to_string()
|
err.to_string()
|
||||||
),
|
),
|
||||||
ERROR,
|
ERROR,
|
||||||
);
|
);
|
||||||
|
@ -1557,17 +1559,17 @@ impl Component for MailView {
|
||||||
name: ref _name, ..
|
name: ref _name, ..
|
||||||
} => {
|
} => {
|
||||||
let mut f = match std::fs::File::create(path.trim()) {
|
let mut f = match std::fs::File::create(path.trim()) {
|
||||||
Err(e) => {
|
Err(err) => {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some(format!("Failed to create file at {}", path)),
|
Some(format!("Failed to create file at {}", path)),
|
||||||
e.to_string(),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::ErrorKind::External)),
|
||||||
));
|
));
|
||||||
log(
|
log(
|
||||||
format!(
|
format!(
|
||||||
"Failed to create file at {}: {}",
|
"Failed to create file at {}: {}",
|
||||||
path,
|
path,
|
||||||
e.to_string()
|
err.to_string()
|
||||||
),
|
),
|
||||||
ERROR,
|
ERROR,
|
||||||
);
|
);
|
||||||
|
@ -1583,7 +1585,7 @@ impl Component for MailView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
format!("Saved at {}", &path),
|
format!("Saved at {}", &path),
|
||||||
Some(NotificationType::INFO),
|
Some(NotificationType::Info),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
context
|
context
|
||||||
|
|
|
@ -101,31 +101,33 @@ impl EnvelopeView {
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn();
|
.spawn();
|
||||||
if command_obj.is_err() {
|
match command_obj {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
Err(err) => {
|
||||||
Some(format!(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
"Failed to start html filter process: {}",
|
Some(format!(
|
||||||
filter_invocation,
|
"Failed to start html filter process: {}",
|
||||||
)),
|
filter_invocation,
|
||||||
String::new(),
|
)),
|
||||||
Some(NotificationType::ERROR),
|
err.to_string(),
|
||||||
));
|
Some(NotificationType::Error(melib::ErrorKind::External)),
|
||||||
return;
|
));
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
let mut html_filter = command_obj.unwrap();
|
Ok(mut html_filter) => {
|
||||||
html_filter
|
html_filter
|
||||||
.stdin
|
.stdin
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.write_all(&v)
|
.write_all(&v)
|
||||||
.expect("Failed to write to stdin");
|
.expect("Failed to write to stdin");
|
||||||
*v = format!(
|
*v = format!(
|
||||||
"Text piped through `{}`. Press `v` to open in web browser. \n\n",
|
"Text piped through `{}`. Press `v` to open in web browser. \n\n",
|
||||||
filter_invocation
|
filter_invocation
|
||||||
)
|
)
|
||||||
.into_bytes();
|
.into_bytes();
|
||||||
v.extend(html_filter.wait_with_output().unwrap().stdout);
|
v.extend(html_filter.wait_with_output().unwrap().stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})),
|
})),
|
||||||
|
|
|
@ -43,32 +43,34 @@ impl HtmlView {
|
||||||
.stdin(Stdio::piped())
|
.stdin(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn();
|
.spawn();
|
||||||
if command_obj.is_err() {
|
match command_obj {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
Err(err) => {
|
||||||
Some(format!(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
"Failed to start html filter process: {}",
|
Some(format!(
|
||||||
filter_invocation,
|
"Failed to start html filter process: {}",
|
||||||
)),
|
filter_invocation,
|
||||||
String::new(),
|
)),
|
||||||
Some(NotificationType::ERROR),
|
err.to_string(),
|
||||||
));
|
Some(NotificationType::Error(melib::ErrorKind::External)),
|
||||||
String::from_utf8_lossy(&bytes).to_string()
|
));
|
||||||
} else {
|
String::from_utf8_lossy(&bytes).to_string()
|
||||||
let mut html_filter = command_obj.unwrap();
|
}
|
||||||
html_filter
|
Ok(mut html_filter) => {
|
||||||
.stdin
|
html_filter
|
||||||
.as_mut()
|
.stdin
|
||||||
.unwrap()
|
.as_mut()
|
||||||
.write_all(&bytes)
|
.unwrap()
|
||||||
.expect("Failed to write to html filter stdin");
|
.write_all(&bytes)
|
||||||
let mut display_text = format!(
|
.expect("Failed to write to html filter stdin");
|
||||||
"Text piped through `{}`. Press `v` to open in web browser. \n\n",
|
let mut display_text = format!(
|
||||||
filter_invocation
|
"Text piped through `{}`. Press `v` to open in web browser. \n\n",
|
||||||
);
|
filter_invocation
|
||||||
display_text.push_str(&String::from_utf8_lossy(
|
);
|
||||||
&html_filter.wait_with_output().unwrap().stdout,
|
display_text.push_str(&String::from_utf8_lossy(
|
||||||
));
|
&html_filter.wait_with_output().unwrap().stdout,
|
||||||
display_text
|
));
|
||||||
|
display_text
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if let Ok(mut html_filter) = Command::new("w3m")
|
} else if let Ok(mut html_filter) = Command::new("w3m")
|
||||||
.args(&["-I", "utf-8", "-T", "text/html"])
|
.args(&["-I", "utf-8", "-T", "text/html"])
|
||||||
|
@ -93,7 +95,7 @@ impl HtmlView {
|
||||||
context.replies.push_back(UIEvent::Notification(
|
context.replies.push_back(UIEvent::Notification(
|
||||||
Some("Failed to find any application to use as html filter".to_string()),
|
Some("Failed to find any application to use as html filter".to_string()),
|
||||||
String::new(),
|
String::new(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(melib::error::ErrorKind::None)),
|
||||||
));
|
));
|
||||||
String::from_utf8_lossy(&bytes).to_string()
|
String::from_utf8_lossy(&bytes).to_string()
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,17 +71,46 @@ mod dbus {
|
||||||
let mut notification = notify_rust::Notification::new();
|
let mut notification = notify_rust::Notification::new();
|
||||||
notification
|
notification
|
||||||
.appname("meli")
|
.appname("meli")
|
||||||
.icon("mail-message-new")
|
|
||||||
.summary(title.as_ref().map(String::as_str).unwrap_or("meli"))
|
.summary(title.as_ref().map(String::as_str).unwrap_or("meli"))
|
||||||
.body(&escape_str(body));
|
.body(&escape_str(body));
|
||||||
if *kind == Some(NotificationType::NEWMAIL) {
|
match *kind {
|
||||||
notification.hint(notify_rust::Hint::Category("email".to_owned()));
|
Some(NotificationType::NewMail) => {
|
||||||
|
notification.hint(notify_rust::Hint::Category("email".to_owned()));
|
||||||
|
notification.icon("mail-message-new");
|
||||||
|
notification.sound_name("message-new-email");
|
||||||
|
}
|
||||||
|
Some(NotificationType::SentMail) => {
|
||||||
|
notification.hint(notify_rust::Hint::Category("email".to_owned()));
|
||||||
|
notification.icon("mail-send");
|
||||||
|
notification.sound_name("message-sent-email");
|
||||||
|
}
|
||||||
|
Some(NotificationType::Saved) => {
|
||||||
|
notification.icon("document-save");
|
||||||
|
}
|
||||||
|
Some(NotificationType::Info) => {
|
||||||
|
notification.icon("dialog-information");
|
||||||
|
}
|
||||||
|
Some(NotificationType::Error(melib::ErrorKind::Authentication)) => {
|
||||||
|
notification.icon("dialog-password");
|
||||||
|
}
|
||||||
|
Some(NotificationType::Error(melib::ErrorKind::Bug)) => {
|
||||||
|
notification.icon("face-embarrassed");
|
||||||
|
}
|
||||||
|
Some(NotificationType::Error(melib::ErrorKind::None))
|
||||||
|
| Some(NotificationType::Error(melib::ErrorKind::External)) => {
|
||||||
|
notification.icon("dialog-error");
|
||||||
|
}
|
||||||
|
Some(NotificationType::Error(melib::ErrorKind::Network)) => {
|
||||||
|
notification.icon("network-error");
|
||||||
|
}
|
||||||
|
Some(NotificationType::Error(melib::ErrorKind::Timeout)) => {
|
||||||
|
notification.icon("network-offline");
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
if settings.play_sound.is_true() {
|
if settings.play_sound.is_true() {
|
||||||
if let Some(ref sound_path) = settings.sound_file {
|
if let Some(ref sound_path) = settings.sound_file {
|
||||||
notification.hint(notify_rust::Hint::SoundFile(sound_path.to_owned()));
|
notification.hint(notify_rust::Hint::SoundFile(sound_path.to_owned()));
|
||||||
} else {
|
|
||||||
notification.sound_name("message-new-email");
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
notification.hint(notify_rust::Hint::SuppressSound(true));
|
notification.hint(notify_rust::Hint::SuppressSound(true));
|
||||||
|
@ -186,7 +215,7 @@ impl Component for NotificationCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if *kind == Some(NotificationType::NEWMAIL) {
|
if *kind == Some(NotificationType::NewMail) {
|
||||||
if let Some(ref path) = context.settings.notifications.xbiff_file_path {
|
if let Some(ref path) = context.settings.notifications.xbiff_file_path {
|
||||||
if let Err(err) = update_xbiff(path) {
|
if let Err(err) = update_xbiff(path) {
|
||||||
debug!("Could not update xbiff file: {:?}", &err);
|
debug!("Could not update xbiff file: {:?}", &err);
|
||||||
|
|
|
@ -856,7 +856,7 @@ impl Account {
|
||||||
self.name,
|
self.name,
|
||||||
self.mailbox_entries[&mailbox_hash].name()
|
self.mailbox_entries[&mailbox_hash].name()
|
||||||
),
|
),
|
||||||
Some(crate::types::NotificationType::NEWMAIL),
|
Some(crate::types::NotificationType::NewMail),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
RefreshEventKind::Remove(env_hash) => {
|
RefreshEventKind::Remove(env_hash) => {
|
||||||
|
@ -906,7 +906,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{} watcher exited with error", &self.name)),
|
Some(format!("{} watcher exited with error", &self.name)),
|
||||||
e.to_string(),
|
e.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
*/
|
*/
|
||||||
|
@ -914,7 +914,7 @@ impl Account {
|
||||||
return Some(Notification(
|
return Some(Notification(
|
||||||
Some("Account watch failed".into()),
|
Some("Account watch failed".into()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1303,7 +1303,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
format!("'`{}` has been subscribed.", &path),
|
format!("'`{}` has been subscribed.", &path),
|
||||||
Some(crate::types::NotificationType::INFO),
|
Some(crate::types::NotificationType::Info),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1323,7 +1323,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
format!("'`{}` has been unsubscribed.", &path),
|
format!("'`{}` has been unsubscribed.", &path),
|
||||||
Some(crate::types::NotificationType::INFO),
|
Some(crate::types::NotificationType::Info),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1468,7 +1468,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: authentication error", &self.name)),
|
Some(format!("{}: authentication error", &self.name)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
self.is_online = Err(err);
|
self.is_online = Err(err);
|
||||||
|
@ -1511,7 +1511,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: could not fetch mailbox", &self.name)),
|
Some(format!("{}: could not fetch mailbox", &self.name)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
self.mailbox_entries
|
self.mailbox_entries
|
||||||
|
@ -1636,7 +1636,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: could not set flag", &self.name)),
|
Some(format!("{}: could not set flag", &self.name)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1665,7 +1665,7 @@ impl Account {
|
||||||
"Message was stored in {} so that you can restore it manually.",
|
"Message was stored in {} so that you can restore it manually.",
|
||||||
file.path.display()
|
file.path.display()
|
||||||
),
|
),
|
||||||
Some(crate::types::NotificationType::INFO),
|
Some(crate::types::NotificationType::Info),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1678,7 +1678,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some("Could not send message".to_string()),
|
Some("Could not send message".to_string()),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1694,7 +1694,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: could not save message", &self.name)),
|
Some(format!("{}: could not save message", &self.name)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1706,7 +1706,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: could not delete message", &self.name)),
|
Some(format!("{}: could not delete message", &self.name)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1727,7 +1727,7 @@ impl Account {
|
||||||
&self.name, path
|
&self.name, path
|
||||||
)),
|
)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1807,7 +1807,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: could not delete mailbox", &self.name)),
|
Some(format!("{}: could not delete mailbox", &self.name)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1862,7 +1862,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: mailbox deleted successfully", &self.name)),
|
Some(format!("{}: mailbox deleted successfully", &self.name)),
|
||||||
String::new(),
|
String::new(),
|
||||||
Some(crate::types::NotificationType::INFO),
|
Some(crate::types::NotificationType::Info),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1882,7 +1882,7 @@ impl Account {
|
||||||
&self.name
|
&self.name
|
||||||
)),
|
)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1894,7 +1894,7 @@ impl Account {
|
||||||
&self.name
|
&self.name
|
||||||
)),
|
)),
|
||||||
String::new(),
|
String::new(),
|
||||||
Some(crate::types::NotificationType::INFO),
|
Some(crate::types::NotificationType::Info),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1912,7 +1912,7 @@ impl Account {
|
||||||
&self.name
|
&self.name
|
||||||
)),
|
)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1924,7 +1924,7 @@ impl Account {
|
||||||
&self.name
|
&self.name
|
||||||
)),
|
)),
|
||||||
String::new(),
|
String::new(),
|
||||||
Some(crate::types::NotificationType::INFO),
|
Some(crate::types::NotificationType::Info),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1947,7 +1947,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: watch thread failed", &self.name)),
|
Some(format!("{}: watch thread failed", &self.name)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1967,7 +1967,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: {} failed", &self.name, name,)),
|
Some(format!("{}: {} failed", &self.name, name,)),
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
Some(crate::types::NotificationType::ERROR),
|
Some(crate::types::NotificationType::Error(err.kind)),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
@ -1977,7 +1977,7 @@ impl Account {
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
.send(ThreadEvent::UIEvent(UIEvent::Notification(
|
||||||
Some(format!("{}: {} succeeded", &self.name, name,)),
|
Some(format!("{}: {} succeeded", &self.name, name,)),
|
||||||
String::new(),
|
String::new(),
|
||||||
Some(crate::types::NotificationType::INFO),
|
Some(crate::types::NotificationType::Info),
|
||||||
)))
|
)))
|
||||||
.expect("Could not send event on main channel");
|
.expect("Could not send event on main channel");
|
||||||
}
|
}
|
||||||
|
|
18
src/state.rs
18
src/state.rs
|
@ -851,7 +851,7 @@ impl State {
|
||||||
self.context.replies.push_back(UIEvent::Notification(
|
self.context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
format!("Account {} was not found.", account_name),
|
format!("Account {} was not found.", account_name),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(ErrorKind::None)),
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -867,7 +867,7 @@ impl State {
|
||||||
"Account {} doesn't have an sqlite3 search backend.",
|
"Account {} doesn't have an sqlite3 search backend.",
|
||||||
account_name
|
account_name
|
||||||
),
|
),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(ErrorKind::None)),
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -888,14 +888,14 @@ impl State {
|
||||||
self.context.replies.push_back(UIEvent::Notification(
|
self.context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
"Message index rebuild started.".to_string(),
|
"Message index rebuild started.".to_string(),
|
||||||
Some(NotificationType::INFO),
|
Some(NotificationType::Info),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(err) => {
|
||||||
self.context.replies.push_back(UIEvent::Notification(
|
self.context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
Some("Message index rebuild failed".to_string()),
|
||||||
format!("Message index rebuild failed: {}.", e),
|
err.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(err.kind)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -906,7 +906,7 @@ impl State {
|
||||||
None,
|
None,
|
||||||
"Message index rebuild failed: meli is not built with sqlite3 support."
|
"Message index rebuild failed: meli is not built with sqlite3 support."
|
||||||
.to_string(),
|
.to_string(),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(ErrorKind::None)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
AccountAction(ref account_name, PrintAccountSetting(ref setting)) => {
|
AccountAction(ref account_name, PrintAccountSetting(ref setting)) => {
|
||||||
|
@ -930,7 +930,7 @@ impl State {
|
||||||
self.context.replies.push_back(UIEvent::Notification(
|
self.context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
format!("Account {} was not found.", account_name),
|
format!("Account {} was not found.", account_name),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::Error(ErrorKind::None)),
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
25
src/types.rs
25
src/types.rs
|
@ -91,22 +91,23 @@ pub enum ForkType {
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||||
pub enum NotificationType {
|
pub enum NotificationType {
|
||||||
INFO,
|
Info,
|
||||||
ERROR,
|
Error(melib::error::ErrorKind),
|
||||||
NEWMAIL,
|
NewMail,
|
||||||
|
SentMail,
|
||||||
|
Saved,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl core::fmt::Display for NotificationType {
|
impl core::fmt::Display for NotificationType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
match *self {
|
||||||
f,
|
NotificationType::Info => write!(f, "info"),
|
||||||
"{}",
|
NotificationType::Error(melib::error::ErrorKind::None) => write!(f, "error"),
|
||||||
match *self {
|
NotificationType::Error(kind) => write!(f, "error: {}", kind),
|
||||||
NotificationType::INFO => "info",
|
NotificationType::NewMail => write!(f, "new mail"),
|
||||||
NotificationType::ERROR => "error",
|
NotificationType::SentMail => write!(f, "sent mail"),
|
||||||
NotificationType::NEWMAIL => "new-mail",
|
NotificationType::Saved => write!(f, "saved"),
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue