Make date printing prettier in entry formatting

embed
Manos Pitsidianakis 2018-07-22 11:14:23 +03:00
parent 00235fe814
commit a7993d48f8
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
3 changed files with 230 additions and 202 deletions

View File

@ -141,7 +141,7 @@ pub struct Envelope {
references: Option<References>,
datetime: Option<chrono::DateTime<chrono::FixedOffset>>,
timestamp: i64,
timestamp: u64,
thread: usize,
operation_token: Arc<Box<BackendOpGenerator>>,
@ -254,9 +254,10 @@ if let Some(ref mut d) = datetime {
}
}
}
pub fn date(&self) -> i64 {
pub fn date(&self) -> u64 {
self.timestamp
}
pub fn datetime(&self) -> chrono::DateTime<chrono::FixedOffset> {
self.datetime.unwrap_or_else(|| {
chrono::FixedOffset::west(0)
@ -345,7 +346,7 @@ fn set_to(&mut self, new_val: String) -> () {
fn set_in_reply_to(&mut self, new_val: &str) -> () {
let slice = match parser::message_id(new_val.as_bytes()).to_full_result() {
Ok(v) => v,
Err(v) => {
Err(_) => {
self.in_reply_to = None;
return;
}
@ -358,7 +359,7 @@ fn set_subject(&mut self, new_val: String) -> () {
fn set_message_id(&mut self, new_val: &str) -> () {
let slice = match parser::message_id(new_val.as_bytes()).to_full_result() {
Ok(v) => v,
Err(v) => {
Err(_) => {
self.message_id = None;
return;
}
@ -368,7 +369,7 @@ fn set_message_id(&mut self, new_val: &str) -> () {
fn push_references(&mut self, new_val: &str) -> () {
let slice = match parser::message_id(new_val.as_bytes()).to_full_result() {
Ok(v) => v,
Err(v) => {
Err(_) => {
return;
}
};
@ -434,7 +435,7 @@ pub fn set_thread(&mut self, new_val: usize) -> () {
}
pub fn set_datetime(&mut self, new_val: chrono::DateTime<chrono::FixedOffset>) -> () {
self.datetime = Some(new_val);
self.timestamp = new_val.timestamp();
self.timestamp = new_val.timestamp() as u64;
}
pub fn flags(&self) -> Flag {
self.flags

View File

@ -27,9 +27,7 @@ extern crate fnv;
use self::fnv::FnvHashMap;
use std;
type UnixTimestamp = i64;
type UnixTimestamp = u64;
/// A `Container` struct is needed to describe the thread tree forest during creation of threads.
/// Because of Rust's memory model, we store indexes of Envelopes inside a collection instead of

View File

@ -54,7 +54,6 @@ impl MailListing {
self.length = if threaded {
mailbox.threaded_collection.len()
} else {
mailbox.len()
};
@ -75,17 +74,23 @@ impl MailListing {
// TODO: Fix the threaded hell and refactor stuff into seperate functions and/or modules.
if threaded {
let mut indentations: Vec<bool> = Vec::with_capacity(6);
let mut thread_idx = 0; // needed for alternate thread colors
/* Draw threaded view. */
let mut iter = mailbox
.threaded_collection
.iter()
.enumerate()
.peekable();
let len = mailbox.threaded_collection.len().to_string().chars().count();
/* This is just a desugared for loop so that we can use .peek() */
while let Some((idx, i)) = iter.next() {
let container = mailbox.thread(*i);
let indentation = container.indentation();
if indentation == 0 {
thread_idx += 1;
}
assert_eq!(container.has_message(), true);
match iter.peek() {
Some(&(_, x))
@ -111,12 +116,12 @@ impl MailListing {
};
let bg_color = if !envelope.is_seen() {
Color::Byte(251)
} else if idx % 2 == 0 {
} else if thread_idx % 2 == 0 {
Color::Byte(236)
} else {
Color::Default
};
let (x, y) = write_string_to_grid(&MailListing::make_thread_entry(envelope, idx, indentation, container, &indentations),
let (x, y) = write_string_to_grid(&MailListing::make_thread_entry(envelope, idx, indentation, container, &indentations, len),
&mut content,
fg_color,
bg_color,
@ -280,12 +285,12 @@ impl MailListing {
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>) -> String {
container: &Container, indentations: &Vec<bool>, idx_width: usize) -> String {
let has_sibling = container.has_sibling();
let has_parent = container.has_parent();
let show_subject = container.show_subject();
let mut s = format!("{} {} ", idx, &envelope.datetime().format("%Y-%m-%d %H:%M:%S").to_string());
let mut s = format!("{}{}{} ", idx, " ".repeat(idx_width + 2 - (idx.to_string().chars().count())), MailListing::format_date(&envelope));
for i in 0..indent {
if indentations.len() > i && indentations[i]
{
@ -307,13 +312,37 @@ impl MailListing {
}
s.push('─'); s.push('>');
}
s.push_str(&format!(" {}", envelope.body().count_attachments()));
if show_subject {
s.push_str(&format!("{:.85}", envelope.subject()));
}
let attach_count = envelope.body().count_attachments();
if attach_count > 0 {
s.push_str(&format!(" {}", attach_count));
}
s
}
fn format_date(envelope: &Envelope) -> String {
let d = std::time::UNIX_EPOCH + std::time::Duration::from_secs(envelope.date());
let now: std::time::Duration = std::time::SystemTime::now().duration_since(d).unwrap();
match now.as_secs() {
n if n < 10*60*60 => {
format!("{} hours ago{}", n / (60*60), " ".repeat(8))
},
n if n < 24*60*60 => {
format!("{} hours ago{}", n / (60*60), " ".repeat(7))
},
n if n < 4*24*60*60 => {
format!("{} days ago{}", n / (24*60*60), " ".repeat(9))
},
_ => {
let date = envelope.datetime();
envelope.datetime().format("%Y-%m-%d %H:%M:%S").to_string()
},
}
}
}
impl Component for MailListing {