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
memfd
Manos Pitsidianakis 2020-01-02 00:07:19 +02:00
parent 3d84f3b9ad
commit 8694278369
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
6 changed files with 67 additions and 17 deletions

View File

@ -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,
})
}
}

View File

@ -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)]

View File

@ -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 = {

View File

@ -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 {

View File

@ -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>,

View File

@ -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 {