Some listing refactoring

async
Manos Pitsidianakis 2020-01-15 12:38:18 +02:00
parent f58ed387dd
commit 0ac10aa4d0
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
4 changed files with 87 additions and 68 deletions

View File

@ -141,6 +141,9 @@ pub trait MailListingTrait: ListingTrait {
fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]>; fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]>;
fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadHash; 8]>; fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadHash; 8]>;
fn redraw_list(&mut self, context: &Context, items: Box<dyn Iterator<Item = ThreadHash>>) {
unimplemented!()
}
} }
pub trait ListingTrait: Component { pub trait ListingTrait: Component {

View File

@ -469,7 +469,11 @@ impl ListingTrait for CompactListing {
self.data_columns.columns[0] = self.data_columns.columns[0] =
CellBuffer::new_with_context(0, 0, Cell::with_char(' '), context); CellBuffer::new_with_context(0, 0, Cell::with_char(' '), context);
} }
self.redraw_list(context); self.redraw_list(
context,
Box::new(self.filtered_selection.clone().into_iter())
as Box<dyn Iterator<Item = ThreadHash>>,
);
} }
Err(e) => { Err(e) => {
self.cursor_pos.2 = 0; self.cursor_pos.2 = 0;
@ -545,9 +549,13 @@ impl CompactListing {
&self, &self,
e: &Envelope, e: &Envelope,
context: &Context, context: &Context,
thread_node: &ThreadNode, threads: &Threads,
is_snoozed: bool, hash: ThreadHash,
) -> EntryStrings { ) -> EntryStrings {
let is_snoozed: bool = threads.is_snoozed(hash);
let date =
threads.thread_dates[&melib::thread::find_thread_group(threads.thread_nodes(), hash)];
let thread_node = &threads[&hash];
let folder_hash = &context.accounts[self.cursor_pos.0][self.cursor_pos.1] let folder_hash = &context.accounts[self.cursor_pos.0][self.cursor_pos.1]
.unwrap() .unwrap()
.folder .folder
@ -591,7 +599,7 @@ impl CompactListing {
subject.truncate_at_boundary(150); subject.truncate_at_boundary(150);
if thread_node.len() > 0 { if thread_node.len() > 0 {
EntryStrings { EntryStrings {
date: DateString(ConversationsListing::format_date(context, thread_node)), date: DateString(ConversationsListing::format_date(context, date)),
subject: SubjectString(format!("{} ({})", subject, thread_node.len(),)), subject: SubjectString(format!("{} ({})", subject, thread_node.len(),)),
flag: FlagString(format!( flag: FlagString(format!(
"{}{}", "{}{}",
@ -603,7 +611,7 @@ impl CompactListing {
} }
} else { } else {
EntryStrings { EntryStrings {
date: DateString(ConversationsListing::format_date(context, thread_node)), date: DateString(ConversationsListing::format_date(context, date)),
subject: SubjectString(subject), subject: SubjectString(subject),
flag: FlagString(format!( flag: FlagString(format!(
"{}{}", "{}{}",
@ -667,10 +675,22 @@ impl CompactListing {
self.view = ThreadView::new(self.new_cursor_pos, None, context); self.view = ThreadView::new(self.new_cursor_pos, None, context);
} }
self.redraw_list(context); let threads = &context.accounts[self.cursor_pos.0].collection.threads[&folder_hash];
threads.sort_by(
self.sort,
self.subsort,
&context.accounts[self.cursor_pos.0].collection.envelopes,
);
self.all_threads.clear();
self.redraw_list(
context,
Box::new(threads.root_iter().collect::<Vec<ThreadHash>>().into_iter())
as Box<dyn Iterator<Item = ThreadHash>>,
);
} }
fn redraw_list(&mut self, context: &Context) { fn redraw_list(&mut self, context: &Context, items: Box<dyn Iterator<Item = ThreadHash>>) {
let account = &context.accounts[self.cursor_pos.0]; let account = &context.accounts[self.cursor_pos.0];
let mailbox = &account[self.cursor_pos.1].unwrap(); let mailbox = &account[self.cursor_pos.1].unwrap();
@ -694,18 +714,7 @@ impl CompactListing {
SmallVec::new(), SmallVec::new(),
); );
threads.sort_by(self.sort, self.subsort, &account.collection.envelopes); for (idx, root_idx) in items.enumerate() {
let mut refresh_mailbox = false;
let threads_iter = if self.filter_term.is_empty() {
refresh_mailbox = true;
self.all_threads.clear();
Box::new(threads.root_iter()) as Box<dyn Iterator<Item = ThreadHash>>
} else {
Box::new(self.filtered_selection.iter().map(|h| *h))
as Box<dyn Iterator<Item = ThreadHash>>
};
for (idx, root_idx) in threads_iter.enumerate() {
self.length += 1; self.length += 1;
let thread_node = &threads.thread_nodes()[&root_idx]; let thread_node = &threads.thread_nodes()[&root_idx];
let i = thread_node.message().unwrap_or_else(|| { let i = thread_node.message().unwrap_or_else(|| {
@ -729,12 +738,7 @@ impl CompactListing {
let root_envelope: EnvelopeRef = let root_envelope: EnvelopeRef =
context.accounts[self.cursor_pos.0].collection.get_env(i); context.accounts[self.cursor_pos.0].collection.get_env(i);
let entry_strings = self.make_entry_string( let entry_strings = self.make_entry_string(&root_envelope, context, threads, root_idx);
&root_envelope,
context,
thread_node,
threads.is_snoozed(root_idx),
);
row_widths.1.push( row_widths.1.push(
entry_strings entry_strings
.date .date
@ -768,10 +772,8 @@ impl CompactListing {
min_width.4, min_width.4,
entry_strings.subject.grapheme_width() + 1 + entry_strings.tags.grapheme_width(), entry_strings.subject.grapheme_width() + 1 + entry_strings.tags.grapheme_width(),
); /* subject */ ); /* subject */
rows.push(entry_strings); rows.push(((idx, root_idx), entry_strings));
if refresh_mailbox {
self.all_threads.insert(root_idx); self.all_threads.insert(root_idx);
}
self.order.insert(root_idx, idx); self.order.insert(root_idx, idx);
self.selection.insert(root_idx, false); self.selection.insert(root_idx, false);
@ -797,14 +799,8 @@ impl CompactListing {
self.data_columns.columns[4] = self.data_columns.columns[4] =
CellBuffer::new_with_context(min_width.4, rows.len(), Cell::with_char(' '), context); CellBuffer::new_with_context(min_width.4, rows.len(), Cell::with_char(' '), context);
self.data_columns.segment_tree[4] = row_widths.4.into(); self.data_columns.segment_tree[4] = row_widths.4.into();
let threads_iter = if self.filter_term.is_empty() {
Box::new(threads.root_iter()) as Box<dyn Iterator<Item = ThreadHash>>
} else {
Box::new(self.filtered_selection.iter().map(|h| *h))
as Box<dyn Iterator<Item = ThreadHash>>
};
for ((idx, root_idx), strings) in threads_iter.enumerate().zip(rows) { for ((idx, root_idx), strings) in rows {
let thread_node = &threads.thread_nodes()[&root_idx]; let thread_node = &threads.thread_nodes()[&root_idx];
let i = thread_node.message().unwrap_or_else(|| { let i = thread_node.message().unwrap_or_else(|| {
let mut iter_ptr = thread_node.children()[0]; let mut iter_ptr = thread_node.children()[0];
@ -975,11 +971,19 @@ impl CompactListing {
} }
fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadHash { fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadHash {
let account = &context.accounts[self.cursor_pos.0]; //let account = &context.accounts[self.cursor_pos.0];
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); //let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
let threads = &account.collection.threads[&folder_hash];
if self.filter_term.is_empty() { if self.filter_term.is_empty() {
threads.root_set(cursor) *self
.order
.iter()
.find(|(_, &r)| r == cursor)
.unwrap_or_else(|| {
debug!("self.order empty ? cursor={} {:#?}", cursor, &self.order);
panic!();
})
.0
//threads.root_set(cursor)
} else { } else {
self.filtered_selection[cursor] self.filtered_selection[cursor]
} }
@ -1020,12 +1024,7 @@ impl CompactListing {
Color::Default Color::Default
} }
}; };
let strings = self.make_entry_string( let strings = self.make_entry_string(&envelope, context, threads, thread_hash);
&envelope,
context,
&threads[&thread_hash],
threads.is_snoozed(thread_hash),
);
drop(envelope); drop(envelope);
let columns = &mut self.data_columns.columns; let columns = &mut self.data_columns.columns;
let min_width = ( let min_width = (

View File

@ -562,7 +562,10 @@ impl ConversationsListing {
subject.truncate_at_boundary(150); subject.truncate_at_boundary(150);
if thread_node.len() > 0 { if thread_node.len() > 0 {
EntryStrings { EntryStrings {
date: DateString(ConversationsListing::format_date(context, thread_node)), date: DateString(ConversationsListing::format_date(
context,
thread_node.date(),
)),
subject: SubjectString(format!("{} ({})", subject, thread_node.len(),)), subject: SubjectString(format!("{} ({})", subject, thread_node.len(),)),
flag: FlagString(format!( flag: FlagString(format!(
"{}{}", "{}{}",
@ -574,7 +577,10 @@ impl ConversationsListing {
} }
} else { } else {
EntryStrings { EntryStrings {
date: DateString(ConversationsListing::format_date(context, thread_node)), date: DateString(ConversationsListing::format_date(
context,
thread_node.date(),
)),
subject: SubjectString(subject), subject: SubjectString(subject),
flag: FlagString(format!( flag: FlagString(format!(
"{}{}", "{}{}",
@ -890,8 +896,8 @@ impl ConversationsListing {
} }
} }
pub(super) fn format_date(context: &Context, thread_node: &ThreadNode) -> String { pub(super) fn format_date(context: &Context, epoch: UnixTimestamp) -> String {
let d = std::time::UNIX_EPOCH + std::time::Duration::from_secs(thread_node.date()); let d = std::time::UNIX_EPOCH + std::time::Duration::from_secs(epoch);
let now: std::time::Duration = std::time::SystemTime::now() let now: std::time::Duration = std::time::SystemTime::now()
.duration_since(d) .duration_since(d)
.unwrap_or_else(|_| std::time::Duration::new(std::u64::MAX, 0)); .unwrap_or_else(|_| std::time::Duration::new(std::u64::MAX, 0));
@ -912,7 +918,7 @@ impl ConversationsListing {
if n / (24 * 60 * 60) == 1 { "" } else { "s" } if n / (24 * 60 * 60) == 1 { "" } else { "s" }
), ),
_ => melib::datetime::timestamp_to_string( _ => melib::datetime::timestamp_to_string(
thread_node.date(), epoch,
context context
.settings .settings
.listing .listing
@ -925,11 +931,20 @@ impl ConversationsListing {
} }
fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadHash { fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadHash {
let account = &context.accounts[self.cursor_pos.0]; //let account = &context.accounts[self.cursor_pos.0];
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); //let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
let threads = &account.collection.threads[&folder_hash]; //let threads = &account.collection.threads[&folder_hash];
if self.filter_term.is_empty() { if self.filter_term.is_empty() {
threads.root_set(cursor) *self
.order
.iter()
.find(|(_, &r)| r == cursor)
.unwrap_or_else(|| {
debug!("self.order empty ? cursor={} {:#?}", cursor, &self.order);
panic!();
})
.0
//threads.root_set(cursor)
} else { } else {
self.filtered_selection[cursor] self.filtered_selection[cursor]
} }

View File

@ -418,9 +418,10 @@ impl Component for MailView {
format!("Subject: {}", envelope.subject()) format!("Subject: {}", envelope.subject())
format!("Message-ID: <{}>", envelope.message_id_raw()) format!("Message-ID: <{}>", envelope.message_id_raw())
); );
if self.expand_headers && envelope.in_reply_to().is_some() { if self.expand_headers {
if let Some(val) = envelope.in_reply_to_display() {
print_header!( print_header!(
format!("In-Reply-To: {}", envelope.in_reply_to_display().unwrap()) format!("In-Reply-To: {}", val)
format!( format!(
"References: {}", "References: {}",
envelope envelope
@ -432,6 +433,7 @@ impl Component for MailView {
) )
); );
} }
}
if let Some(list_management::ListActions { if let Some(list_management::ListActions {
ref id, ref id,
ref archive, ref archive,