Re-enable conversations listing style
Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>pull/319/head
parent
031d0f7dc7
commit
c751b2e845
|
@ -230,8 +230,8 @@ impl<T> RowsState<T> {
|
|||
}
|
||||
}
|
||||
|
||||
//mod conversations;
|
||||
//pub use self::conversations::*;
|
||||
mod conversations;
|
||||
pub use self::conversations::*;
|
||||
|
||||
mod compact;
|
||||
pub use self::compact::*;
|
||||
|
@ -927,7 +927,7 @@ pub trait ListingTrait: Component {
|
|||
#[derive(Debug)]
|
||||
pub enum ListingComponent {
|
||||
Compact(Box<CompactListing>),
|
||||
//Conversations(Box<ConversationsListing>),
|
||||
Conversations(Box<ConversationsListing>),
|
||||
Offline(Box<OfflineListing>),
|
||||
Plain(Box<PlainListing>),
|
||||
Threaded(Box<ThreadListing>),
|
||||
|
@ -940,7 +940,7 @@ impl std::ops::Deref for ListingComponent {
|
|||
fn deref(&self) -> &Self::Target {
|
||||
match &self {
|
||||
Compact(ref l) => l.as_ref(),
|
||||
//Conversations(ref l) => l.as_ref(),
|
||||
Conversations(ref l) => l.as_ref(),
|
||||
Offline(ref l) => l.as_ref(),
|
||||
Plain(ref l) => l.as_ref(),
|
||||
Threaded(ref l) => l.as_ref(),
|
||||
|
@ -952,7 +952,7 @@ impl std::ops::DerefMut for ListingComponent {
|
|||
fn deref_mut(&mut self) -> &mut (dyn MailListingTrait + 'static) {
|
||||
match self {
|
||||
Compact(l) => l.as_mut(),
|
||||
//Conversations(l) => l.as_mut(),
|
||||
Conversations(l) => l.as_mut(),
|
||||
Offline(l) => l.as_mut(),
|
||||
Plain(l) => l.as_mut(),
|
||||
Threaded(l) => l.as_mut(),
|
||||
|
@ -964,7 +964,7 @@ impl ListingComponent {
|
|||
fn id(&self) -> ComponentId {
|
||||
match self {
|
||||
Compact(l) => l.as_component().id(),
|
||||
//Conversations(l) => l.as_component().id(),
|
||||
Conversations(l) => l.as_component().id(),
|
||||
Offline(l) => l.as_component().id(),
|
||||
Plain(l) => l.as_component().id(),
|
||||
Threaded(l) => l.as_component().id(),
|
||||
|
@ -1041,7 +1041,7 @@ impl std::fmt::Display for Listing {
|
|||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self.component {
|
||||
Compact(ref l) => write!(f, "{}", l),
|
||||
//Conversations(ref l) => write!(f, "{}", l),
|
||||
Conversations(ref l) => write!(f, "{}", l),
|
||||
Offline(ref l) => write!(f, "{}", l),
|
||||
Plain(ref l) => write!(f, "{}", l),
|
||||
Threaded(ref l) => write!(f, "{}", l),
|
||||
|
@ -2458,7 +2458,7 @@ impl Component for Listing {
|
|||
self.component.id(),
|
||||
match &self.component {
|
||||
Compact(l) => l.as_component(),
|
||||
//Conversations(l) => l.as_component(),
|
||||
Conversations(l) => l.as_component(),
|
||||
Offline(l) => l.as_component(),
|
||||
Plain(l) => l.as_component(),
|
||||
Threaded(l) => l.as_component(),
|
||||
|
@ -2474,7 +2474,7 @@ impl Component for Listing {
|
|||
self.component.id(),
|
||||
match &mut self.component {
|
||||
Compact(l) => l.as_component_mut(),
|
||||
//Conversations(l) => l.as_component_mut(),
|
||||
Conversations(l) => l.as_component_mut(),
|
||||
Offline(l) => l.as_component_mut(),
|
||||
Plain(l) => l.as_component_mut(),
|
||||
Threaded(l) => l.as_component_mut(),
|
||||
|
@ -3124,7 +3124,7 @@ impl Listing {
|
|||
|
||||
fn set_index_style(&mut self, new_style: IndexStyle, context: &mut Context) {
|
||||
let old = match new_style {
|
||||
IndexStyle::Conversations | IndexStyle::Plain => {
|
||||
IndexStyle::Plain => {
|
||||
if matches!(self.component, Plain(_)) {
|
||||
return;
|
||||
}
|
||||
|
@ -3153,17 +3153,17 @@ impl Listing {
|
|||
&mut self.component,
|
||||
Compact(CompactListing::new(self.id, coordinates)),
|
||||
)
|
||||
} //IndexStyle::Conversations => {
|
||||
// return;
|
||||
// //if matches!(self.component, Conversations(_)) {
|
||||
// // return;
|
||||
// //}
|
||||
// //let coordinates = self.component.coordinates();
|
||||
// //std::mem::replace(
|
||||
// // &mut self.component,
|
||||
// // Conversations(ConversationsListing::new(self.id,
|
||||
// // coordinates)),
|
||||
//}
|
||||
}
|
||||
IndexStyle::Conversations => {
|
||||
if matches!(self.component, Conversations(_)) {
|
||||
return;
|
||||
}
|
||||
let coordinates = self.component.coordinates();
|
||||
std::mem::replace(
|
||||
&mut self.component,
|
||||
Conversations(ConversationsListing::new(self.id, coordinates)),
|
||||
)
|
||||
}
|
||||
};
|
||||
if let MenuEntryCursor::Mailbox(idx) = self.cursor_pos.menu {
|
||||
if let Some(mbox_entry) = self.accounts[self.cursor_pos.account].entries.get_mut(idx) {
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
use std::{collections::BTreeMap, iter::FromIterator};
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use melib::{SortField, SortOrder, TagHash, Threads};
|
||||
use melib::{Address, SortField, SortOrder, TagHash, Threads};
|
||||
|
||||
use super::*;
|
||||
use crate::{components::PageMovement, jobs::JoinHandle};
|
||||
|
@ -460,11 +460,8 @@ impl ListingTrait for ConversationsListing {
|
|||
{
|
||||
self.refresh_mailbox(context, false);
|
||||
}
|
||||
let upper_left = area.upper_left();
|
||||
let bottom_right = area.bottom_right();
|
||||
if let Err(message) = self.error.as_ref() {
|
||||
grid.clear_area(area, self.color_cache.theme_default);
|
||||
|
||||
grid.write_string(
|
||||
message,
|
||||
self.color_cache.theme_default.fg,
|
||||
|
@ -476,7 +473,7 @@ impl ListingTrait for ConversationsListing {
|
|||
context.dirty_areas.push_back(area);
|
||||
return;
|
||||
}
|
||||
let rows = (get_y(bottom_right) - get_y(upper_left) + 1) / 3;
|
||||
let rows = area.height() / 3;
|
||||
if rows == 0 {
|
||||
return;
|
||||
}
|
||||
|
@ -519,8 +516,8 @@ impl ListingTrait for ConversationsListing {
|
|||
|
||||
let top_idx = page_no * rows;
|
||||
|
||||
/* If cursor position has changed, remove the highlight from the previous
|
||||
* position and apply it in the new one. */
|
||||
// If cursor position has changed, remove the highlight from the previous
|
||||
// position and apply it in the new one.
|
||||
if self.cursor_pos.2 != self.new_cursor_pos.2 && prev_page_no == page_no {
|
||||
let old_cursor_pos = self.cursor_pos;
|
||||
self.cursor_pos = self.new_cursor_pos;
|
||||
|
@ -544,12 +541,12 @@ impl ListingTrait for ConversationsListing {
|
|||
}
|
||||
|
||||
grid.clear_area(area, self.color_cache.theme_default);
|
||||
/* Page_no has changed, so draw new page */
|
||||
// Page_no has changed, so draw new page
|
||||
self.draw_rows(grid, area, context, top_idx);
|
||||
|
||||
self.highlight_line(
|
||||
grid,
|
||||
area.skip_rows(3 * (self.cursor_pos.2 % rows)).take_rows(2),
|
||||
area.skip_rows(3 * (self.cursor_pos.2 % rows)).take_rows(3),
|
||||
self.cursor_pos.2,
|
||||
context,
|
||||
);
|
||||
|
@ -639,10 +636,9 @@ impl ListingTrait for ConversationsListing {
|
|||
match new_value {
|
||||
Focus::None => {
|
||||
self.dirty = true;
|
||||
/* If self.rows.row_updates is not empty and we exit a thread, the row_update
|
||||
* events will be performed but the list will not be drawn.
|
||||
* So force a draw in any case.
|
||||
*/
|
||||
// If self.rows.row_updates is not empty and we exit a thread, the row_update
|
||||
// events will be performed but the list will not be drawn. So force a draw in
|
||||
// any case.
|
||||
self.force_draw = true;
|
||||
}
|
||||
Focus::Entry => {
|
||||
|
@ -797,7 +793,7 @@ impl ConversationsListing {
|
|||
if thread.has_attachments() { "📎" } else { "" },
|
||||
if thread.snoozed() { "💤" } else { "" }
|
||||
)),
|
||||
from: FromString(address_list!((from) as comma_sep_list)),
|
||||
from: FromString(Address::display_name_slice(from).to_string()),
|
||||
tags: TagString(tags_string, colors),
|
||||
}
|
||||
}
|
||||
|
@ -885,6 +881,7 @@ impl ConversationsListing {
|
|||
if !context.accounts[&self.cursor_pos.0].contains_key(*root_env_hash) {
|
||||
continue;
|
||||
}
|
||||
let area = area.skip_rows(3 * (idx - top_idx)).take_rows(3);
|
||||
let thread = threads.thread_ref(*thread_hash);
|
||||
|
||||
let row_attr = row_attr!(
|
||||
|
@ -893,17 +890,20 @@ impl ConversationsListing {
|
|||
self.cursor_pos.2 == idx,
|
||||
self.rows.is_thread_selected(*thread_hash)
|
||||
);
|
||||
/* draw flags */
|
||||
let (x, _) = grid.write_string(
|
||||
// draw flags
|
||||
let (mut x, _) = grid.write_string(
|
||||
&strings.flag,
|
||||
row_attr.fg,
|
||||
row_attr.bg,
|
||||
row_attr.attrs,
|
||||
area.skip_rows(idx),
|
||||
area,
|
||||
None,
|
||||
);
|
||||
for c in grid.row_iter(area, x..(x + 3), idx) {
|
||||
grid[c].set_bg(row_attr.bg);
|
||||
if !strings.flag.is_empty() {
|
||||
for c in grid.row_iter(area, x..(x + 3), 0) {
|
||||
grid[c].set_bg(row_attr.bg);
|
||||
}
|
||||
x += 3;
|
||||
}
|
||||
let subject_attr = row_attr!(
|
||||
subject,
|
||||
|
@ -912,53 +912,50 @@ impl ConversationsListing {
|
|||
self.cursor_pos.2 == idx,
|
||||
self.rows.is_thread_selected(*thread_hash)
|
||||
);
|
||||
/* draw subject */
|
||||
let (mut x, subject_overflowed) = grid.write_string(
|
||||
// draw subject
|
||||
let (x_, subject_overflowed) = grid.write_string(
|
||||
&strings.subject,
|
||||
subject_attr.fg,
|
||||
subject_attr.bg,
|
||||
subject_attr.attrs,
|
||||
area.skip(idx, x),
|
||||
area.skip_cols(x),
|
||||
None,
|
||||
);
|
||||
x += x_;
|
||||
let mut subject_overflowed = subject_overflowed > 0;
|
||||
for (t, &color) in strings.tags.split_whitespace().zip(strings.tags.1.iter()) {
|
||||
if subject_overflowed {
|
||||
break;
|
||||
};
|
||||
let area = area.skip_cols(x).take_cols(t.grapheme_width() + 2);
|
||||
let color = color.unwrap_or(self.color_cache.tag_default.bg);
|
||||
let (_x, _y) = grid.write_string(
|
||||
t,
|
||||
self.color_cache.tag_default.fg,
|
||||
color,
|
||||
self.color_cache.tag_default.attrs,
|
||||
area.skip(idx, x + 1),
|
||||
area.skip_cols(1),
|
||||
None,
|
||||
);
|
||||
if _y > 0 {
|
||||
subject_overflowed = true;
|
||||
break;
|
||||
}
|
||||
grid[set_x(upper_left, x)].set_bg(color);
|
||||
if _x <= get_x(bottom_right) {
|
||||
grid[set_x(upper_left, _x)].set_bg(color).set_keep_bg(true);
|
||||
}
|
||||
for x in (x + 1).._x {
|
||||
grid[set_x(upper_left, x)]
|
||||
for c in grid.row_iter(area, 0..area.width(), 0) {
|
||||
grid[c]
|
||||
.set_keep_fg(true)
|
||||
.set_keep_bg(true);
|
||||
.set_bg(color)
|
||||
.set_keep_bg(true)
|
||||
.set_attrs(self.color_cache.tag_default.attrs);
|
||||
}
|
||||
grid[set_x(upper_left, x)].set_keep_bg(true);
|
||||
x = _x + 1;
|
||||
x += _x + 2;
|
||||
}
|
||||
if !subject_overflowed {
|
||||
for x in x..get_x(bottom_right) {
|
||||
grid[set_x(upper_left, x)]
|
||||
.set_ch(' ')
|
||||
.set_fg(row_attr.fg)
|
||||
.set_bg(row_attr.bg);
|
||||
for c in grid.row_iter(area, x..area.width(), 0) {
|
||||
grid[c].set_ch(' ').set_fg(row_attr.fg).set_bg(row_attr.bg);
|
||||
}
|
||||
}
|
||||
// Next line, draw date
|
||||
let date_attr = row_attr!(
|
||||
date,
|
||||
self.color_cache,
|
||||
|
@ -966,25 +963,21 @@ impl ConversationsListing {
|
|||
self.cursor_pos.2 == idx,
|
||||
self.rows.is_thread_selected(*thread_hash)
|
||||
);
|
||||
upper_left.1 += 1;
|
||||
if upper_left.1 >= bottom_right.1 {
|
||||
return;
|
||||
}
|
||||
/* Next line, draw date */
|
||||
let (x, _) = grid.write_string(
|
||||
&strings.date,
|
||||
date_attr.fg,
|
||||
date_attr.bg,
|
||||
date_attr.attrs,
|
||||
(upper_left, bottom_right),
|
||||
None,
|
||||
);
|
||||
for x in x..(x + 4) {
|
||||
grid[set_x(upper_left, x)]
|
||||
.set_ch('▁')
|
||||
.set_fg(row_attr.fg)
|
||||
.set_bg(row_attr.bg);
|
||||
x = 0;
|
||||
x += grid
|
||||
.write_string(
|
||||
&strings.date,
|
||||
date_attr.fg,
|
||||
date_attr.bg,
|
||||
date_attr.attrs,
|
||||
area.skip(x, 1),
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
for c in grid.row_iter(area, x..(x + 4), 1) {
|
||||
grid[c].set_ch('▁').set_fg(row_attr.fg).set_bg(row_attr.bg);
|
||||
}
|
||||
x += 4;
|
||||
let from_attr = row_attr!(
|
||||
from,
|
||||
self.color_cache,
|
||||
|
@ -992,25 +985,20 @@ impl ConversationsListing {
|
|||
self.cursor_pos.2 == idx,
|
||||
self.rows.is_thread_selected(*thread_hash)
|
||||
);
|
||||
/* draw from */
|
||||
let (x, _) = grid.write_string(
|
||||
&strings.from,
|
||||
from_attr.fg,
|
||||
from_attr.bg,
|
||||
from_attr.attrs,
|
||||
(set_x(upper_left, x + 4), bottom_right),
|
||||
None,
|
||||
);
|
||||
// draw from
|
||||
x += grid
|
||||
.write_string(
|
||||
&strings.from,
|
||||
from_attr.fg,
|
||||
from_attr.bg,
|
||||
from_attr.attrs,
|
||||
area.skip(x, 1),
|
||||
None,
|
||||
)
|
||||
.0;
|
||||
|
||||
for x in x..get_x(bottom_right) {
|
||||
grid[set_x(upper_left, x)]
|
||||
.set_ch('▁')
|
||||
.set_fg(row_attr.fg)
|
||||
.set_bg(row_attr.bg);
|
||||
}
|
||||
upper_left.1 += 2;
|
||||
if upper_left.1 >= bottom_right.1 {
|
||||
return;
|
||||
for c in grid.row_iter(area, x..area.width(), 1) {
|
||||
grid[c].set_ch('▁').set_fg(row_attr.fg).set_bg(row_attr.bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1027,7 +1015,6 @@ impl Component for ConversationsListing {
|
|||
return;
|
||||
}
|
||||
|
||||
let (upper_left, bottom_right) = area;
|
||||
{
|
||||
let mut area = area;
|
||||
|
||||
|
@ -1042,24 +1029,18 @@ impl Component for ConversationsListing {
|
|||
self.color_cache.theme_default.bg,
|
||||
self.color_cache.theme_default.attrs,
|
||||
area,
|
||||
Some(get_x(upper_left)),
|
||||
Some(0),
|
||||
);
|
||||
for c in grid.row_iter(area, x..(get_x(bottom_right) + 1), y) {
|
||||
for c in grid.row_iter(area, x..area.width(), y) {
|
||||
grid[c] = Cell::default();
|
||||
}
|
||||
|
||||
grid.clear_area(
|
||||
((x, y), set_y(bottom_right, y)),
|
||||
self.color_cache.theme_default,
|
||||
);
|
||||
context
|
||||
.dirty_areas
|
||||
.push_back((upper_left, set_y(bottom_right, y + 1)));
|
||||
grid.clear_area(area.skip(x, y), self.color_cache.theme_default);
|
||||
context.dirty_areas.push_back(area.nth_row(0));
|
||||
|
||||
area = (set_y(upper_left, y + 1), bottom_right);
|
||||
area = area.skip_rows(1);
|
||||
}
|
||||
let (upper_left, bottom_right) = area;
|
||||
let rows = (get_y(bottom_right) - get_y(upper_left) + 1) / 3;
|
||||
let rows = area.height() / 3;
|
||||
if let Some(modifier) = self.modifier_command.take() {
|
||||
if let Some(mvm) = self.movement.as_ref() {
|
||||
match mvm {
|
||||
|
@ -1231,8 +1212,7 @@ impl Component for ConversationsListing {
|
|||
}
|
||||
|
||||
if !self.rows.row_updates.is_empty() {
|
||||
/* certain rows need to be updated (eg an unseen message was just set seen)
|
||||
*/
|
||||
// certain rows need to be updated (eg an unseen message was just set seen)
|
||||
while let Some(row) = self.rows.row_updates.pop() {
|
||||
self.update_line(context, row);
|
||||
let row: usize = self.rows.env_order[&row];
|
||||
|
@ -1240,23 +1220,20 @@ impl Component for ConversationsListing {
|
|||
let page_no = (self.cursor_pos.2).wrapping_div(rows);
|
||||
|
||||
let top_idx = page_no * rows;
|
||||
/* Update row only if it's currently visible */
|
||||
// Update row only if it's currently visible
|
||||
if row >= top_idx && row < top_idx + rows {
|
||||
let area = (
|
||||
set_y(upper_left, get_y(upper_left) + (3 * (row % rows))),
|
||||
set_y(bottom_right, get_y(upper_left) + (3 * (row % rows) + 2)),
|
||||
);
|
||||
let area = area.skip_rows(3 * (row % rows)).take_rows(3);
|
||||
self.highlight_line(grid, area, row, context);
|
||||
context.dirty_areas.push_back(area);
|
||||
}
|
||||
}
|
||||
if self.force_draw {
|
||||
/* Draw the entire list */
|
||||
// Draw the entire list
|
||||
self.draw_list(grid, area, context);
|
||||
self.force_draw = false;
|
||||
}
|
||||
} else {
|
||||
/* Draw the entire list */
|
||||
// Draw the entire list
|
||||
self.draw_list(grid, area, context);
|
||||
}
|
||||
}
|
||||
|
@ -1267,14 +1244,8 @@ impl Component for ConversationsListing {
|
|||
return;
|
||||
}
|
||||
|
||||
let entry_area = (
|
||||
set_x(upper_left, get_x(upper_left) + area.width() / 3 + 2),
|
||||
bottom_right,
|
||||
);
|
||||
let gap_area = (
|
||||
pos_dec(entry_area.upper_left(), (1, 0)),
|
||||
entry_area.bottom_right(),
|
||||
);
|
||||
let entry_area = area.skip_cols(1 + area.width() / 3);
|
||||
let gap_area = area.nth_col(area.width() / 3);
|
||||
grid.clear_area(gap_area, self.color_cache.theme_default);
|
||||
context.dirty_areas.push_back(gap_area);
|
||||
self.view_area = entry_area.into();
|
||||
|
@ -1415,23 +1386,21 @@ impl Component for ConversationsListing {
|
|||
return true;
|
||||
}
|
||||
Action::Listing(ToggleThreadSnooze) if !self.unfocused() => {
|
||||
/*
|
||||
if let Some(thread) = self.get_thread_under_cursor(self.cursor_pos.2) {
|
||||
let account = &mut context.accounts[&self.cursor_pos.0];
|
||||
account
|
||||
.collection
|
||||
.threads
|
||||
.write()
|
||||
.unwrap()
|
||||
.entry(self.cursor_pos.1)
|
||||
.and_modify(|threads| {
|
||||
let is_snoozed = threads.thread_ref(thread).snoozed();
|
||||
threads.thread_ref_mut(thread).set_snoozed(!is_snoozed);
|
||||
});
|
||||
self.rows.row_updates.push(thread);
|
||||
self.refresh_mailbox(context, false);
|
||||
}
|
||||
*/
|
||||
//if let Some(thread) = self.get_thread_under_cursor(self.cursor_pos.2) {
|
||||
// let account = &mut context.accounts[&self.cursor_pos.0];
|
||||
// account
|
||||
// .collection
|
||||
// .threads
|
||||
// .write()
|
||||
// .unwrap()
|
||||
// .entry(self.cursor_pos.1)
|
||||
// .and_modify(|threads| {
|
||||
// let is_snoozed = threads.thread_ref(thread).snoozed();
|
||||
// threads.thread_ref_mut(thread).set_snoozed(!is_snoozed);
|
||||
// });
|
||||
// self.rows.row_updates.push(thread);
|
||||
// self.refresh_mailbox(context, false);
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
|
@ -1476,7 +1445,12 @@ impl Component for ConversationsListing {
|
|||
self.search_job = Some((filter_term.to_string(), handle));
|
||||
}
|
||||
Err(err) => {
|
||||
context.replies.push_back(UIEvent::Notification { title: Some("Could not perform search".into()), source: None, body: err.to_string().into(), kind: Some(crate::types::NotificationType::Error(err.kind)), });
|
||||
context.replies.push_back(UIEvent::Notification {
|
||||
title: Some("Could not perform search".into()),
|
||||
source: None,
|
||||
body: err.to_string().into(),
|
||||
kind: Some(crate::types::NotificationType::Error(err.kind)),
|
||||
});
|
||||
}
|
||||
};
|
||||
self.set_dirty(true);
|
||||
|
@ -1518,7 +1492,12 @@ impl Component for ConversationsListing {
|
|||
Ok(None) => { /* something happened, perhaps a worker thread panicked */ }
|
||||
Ok(Some(Ok(results))) => self.filter(filter_term, results, context),
|
||||
Ok(Some(Err(err))) => {
|
||||
context.replies.push_back(UIEvent::Notification { title: Some("Could not perform search".into()), source: None, body: err.to_string().into(), kind: Some(crate::types::NotificationType::Error(err.kind)), });
|
||||
context.replies.push_back(UIEvent::Notification {
|
||||
title: Some("Could not perform search".into()),
|
||||
source: None,
|
||||
body: err.to_string().into(),
|
||||
kind: Some(crate::types::NotificationType::Error(err.kind)),
|
||||
});
|
||||
}
|
||||
}
|
||||
self.set_dirty(true);
|
||||
|
|
Loading…
Reference in New Issue