Add HtmlView, bounds checking in pager scrolling and better attachment view

embed
Manos Pitsidianakis 2018-08-10 11:06:47 +03:00
parent befe00dea6
commit 8462d1aceb
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
8 changed files with 54 additions and 26 deletions

View File

@ -367,7 +367,7 @@ fn display_addr(input: &[u8]) -> IResult<&[u8], Address> {
let mut flag = false;
for (i, b) in input[0..].iter().enumerate() {
if *b == b'<' {
display_name.length = if i != 0 { i - 1 } else { 0 };
display_name.length = i.saturating_sub(1); // if i != 0 { i - 1 } else { 0 };
flag = true;
break;
}
@ -395,9 +395,9 @@ fn display_addr(input: &[u8]) -> IResult<&[u8], Address> {
IResult::Error(e) => IResult::Error(e),
IResult::Incomplete(i) => IResult::Incomplete(i),
IResult::Done(rest, raw) => {
display_name.length = raw.find(b"<").unwrap();
address_spec.offset = display_name.length + 1;
address_spec.length = raw.len() - display_name.length - 2;
display_name.length = raw.find(b"<").unwrap().saturating_sub(1);
address_spec.offset = display_name.length + 2;
address_spec.length = raw.len().saturating_sub(display_name.length).saturating_sub(3);
IResult::Done(
rest,
Address::Mailbox(MailboxAddress {

View File

@ -228,7 +228,6 @@ impl MailListing {
}
} else {
// Populate `CellBuffer` with every entry.
// TODO: Lazy load?
let mut idx = 0;
for y in 0..=self.length {
if idx >= self.length {

View File

@ -25,27 +25,32 @@ use std::process::{Command, Stdio};
pub struct HtmlView {
pager: Pager,
bytes: Vec<u8>
bytes: Vec<u8>,
}
impl HtmlView {
pub fn new(bytes: Vec<u8>) -> Self {
let mut html_filter = Command::new("w3m")
.args(&["-I", "utf-8", "-T", "text/html"])
.args(&["-I", "utf-8", "-T", "text/html"])
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.expect("Failed to start html filter process");
html_filter.stdin.as_mut().unwrap().write_all(&bytes).expect("Failed to write to w3m stdin");
let mut display_text = String::from("Text piped through `w3m`. Press `v` to open in web browser. \n\n");
display_text.push_str(&String::from_utf8_lossy(&html_filter.wait_with_output().unwrap().stdout));
html_filter
.stdin
.as_mut()
.unwrap()
.write_all(&bytes)
.expect("Failed to write to w3m stdin");
let mut display_text =
String::from("Text piped through `w3m`. Press `v` to open in web browser. \n\n");
display_text.push_str(&String::from_utf8_lossy(
&html_filter.wait_with_output().unwrap().stdout,
));
let buf = MailView::plain_text_to_buf(&display_text, true);
let pager = Pager::from_buf(&buf, None);
HtmlView {
pager,
bytes
}
HtmlView { pager, bytes }
}
}
@ -66,20 +71,19 @@ impl Component for HtmlView {
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|_| {
panic!("Failed to start {}", binary.display())
});
.unwrap_or_else(|_| panic!("Failed to start {}", binary.display()));
context.temp_files.push(p);
} else {
context.replies.push_back(UIEvent {
id: 0,
event_type: UIEventType::StatusNotification(format!(
"Couldn't find a default application for html files.")),
"Couldn't find a default application for html files."
)),
});
}
return;
},
_ => {},
}
_ => {}
}
self.pager.process_event(event, context);
}

View File

@ -262,7 +262,7 @@ impl Component for MailView {
grid[(x, y)].set_fg(Color::Default);
}
let (x, y) = write_string_to_grid(
&format!("Message-ID: {}", envelope.message_id_raw()),
&format!("Message-ID: <{}>", envelope.message_id_raw()),
grid,
Color::Byte(33),
Color::Default,
@ -313,8 +313,10 @@ impl Component for MailView {
};
self.dirty = false;
}
if let Some(s) = self.subview.as_mut() {
s.draw(grid, (set_y(upper_left, y + 1), bottom_right), context);
if self.mode == ViewMode::Subview {
if let Some(s) = self.subview.as_mut() {
s.draw(grid, (set_y(upper_left, y + 1), bottom_right), context);
}
} else if let Some(p) = self.pager.as_mut() {
p.draw(grid, (set_y(upper_left, y + 1), bottom_right), context);
}

View File

@ -277,6 +277,11 @@ impl Component for Pager {
}
self.dirty = false;
if self.cursor_pos > 0 && self.cursor_pos + 1 + height!(area) > self.height {
self.cursor_pos = self.cursor_pos.saturating_sub(1);
return;
}
if self.height == 0 || self.height == self.cursor_pos || self.width == 0 {
return;
}
@ -303,7 +308,7 @@ impl Component for Pager {
}
}
UIEventType::Input(Key::Char('j')) => {
if self.height > 0 && self.cursor_pos < self.height - 1 {
if self.height > 0 && self.cursor_pos + 1 < self.height {
self.cursor_pos += 1;
self.dirty = true;
}

View File

@ -371,6 +371,7 @@ impl<W: Write> State<W> {
return;
}
UIEventType::EditDraft(mut file) => {
eprintln!("edit draft event");
use std::io::Read;
use std::process::{Command, Stdio};
let mut output = Command::new("msmtp")
@ -386,7 +387,6 @@ impl<W: Write> State<W> {
f.read_to_end(&mut buf).unwrap();
in_pipe.write_all(&buf).unwrap();
std::fs::remove_file(file.path()).unwrap();
}
output.wait_with_output().expect("Failed to read stdout");

View File

@ -22,6 +22,7 @@
use std;
use std::io::Write;
use std::path::PathBuf;
use std::fs::OpenOptions;
use uuid::Uuid;
@ -38,8 +39,9 @@ impl Drop for File {
impl File {
pub fn file(&mut self) -> std::fs::File {
std::fs::File::create(&self.path).unwrap()
OpenOptions::new().read(true).write(true).create(true).open(&self.path).unwrap()
}
pub fn path(&self) -> &PathBuf {
&self.path
}

View File

@ -55,6 +55,22 @@ pub fn set_y(p: Pos, new_y: usize) -> Pos {
/// ```
pub type Area = (Pos, Pos);
/// Get an area's height
///
/// Example:
/// ```
/// use ui::position;
///
/// let new_area = ((0, 0), (1, 1));
/// assert_eq!(height!(new_area), 1);
/// ```
#[macro_export]
macro_rules! height {
($a:expr) => {
(get_y(bottom_right!($a))).saturating_sub(get_y(upper_left!($a)))
};
}
/// Get the upper left Position of an area
///
/// Example: