summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-01-02 00:07:19 +0200
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-01-02 00:08:21 +0200
commit8694278369a312a1c4e605adedb7ed631c02c95a (patch)
tree1ed59609464687a9c320d211e312e930b758f6df
parent3d84f3b9adaf97f10aa18aa24edc7234566eacaf (diff)
ui: add auto_choose_multipart_alternative
Choose text/html by default if text/plain is empty in multipart/alternative attachments This happens in some newsletters I've come upon
-rw-r--r--melib/src/conf.rs29
-rw-r--r--melib/src/email/attachment_types.rs8
-rw-r--r--ui/src/components/mail/view.rs30
-rw-r--r--ui/src/conf.rs6
-rw-r--r--ui/src/conf/notifications.rs3
-rw-r--r--ui/src/conf/pager.rs8
6 files changed, 67 insertions, 17 deletions
diff --git a/melib/src/conf.rs b/melib/src/conf.rs
index 1b7fed64..985e38eb 100644
--- a/melib/src/conf.rs
+++ b/melib/src/conf.rs
@@ -78,9 +78,9 @@ pub struct FolderConf {
pub alias: Option<String>,
#[serde(default = "true_val")]
pub autoload: bool,
- #[serde(deserialize_with = "toggleflag_de")]
+ #[serde(default)]
pub subscribe: ToggleFlag,
- #[serde(deserialize_with = "toggleflag_de")]
+ #[serde(default)]
pub ignore: ToggleFlag,
#[serde(default = "none")]
pub usage: Option<SpecialUsageMailbox>,
@@ -158,18 +158,6 @@ impl ToggleFlag {
}
}
-pub fn toggleflag_de<'de, D>(deserializer: D) -> std::result::Result<ToggleFlag, D::Error>
-where
- D: Deserializer<'de>,
-{
- let s = <bool>::deserialize(deserializer);
- Ok(match s {
- Err(_) => ToggleFlag::Unset,
- Ok(true) => ToggleFlag::True,
- Ok(false) => ToggleFlag::False,
- })
-}
-
impl Serialize for ToggleFlag {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
@@ -182,3 +170,16 @@ impl Serialize for ToggleFlag {
}
}
}
+
+impl<'de> Deserialize<'de> for ToggleFlag {
+ fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let s = <bool>::deserialize(deserializer);
+ Ok(match s? {
+ true => ToggleFlag::True,
+ false => ToggleFlag::False,
+ })
+ }
+}
diff --git a/melib/src/email/attachment_types.rs b/melib/src/email/attachment_types.rs
index ac05affb..2a6e74d9 100644
--- a/melib/src/email/attachment_types.rs
+++ b/melib/src/email/attachment_types.rs
@@ -249,6 +249,14 @@ impl ContentType {
_ => None,
}
}
+
+ pub fn parts(&self) -> Option<&Vec<Attachment>> {
+ if let ContentType::Multipart { ref parts, .. } = self {
+ Some(parts)
+ } else {
+ None
+ }
+ }
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
diff --git a/ui/src/components/mail/view.rs b/ui/src/components/mail/view.rs
index a6328eae..7fcf78b4 100644
--- a/ui/src/components/mail/view.rs
+++ b/ui/src/components/mail/view.rs
@@ -21,6 +21,7 @@
use super::*;
use melib::list_management;
+use melib::parser::BytesExt;
use std::convert::TryFrom;
use std::process::{Command, Stdio};
@@ -605,6 +606,35 @@ impl Component for MailView {
self.subview = Some(Box::new(HtmlView::new(&body, context)));
self.mode = ViewMode::Subview;
}
+ ViewMode::Normal
+ if context
+ .settings
+ .pager
+ .auto_choose_multipart_alternative
+ .is_true()
+ && match body.content_type {
+ ContentType::Multipart {
+ kind: MultipartType::Alternative,
+ ref parts,
+ ..
+ } => parts.iter().all(|p| {
+ p.is_html() || (p.is_text() && p.body().trim().is_empty())
+ }),
+ _ => false,
+ } =>
+ {
+ self.subview = Some(Box::new(HtmlView::new(
+ &body
+ .content_type
+ .parts()
+ .unwrap()
+ .into_iter()
+ .find(|a| a.is_html())
+ .unwrap_or(&body),
+ context,
+ )));
+ self.mode = ViewMode::Subview;
+ }
ViewMode::Subview | ViewMode::ContactSelector(_) => {}
ViewMode::Raw => {
let text = {
diff --git a/ui/src/conf.rs b/ui/src/conf.rs
index ab15904b..550ab3d8 100644
--- a/ui/src/conf.rs
+++ b/ui/src/conf.rs
@@ -46,7 +46,7 @@ use self::terminal::TerminalSettings;
use crate::pager::PagerSettings;
use crate::plugins::Plugin;
use melib::backends::SpecialUsageMailbox;
-use melib::conf::{toggleflag_de, AccountSettings, FolderConf, ToggleFlag};
+use melib::conf::{AccountSettings, FolderConf, ToggleFlag};
use melib::error::*;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
@@ -454,6 +454,10 @@ mod default_vals {
pub(in crate::conf) fn internal_value_false() -> super::ToggleFlag {
super::ToggleFlag::InternalVal(false)
}
+
+ pub(in crate::conf) fn internal_value_true() -> super::ToggleFlag {
+ super::ToggleFlag::InternalVal(true)
+ }
}
mod deserializers {
diff --git a/ui/src/conf/notifications.rs b/ui/src/conf/notifications.rs
index beeac081..028d4fa9 100644
--- a/ui/src/conf/notifications.rs
+++ b/ui/src/conf/notifications.rs
@@ -20,7 +20,6 @@
*/
use super::default_vals::internal_value_false;
-use super::toggleflag_de;
fn none() -> Option<String> {
None
@@ -38,7 +37,7 @@ pub struct NotificationsSettings {
/// Default: None
#[serde(default = "none")]
pub xbiff_file_path: Option<String>,
- #[serde(deserialize_with = "toggleflag_de", default = "internal_value_false")]
+ #[serde(default = "internal_value_false")]
pub play_sound: super::ToggleFlag,
#[serde(default = "none")]
pub sound_file: Option<String>,
diff --git a/ui/src/conf/pager.rs b/ui/src/conf/pager.rs
index 39dde1c6..40c11d12 100644
--- a/ui/src/conf/pager.rs
+++ b/ui/src/conf/pager.rs
@@ -21,6 +21,8 @@
use super::default_vals::*;
use super::deserializers::*;
+use melib::ToggleFlag;
+
/// Settings for the pager function.
#[derive(Debug, Deserialize, Clone, Default, Serialize)]
pub struct PagerSettings {
@@ -68,6 +70,12 @@ pub struct PagerSettings {
/// Default: 80
#[serde(default = "eighty_val")]
pub minimum_width: usize,
+
+ /// Choose `text/html` alternative if `text/plain` is empty in `multipart/alternative`
+ /// attachments.
+ /// Default: true
+ #[serde(default = "internal_value_true")]
+ pub auto_choose_multipart_alternative: ToggleFlag,
}
fn eighty_val() -> usize {