/*
* meli - ui crate.
*
* Copyright 2017-2018 Manos Pitsidianakis
*
* This file is part of meli.
*
* meli is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* meli is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with meli. If not, see <http://www.gnu.org/licenses/>.
*/
use super::*;
use linkify::{Link, LinkFinder};
use std::convert::TryFrom;
use std::process::{Command, Stdio};
mod list_management;
mod html;
pub use self::html::*;
mod thread;
pub use self::thread::*;
mod envelope;
pub use self::envelope::*;
use mime_apps::query_default_app;
#[derive(PartialEq, Debug, Clone)]
enum ViewMode {
Normal,
Url,
Attachment(usize),
Raw,
Subview,
ContactSelector(Selector),
}
impl Default for ViewMode {
fn default() -> Self {
ViewMode::Normal
}
}
impl ViewMode {
fn is_attachment(&self) -> bool {
match self {
ViewMode::Attachment(_) => true,
_ => false,
}
}
}
/// Contains an Envelope view, with sticky headers, a pager for the body, and subviews for more
/// menus
#[derive(Debug, Default)]
pub struct MailView {
coordinates: (usize, usize, EnvelopeHash),
pager: Option<Pager>,
subview: Option<Box<dyn Component>>,
dirty: bool,
mode: ViewMode,
expand_headers: bool,
cmd_buf: String,
id: ComponentId,
}
impl Clone for MailView {
fn clone(&self) -> Self {
MailView {
subview: None,
cmd_buf: String::with_capacity(4),
pager: self.pager.clone(),
mode: self.mode.clone(),
..*self
}
}
}
impl fmt::Display for MailView {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// TODO display subject/info
write!(f, "{}", MailView::DESCRIPTION)
}
}
impl MailView {
const DESCRIPTION: &'static str = "mail";
pub fn new(
coordinates: (usize, usize, EnvelopeHash),
pager: Option<Pager>,
subview: Option<Box<dyn Component>>,
) -> Self {
MailView {
coordinates,
pager,
subview,
dirty: true,
mode: ViewMode::Normal,
expand_headers: false,
cmd_buf: String::with_capacity(4),
id: ComponentId::new_v4(),
}
}
/// Returns the string to be displayed in the Viewer
fn attachment_to_text<'closure, 's: 'closure, 'context: 's>(
&'s self,
body: &'context Attachment,
context: &'context mut Context,
) -> String {
let finder = LinkFinder::new();
let body_text = String::from_utf8_lossy(&decode_rec(
body,
Some(Box::new(move |a: &'closure Attachment, v: &mut Vec<u8>| {
if a.content_type().is_text_html() {
use std::io::Write;
let settings = context.accounts[self.coordinates.0].runtime_settings.conf();
/* FIXME: duplication with view/html.rs */
if let Some(filter_invocation) = settings.html_filter() {
let parts = split_command!(filter_invocation);
let (cmd, args) = (parts[0], &parts[1..]);
let command_obj = Command::new(cmd)
.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.