Create MailView to replace pager in MailListing

embed
Manos Pitsidianakis 2018-07-22 18:02:44 +03:00
parent 7ed707a309
commit dcb1fe6c3a
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 141 additions and 121 deletions

View File

@ -18,9 +18,9 @@ pub struct MailListing {
content: CellBuffer,
/// If we must redraw on next redraw event
dirty: bool,
/// If `self.pager` exists or not.
/// If `self.view` exists or not.
unfocused: bool,
pager: Option<Pager>,
view: Option<MailView>,
}
impl MailListing {
@ -39,7 +39,7 @@ impl MailListing {
content: content,
dirty: true,
unfocused: false,
pager: None,
view: None,
}
}
/// Fill the `self.content` `CellBuffer` with the contents of the account folder the user has
@ -126,7 +126,7 @@ impl MailListing {
} else {
Color::Default
};
let (x, y) = write_string_to_grid(&MailListing::make_thread_entry(envelope, idx, indentation, container, &indentations, len),
let (x, _) = write_string_to_grid(&MailListing::make_thread_entry(envelope, idx, indentation, container, &indentations, len),
&mut content,
fg_color,
bg_color,
@ -272,23 +272,6 @@ impl MailListing {
context.dirty_areas.push_back(area);
}
/// Create a pager for the `Envelope` currently under the cursor.
fn draw_mail_view(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
{
let envelope_idx: usize = {
let threaded = context.accounts[self.cursor_pos.0].runtime_settings.threaded;
let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap();
if threaded {
mailbox.threaded_mail(self.cursor_pos.2)
} else {
self.cursor_pos.2
}
};
self.pager = Some(Pager::from_envelope((self.cursor_pos.0, self.cursor_pos.1), envelope_idx, context));
}
self.pager.as_mut().map(|p| p.draw(grid, area, context));
}
fn make_thread_entry(envelope: &Envelope, idx: usize, indent: usize,
container: &Container, indentations: &Vec<bool>, idx_width: usize) -> String {
let has_sibling = container.has_sibling();
@ -341,7 +324,6 @@ impl MailListing {
format!("{} days ago{}", n / (24*60*60), " ".repeat(9))
},
_ => {
let date = envelope.datetime();
envelope.datetime().format("%Y-%m-%d %H:%M:%S").to_string()
},
@ -358,9 +340,7 @@ impl Component for MailListing {
}
self.dirty = false;
/* Draw the entire list */
self.draw_list(grid,
area,
context);
self.draw_list(grid, area, context);
} else {
let upper_left = upper_left!(area);
let bottom_right = bottom_right!(area);
@ -371,7 +351,7 @@ impl Component for MailListing {
/* Render the mail body in a pager, basically copy what HSplit does */
let total_rows = get_y(bottom_right) - get_y(upper_left);
let pager_ratio = context.settings.pager.pager_ratio;
let pager_ratio = context.runtime_settings.pager.pager_ratio;
let bottom_entity_rows = (pager_ratio*total_rows )/100;
if bottom_entity_rows > total_rows {
@ -398,99 +378,17 @@ impl Component for MailListing {
for i in get_x(upper_left)..=get_x(bottom_right) {
grid[(i, mid)].set_ch('─');
}
context.dirty_areas.push_back((set_y(upper_left, mid), set_y(bottom_right, mid)));
}
// TODO: Make headers view configurable
/* Draw header */
let y =
{
let threaded = context.accounts[self.cursor_pos.0].runtime_settings.threaded;
let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap();
let envelope: &Envelope = if threaded {
let i = mailbox.threaded_mail(self.cursor_pos.2);
&mailbox.collection[i]
} else {
&mailbox.collection[self.cursor_pos.2]
};
let (x,y) = write_string_to_grid(&format!("Date: {}", envelope.date_as_str()),
grid,
Color::Byte(33),
Color::Default,
(set_y(upper_left, mid+1), bottom_right),
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
let (x,y) = write_string_to_grid(&format!("From: {}", envelope.from()),
grid,
Color::Byte(33),
Color::Default,
(set_y(upper_left, y+1), bottom_right),
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
let (x,y) = write_string_to_grid(&format!("To: {}", envelope.to()),
grid,
Color::Byte(33),
Color::Default,
(set_y(upper_left, y+1), bottom_right),
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
let (x,y) = write_string_to_grid(&format!("Subject: {}", envelope.subject()),
grid,
Color::Byte(33),
Color::Default,
(set_y(upper_left, y+1), bottom_right),
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
let (x, y) = write_string_to_grid(&format!("Message-ID: {}", envelope.message_id_raw()),
grid,
Color::Byte(33),
Color::Default,
(set_y(upper_left, y+1), bottom_right),
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
clear_area(grid,
(set_y(upper_left, y+1), set_y(bottom_right, y+2)));
context.dirty_areas.push_back((set_y(upper_left, mid), set_y(bottom_right, y+1)));
y + 2
};
if !self.dirty {
if let Some(ref mut p) = self.pager {
p.draw(grid,
((get_x(upper_left), y), bottom_right),
context);
}
self.view.as_mut().map(|v| v.draw(grid, (set_y(upper_left, mid + 1), bottom_right), context));
return;
}
self.view = Some(MailView::new(self.cursor_pos, None, None));
self.view.as_mut().map(|v| v.draw(grid, (set_y(upper_left, mid + 1), bottom_right), context));
self.dirty = false;
/* Draw body */
self.draw_mail_view(grid,
((get_x(upper_left), y), bottom_right),
context);
}
}
fn process_event(&mut self, event: &UIEvent, context: &mut Context) {
@ -561,7 +459,7 @@ impl Component for MailListing {
UIEventType::Input(Key::Esc) | UIEventType::Input(Key::Char('i')) if self.unfocused == true => {
self.unfocused = false;
self.dirty = true;
self.pager = None;
self.view = None;
},
UIEventType::Input(Key::Char(k @ 'J')) | UIEventType::Input(Key::Char(k @ 'K')) => {
@ -617,7 +515,7 @@ impl Component for MailListing {
},
UIEventType::RefreshMailbox(_) => {
self.dirty = true;
self.pager = None;
self.view = None;
},
UIEventType::ChangeMode(UIMode::Normal) => {
self.dirty = true;
@ -640,11 +538,11 @@ impl Component for MailListing {
_ => {
},
}
if let Some(ref mut p) = self.pager {
p.process_event(event, context);
if let Some(ref mut v) = self.view {
v.process_event(event, context);
}
}
fn is_dirty(&self) -> bool {
self.dirty || self.pager.as_ref().map(|p| p.is_dirty()).unwrap_or(false)
self.dirty || self.view.as_ref().map(|p| p.is_dirty()).unwrap_or(false)
}
}

View File

@ -3,7 +3,9 @@
use super::*;
pub mod listing;
pub mod view;
pub use listing::*;
pub use view::*;
#[derive(Debug)]

View File

@ -0,0 +1,121 @@
use super::*;
pub struct MailView {
coordinates: (usize, usize, usize),
pager: Option<Pager>,
subview: Option<Box<MailView>>,
dirty: bool,
}
impl MailView {
pub fn new(coordinates: (usize, usize, usize), pager: Option<Pager>, subview: Option<Box<MailView>>) -> Self {
MailView {
coordinates: coordinates,
pager: pager,
subview: subview,
dirty: true,
}
}
}
impl Component for MailView {
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
let upper_left = upper_left!(area);
let bottom_right = bottom_right!(area);
let (envelope_idx, y): (usize, usize) = {
let threaded = context.accounts[self.coordinates.0].runtime_settings.threaded;
let mailbox = &mut context.accounts[self.coordinates.0][self.coordinates.1].as_ref().unwrap().as_ref().unwrap();
let envelope_idx: usize = if threaded {
mailbox.threaded_mail(self.coordinates.2)
} else {
self.coordinates.2
};
let envelope: &Envelope = &mailbox.collection[envelope_idx];
let (x,y) = write_string_to_grid(&format!("Date: {}", envelope.date_as_str()),
grid,
Color::Byte(33),
Color::Default,
area,
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
let (x,y) = write_string_to_grid(&format!("From: {}", envelope.from()),
grid,
Color::Byte(33),
Color::Default,
(set_y(upper_left, y+1), bottom_right),
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
let (x,y) = write_string_to_grid(&format!("To: {}", envelope.to()),
grid,
Color::Byte(33),
Color::Default,
(set_y(upper_left, y+1), bottom_right),
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
let (x,y) = write_string_to_grid(&format!("Subject: {}", envelope.subject()),
grid,
Color::Byte(33),
Color::Default,
(set_y(upper_left, y+1), bottom_right),
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
let (x, y) = write_string_to_grid(&format!("Message-ID: {}", envelope.message_id_raw()),
grid,
Color::Byte(33),
Color::Default,
(set_y(upper_left, y+1), bottom_right),
true);
for x in x..=get_x(bottom_right) {
grid[(x, y)].set_ch(' ');
grid[(x, y)].set_bg(Color::Default);
grid[(x, y)].set_fg(Color::Default);
}
clear_area(grid,
(set_y(upper_left, y+1), set_y(bottom_right, y+2)));
context.dirty_areas.push_back((upper_left, set_y(bottom_right, y+1)));
(envelope_idx, y + 1)
};
if self.dirty {
self.pager = Some(Pager::from_envelope((self.coordinates.0, self.coordinates.1), envelope_idx, context));
self.dirty = false;
}
self.pager.as_mut().map(|p| p.draw(grid, (set_y(upper_left, y + 1),bottom_right), context));
}
fn process_event(&mut self, event: &UIEvent, context: &mut Context) {
if let Some(ref mut sub) = self.subview {
sub.process_event(event, context);
} else {
if let Some(ref mut p) = self.pager {
p.process_event(event, context);
}
}
}
fn is_dirty(&self) -> bool {
self.dirty || self.pager.as_ref().map(|p| p.is_dirty()).unwrap_or(false) ||
self.subview.as_ref().map(|p| p.is_dirty()).unwrap_or(false)
}
}

View File

@ -172,7 +172,7 @@ impl Pager {
let mut text = text.to_string();
if envelope.body().count_attachments() > 1 {
eprintln!("text was {}", text);
text = envelope.body().attachments().iter().fold(text, |mut s, a| { s.push_str(&format!("{}\n", a)); s });
text = envelope.body().attachments().iter().enumerate().fold(text, |mut s, (idx, a)| { s.push_str(&format!("[{}] {}\n\n", idx, a)); s });
eprintln!("text is {}", text);
}
let mut lines: Vec<&str> = text.trim().split('\n').collect();
@ -208,7 +208,6 @@ impl Pager {
let width = lines.iter().map(|l| l.len()).max().unwrap_or(0);
if width > 0 {
for (i, l) in lines.iter().enumerate() {
eprintln!("line: {:?}", l);
write_string_to_grid(l,
content,
Color::Default,
@ -235,11 +234,10 @@ impl Component for Pager {
if self.height == 0 || self.height == self.cursor_pos || self.width == 0 {
return;
}
eprintln!("drawing");
clear_area(grid,
(upper_left, bottom_right));
context.dirty_areas.push_back((upper_left, bottom_right));
//let pager_context: usize = context.settings.pager.pager_context;
//let pager_stop: bool = context.settings.pager.pager_stop;
//let rows = y(bottom_right) - y(upper_left);
@ -248,6 +246,7 @@ impl Component for Pager {
context.dirty_areas.push_back(area);
}
fn process_event(&mut self, event: &UIEvent, _context: &mut Context) {
eprintln!("pager got {:?}", event);
match event.event_type {
UIEventType::Input(Key::Char('k')) => {
if self.cursor_pos > 0 {