browse: attachment save hotkey

This commit is contained in:
FliegendeWurst 2021-06-11 16:14:55 +02:00 committed by Arne Keller
parent cf037127dc
commit 316ac357a3
2 changed files with 51 additions and 8 deletions

View File

@ -1,9 +1,9 @@
#![feature(internal_output_capture)] #![feature(internal_output_capture)]
use std::{cell::RefCell, cmp, collections::{HashMap, HashSet}, env, fmt::Display, io, sync::{Arc, atomic::{AtomicBool, Ordering}}}; use std::{cell::RefCell, cmp, collections::{HashMap, HashSet}, env, fmt::Display, io, rc::Rc, sync::{Arc, atomic::{AtomicBool, Ordering}}};
use std::result::Result as StdResult; use std::result::Result as StdResult;
use cursive::{Cursive, Vec2, WrapMethod, view::ViewWrapper}; use cursive::{Cursive, Vec2, WrapMethod, traits::Boxable, view::ViewWrapper, views::{Dialog, EditView}};
use cursive::align::HAlign; use cursive::align::HAlign;
use cursive::event::{Event, Key}; use cursive::event::{Event, Key};
use cursive::traits::Identifiable; use cursive::traits::Identifiable;
@ -306,6 +306,43 @@ fn show_listing(mailbox: &str) -> Result<()> {
s.add_fullscreen_layer(ResizedView::with_full_screen(it)); s.add_fullscreen_layer(ResizedView::with_full_screen(it));
MAIL_FULLSCREEN.store(true, Ordering::SeqCst); MAIL_FULLSCREEN.store(true, Ordering::SeqCst);
} }
})
.on_event('s', |s| {
if let Some((bytes, name)) = s.call_on_name("mail", |mail: &mut MailPartView| {
mail.part.map(|x| (x.get_body_raw().unwrap(), x.get_content_disposition().params.get("filename").cloned()))
}).flatten() {
let mut default_path = CONFIG.get().unwrap().read().browse.base_save_path.display().to_string();
if let Some(name) = name {
default_path.push('/');
default_path += &name;
}
let bytes = Rc::new(bytes);
let bytes2 = bytes.clone();
s.add_layer(
Dialog::new()
.title("Enter filename")
.padding_lrtb(1, 1, 1, 0)
.content(
EditView::new()
.content(default_path)
.on_submit(move |s, path| {
std::fs::write(path, bytes.as_ref()).unwrap();
s.pop_layer();
})
.with_name("filename")
.fixed_width(100),
)
.button("Ok", move |s| {
let path = s
.call_on_name("filename", move |view: &mut EditView| {
view.get_content()
})
.unwrap();
std::fs::write(path.as_ref(), bytes2.as_ref()).unwrap();
s.pop_layer();
}),
);
}
}); });
let mail_content: MailScrollerView = mail_content; let mail_content: MailScrollerView = mail_content;
let mail_content = mail_content.with_name("mail_scroller"); let mail_content = mail_content.with_name("mail_scroller");
@ -454,6 +491,7 @@ impl MailPartView {
fn set_scroll(&mut self, scroll: bool) { fn set_scroll(&mut self, scroll: bool) {
self.scroll = scroll; self.scroll = scroll;
self.layouted_text_with_scroll = !scroll;
if let Some(text) = self.text.as_mut() { if let Some(text) = self.text.as_mut() {
text.set_show_scrollbars(scroll); text.set_show_scrollbars(scroll);
} }
@ -476,8 +514,10 @@ impl MailPartView {
let html = part.get_body().unwrap(); let html = part.get_body().unwrap();
eprintln!("HTML layout using {} width, length {:?}", size.x, html.len()); eprintln!("HTML layout using {} width, length {:?}", size.x, html.len());
html2text::from_read(html.as_bytes(), size.x) html2text::from_read(html.as_bytes(), size.x)
} else { } else if part.ctype.mimetype.starts_with("text/") {
part.get_body().unwrap() part.get_body().unwrap()
} else {
"binary data".into()
}; };
let mut text = TextView::new(body); let mut text = TextView::new(body);
text.set_wrap_method(self.wrap); text.set_wrap_method(self.wrap);
@ -489,8 +529,6 @@ impl MailPartView {
impl View for MailPartView { impl View for MailPartView {
fn draw(&self, printer: &cursive::Printer) { fn draw(&self, printer: &cursive::Printer) {
eprintln!("drawing with {:?}", printer.output_size);
eprintln!("have text {:?}", self.text.is_some());
if let Some(text) = self.text.as_ref() { if let Some(text) = self.text.as_ref() {
text.draw(printer) text.draw(printer)
} }
@ -502,10 +540,10 @@ impl View for MailPartView {
if self.cached_size != Some(given_size) { if self.cached_size != Some(given_size) {
self.setup_text(given_size); self.setup_text(given_size);
} else { } else {
if !self.layouted_text_with_scroll && self.scroll && self.expected_text_height.unwrap_or(0) > given_size.y { if self.layouted_text_with_scroll != self.scroll && self.expected_text_height.unwrap_or(0) > given_size.y {
eprintln!("reconsidering given {:?}", given_size); eprintln!("reconsidering given {:?}", given_size);
self.setup_text(given_size.map_x(|x| x-2)); self.setup_text(given_size.map_x(|x| x-2));
self.layouted_text_with_scroll = true; self.layouted_text_with_scroll = self.scroll;
} else { } else {
return; return;
} }

View File

@ -520,10 +520,12 @@ impl MaildirExtension for Maildir {
} }
} }
#[deprecated]
pub fn store_i64(x: u64) -> i64 { pub fn store_i64(x: u64) -> i64 {
unsafe { std::mem::transmute(x) } unsafe { std::mem::transmute(x) }
} }
#[deprecated]
pub fn load_i64(x: i64) -> u64 { pub fn load_i64(x: i64) -> u64 {
unsafe { std::mem::transmute(x) } unsafe { std::mem::transmute(x) }
} }
@ -626,6 +628,8 @@ pub struct Browse {
#[serde(deserialize_with = "deserialize_style")] #[serde(deserialize_with = "deserialize_style")]
#[serde(serialize_with = "serialize_style")] #[serde(serialize_with = "serialize_style")]
pub deleted_style: Style, pub deleted_style: Style,
#[serde(default)]
pub base_save_path: PathBuf,
} }
impl Default for Browse { impl Default for Browse {
@ -634,7 +638,8 @@ impl Default for Browse {
show_email_addresses: Default::default(), show_email_addresses: Default::default(),
unread_style: default_unread_style(), unread_style: default_unread_style(),
trashed_style: default_trashed_style(), trashed_style: default_trashed_style(),
deleted_style: default_deleted_style() deleted_style: default_deleted_style(),
base_save_path: directories_next::UserDirs::new().expect("no user dirs").download_dir().expect("no download directory").to_owned()
} }
} }
} }