summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2022-12-01 21:08:56 +0200
committerManos Pitsidianakis <el13635@mail.ntua.gr>2022-12-01 21:20:20 +0200
commitb9030a684c0ad64951a388e49d5825c12b483fb4 (patch)
treec49fa13fa0d7b77e7dc7c4861e60d08666cb8774
parent2224a7100f9bc6c44bc66117a88556003e74186e (diff)
downloadmeli-b9030a684c0ad64951a388e49d5825c12b483fb4.zip
listings: fix selection not appearing immediately and invalid motions
-rw-r--r--src/components/mail/listing.rs3
-rw-r--r--src/components/mail/listing/compact.rs52
-rw-r--r--src/components/mail/listing/conversations.rs45
-rw-r--r--src/components/mail/listing/plain.rs212
-rw-r--r--src/components/mail/listing/thread.rs1
5 files changed, 233 insertions, 80 deletions
diff --git a/src/components/mail/listing.rs b/src/components/mail/listing.rs
index a94c1107..dc0115b5 100644
--- a/src/components/mail/listing.rs
+++ b/src/components/mail/listing.rs
@@ -93,9 +93,10 @@ impl<T> RowsState<T> {
&mut self,
thread: ThreadHash,
metadata: T,
- env_hashes: SmallVec<[EnvelopeHash; 8]>,
+ mut env_hashes: SmallVec<[EnvelopeHash; 8]>,
entry_strings: EntryStrings,
) {
+ env_hashes.dedup();
let index = self.entries.len();
self.thread_order.insert(thread, index);
self.all_threads.insert(thread);
diff --git a/src/components/mail/listing/compact.rs b/src/components/mail/listing/compact.rs
index cd49a685..dc476586 100644
--- a/src/components/mail/listing/compact.rs
+++ b/src/components/mail/listing/compact.rs
@@ -1372,9 +1372,7 @@ impl Component for CompactListing {
if let Some(mvm) = self.movement.as_ref() {
match mvm {
PageMovement::Up(amount) => {
- for c in self.new_cursor_pos.2.saturating_sub(*amount)
- ..=self.new_cursor_pos.2
- {
+ for c in self.cursor_pos.2.saturating_sub(*amount)..=self.cursor_pos.2 {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
thread,
@@ -1390,8 +1388,8 @@ impl Component for CompactListing {
}
}
if modifier == Modifier::Intersection {
- for c in (0..self.new_cursor_pos.2.saturating_sub(*amount))
- .chain((self.new_cursor_pos.2 + 2)..self.length)
+ for c in (0..self.cursor_pos.2.saturating_sub(*amount))
+ .chain((self.cursor_pos.2 + 2)..self.length)
{
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows
@@ -1401,8 +1399,8 @@ impl Component for CompactListing {
}
}
PageMovement::PageUp(multiplier) => {
- for c in self.new_cursor_pos.2.saturating_sub(rows * multiplier)
- ..=self.new_cursor_pos.2
+ for c in self.cursor_pos.2.saturating_sub(rows * multiplier)
+ ..=self.cursor_pos.2
{
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
@@ -1420,8 +1418,8 @@ impl Component for CompactListing {
}
}
PageMovement::Down(amount) => {
- for c in self.new_cursor_pos.2
- ..std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
+ for c in self.cursor_pos.2
+ ..std::cmp::min(self.length, self.cursor_pos.2 + amount + 1)
{
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
@@ -1438,9 +1436,9 @@ impl Component for CompactListing {
}
}
if modifier == Modifier::Intersection {
- for c in (0..self.new_cursor_pos.2).chain(
- (std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
- + 1)..self.length,
+ for c in (0..self.cursor_pos.2).chain(
+ (std::cmp::min(self.length, self.cursor_pos.2 + amount) + 1)
+ ..self.length,
) {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows
@@ -1450,9 +1448,9 @@ impl Component for CompactListing {
}
}
PageMovement::PageDown(multiplier) => {
- for c in self.new_cursor_pos.2
+ for c in self.cursor_pos.2
..std::cmp::min(
- self.new_cursor_pos.2 + rows * multiplier + 1,
+ self.cursor_pos.2 + rows * multiplier + 1,
self.length,
)
{
@@ -1471,9 +1469,9 @@ impl Component for CompactListing {
}
}
if modifier == Modifier::Intersection {
- for c in (0..self.new_cursor_pos.2).chain(
+ for c in (0..self.cursor_pos.2).chain(
(std::cmp::min(
- self.new_cursor_pos.2 + rows * multiplier + 1,
+ self.cursor_pos.2 + rows * multiplier,
self.length,
) + 1)..self.length,
) {
@@ -1486,7 +1484,7 @@ impl Component for CompactListing {
}
PageMovement::Right(_) | PageMovement::Left(_) => {}
PageMovement::Home => {
- for c in 0..=self.new_cursor_pos.2 {
+ for c in 0..=self.cursor_pos.2 {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
thread,
@@ -1502,7 +1500,7 @@ impl Component for CompactListing {
}
}
if modifier == Modifier::Intersection {
- for c in (self.new_cursor_pos.2 + 1)..self.length {
+ for c in (self.cursor_pos.2)..self.length {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows
.update_selection_with_thread(thread, |e| *e = false);
@@ -1511,7 +1509,7 @@ impl Component for CompactListing {
}
}
PageMovement::End => {
- for c in self.new_cursor_pos.2..self.length {
+ for c in self.cursor_pos.2..self.length {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
thread,
@@ -1527,7 +1525,7 @@ impl Component for CompactListing {
}
}
if modifier == Modifier::Intersection {
- for c in 0..self.new_cursor_pos.2 {
+ for c in 0..self.cursor_pos.2 {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows
.update_selection_with_thread(thread, |e| *e = false);
@@ -1547,18 +1545,7 @@ impl Component for CompactListing {
let page_no = (self.new_cursor_pos.2).wrapping_div(rows);
let top_idx = page_no * rows;
- if row >= top_idx && row < top_idx + rows {
- let new_area = nth_row_area(area, row % rows);
- self.data_columns.draw(
- grid,
- row,
- self.cursor_pos.2,
- grid.bounds_iter(new_area),
- );
- let row_attr = self.rows.row_attr_cache[&row];
- change_colors(grid, new_area, row_attr.fg, row_attr.bg);
- context.dirty_areas.push_back(new_area);
- }
+ self.force_draw |= row >= top_idx && row < top_idx + rows;
}
if self.force_draw {
/* Draw the entire list */
@@ -1666,6 +1653,7 @@ impl Component for CompactListing {
{
self.rows
.update_selection_with_thread(thread_hash, |e| *e = !*e);
+ self.set_dirty(true);
}
return true;
}
diff --git a/src/components/mail/listing/conversations.rs b/src/components/mail/listing/conversations.rs
index be088a2b..c6d8b6c9 100644
--- a/src/components/mail/listing/conversations.rs
+++ b/src/components/mail/listing/conversations.rs
@@ -473,7 +473,9 @@ impl ListingTrait for ConversationsListing {
self.highlight_line(grid, new_area, *idx, context);
context.dirty_areas.push_back(new_area);
}
- return;
+ if !self.force_draw {
+ return;
+ }
} else if self.cursor_pos != self.new_cursor_pos {
self.cursor_pos = self.new_cursor_pos;
}
@@ -1012,9 +1014,7 @@ impl Component for ConversationsListing {
if let Some(mvm) = self.movement.as_ref() {
match mvm {
PageMovement::Up(amount) => {
- for c in self.new_cursor_pos.2.saturating_sub(*amount)
- ..=self.new_cursor_pos.2
- {
+ for c in self.cursor_pos.2.saturating_sub(*amount)..=self.cursor_pos.2 {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
thread,
@@ -1030,8 +1030,8 @@ impl Component for ConversationsListing {
}
}
if modifier == Modifier::Intersection {
- for c in (0..self.new_cursor_pos.2.saturating_sub(*amount))
- .chain((self.new_cursor_pos.2 + 2)..self.length)
+ for c in (0..self.cursor_pos.2.saturating_sub(*amount))
+ .chain((self.cursor_pos.2 + 2)..self.length)
{
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows
@@ -1041,8 +1041,8 @@ impl Component for ConversationsListing {
}
}
PageMovement::PageUp(multiplier) => {
- for c in self.new_cursor_pos.2.saturating_sub(rows * multiplier)
- ..=self.new_cursor_pos.2
+ for c in self.cursor_pos.2.saturating_sub(rows * multiplier)
+ ..=self.cursor_pos.2
{
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
@@ -1060,8 +1060,8 @@ impl Component for ConversationsListing {
}
}
PageMovement::Down(amount) => {
- for c in self.new_cursor_pos.2
- ..std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
+ for c in self.cursor_pos.2
+ ..std::cmp::min(self.length, self.cursor_pos.2 + amount + 1)
{
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
@@ -1078,9 +1078,9 @@ impl Component for ConversationsListing {
}
}
if modifier == Modifier::Intersection {
- for c in (0..self.new_cursor_pos.2).chain(
- (std::cmp::min(self.length, self.new_cursor_pos.2 + amount + 1)
- + 1)..self.length,
+ for c in (0..self.cursor_pos.2).chain(
+ (std::cmp::min(self.length, self.cursor_pos.2 + amount + 1) + 1)
+ ..self.length,
) {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows
@@ -1090,9 +1090,9 @@ impl Component for ConversationsListing {
}
}
PageMovement::PageDown(multiplier) => {
- for c in self.new_cursor_pos.2
+ for c in self.cursor_pos.2
..std::cmp::min(
- self.new_cursor_pos.2 + rows * multiplier + 1,
+ self.cursor_pos.2 + rows * multiplier + 1,
self.length,
)
{
@@ -1111,9 +1111,9 @@ impl Component for ConversationsListing {
}
}
if modifier == Modifier::Intersection {
- for c in (0..self.new_cursor_pos.2).chain(
+ for c in (0..self.cursor_pos.2).chain(
(std::cmp::min(
- self.new_cursor_pos.2 + rows * multiplier + 1,
+ self.cursor_pos.2 + rows * multiplier + 1,
self.length,
) + 1)..self.length,
) {
@@ -1126,7 +1126,7 @@ impl Component for ConversationsListing {
}
PageMovement::Right(_) | PageMovement::Left(_) => {}
PageMovement::Home => {
- for c in 0..=self.new_cursor_pos.2 {
+ for c in 0..=self.cursor_pos.2 {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
thread,
@@ -1142,7 +1142,7 @@ impl Component for ConversationsListing {
}
}
if modifier == Modifier::Intersection {
- for c in (self.new_cursor_pos.2 + 1)..self.length {
+ for c in (self.cursor_pos.2 + 1)..self.length {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows
.update_selection_with_thread(thread, |e| *e = false);
@@ -1151,7 +1151,7 @@ impl Component for ConversationsListing {
}
}
PageMovement::End => {
- for c in self.new_cursor_pos.2..self.length {
+ for c in self.cursor_pos.2..self.length {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows.update_selection_with_thread(
thread,
@@ -1167,7 +1167,7 @@ impl Component for ConversationsListing {
}
}
if modifier == Modifier::Intersection {
- for c in 0..self.new_cursor_pos.2 {
+ for c in 0..self.cursor_pos.2 {
if let Some(thread) = self.get_thread_under_cursor(c) {
self.rows
.update_selection_with_thread(thread, |e| *e = false);
@@ -1177,7 +1177,9 @@ impl Component for ConversationsListing {
}
}
}
+ self.force_draw = true;
}
+
if !self.rows.row_updates.is_empty() {
/* certain rows need to be updated (eg an unseen message was just set seen)
* */
@@ -1305,6 +1307,7 @@ impl Component for ConversationsListing {
self.modifier_command = Some(Modifier::default());
} else if let Some(thread) = self.get_thread_under_cursor(self.cursor_pos.2) {
self.rows.update_selection_with_thread(thread, |e| *e = !*e);
+ self.set_dirty(true);
}
return true;
}
diff --git a/src/components/mail/listing/plain.rs b/src/components/mail/listing/plain.rs
index 3e45f528..01a0ff48 100644
--- a/src/components/mail/listing/plain.rs
+++ b/src/components/mail/listing/plain.rs
@@ -461,7 +461,9 @@ impl ListingTrait for PlainListing {
}
context.dirty_areas.push_back(new_area);
}
- return;
+ if !self.force_draw {
+ return;
+ }
} else if self.cursor_pos != self.new_cursor_pos {
self.cursor_pos = self.new_cursor_pos;
}
@@ -1025,37 +1027,194 @@ impl Component for PlainListing {
area = (set_y(upper_left, y + 1), bottom_right);
}
+ let (upper_left, bottom_right) = area;
+ let rows = get_y(bottom_right) - get_y(upper_left) + 1;
+
+ if let Some(modifier) = self.modifier_command.take() {
+ if let Some(mvm) = self.movement.as_ref() {
+ match mvm {
+ PageMovement::Up(amount) => {
+ for c in self.cursor_pos.2.saturating_sub(*amount)..=self.cursor_pos.2 {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows.update_selection_with_env(
+ env_hash,
+ match modifier {
+ Modifier::SymmetricDifference => {
+ |e: &mut bool| *e = !*e
+ }
+ Modifier::Union => |e: &mut bool| *e = true,
+ Modifier::Difference => |e: &mut bool| *e = false,
+ Modifier::Intersection => |_: &mut bool| {},
+ },
+ );
+ }
+ }
+ if modifier == Modifier::Intersection {
+ for c in (0..self.cursor_pos.2.saturating_sub(*amount))
+ .chain((self.cursor_pos.2 + 2)..self.length)
+ {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows
+ .update_selection_with_env(env_hash, |e| *e = false);
+ }
+ }
+ }
+ }
+ PageMovement::PageUp(multiplier) => {
+ for c in self.cursor_pos.2.saturating_sub(rows * multiplier)
+ ..=self.cursor_pos.2
+ {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows.update_selection_with_env(
+ env_hash,
+ match modifier {
+ Modifier::SymmetricDifference => {
+ |e: &mut bool| *e = !*e
+ }
+ Modifier::Union => |e: &mut bool| *e = true,
+ Modifier::Difference => |e: &mut bool| *e = false,
+ Modifier::Intersection => |_: &mut bool| {},
+ },
+ );
+ }
+ }
+ }
+ PageMovement::Down(amount) => {
+ for c in self.cursor_pos.2
+ ..std::cmp::min(self.length, self.cursor_pos.2 + amount + 1)
+ {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows.update_selection_with_env(
+ env_hash,
+ match modifier {
+ Modifier::SymmetricDifference => {
+ |e: &mut bool| *e = !*e
+ }
+ Modifier::Union => |e: &mut bool| *e = true,
+ Modifier::Difference => |e: &mut bool| *e = false,
+ Modifier::Intersection => |_: &mut bool| {},
+ },
+ );
+ }
+ }
+ if modifier == Modifier::Intersection {
+ for c in (0..self.cursor_pos.2).chain(
+ (std::cmp::min(self.length, self.cursor_pos.2 + amount) + 1)
+ ..self.length,
+ ) {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows
+ .update_selection_with_env(env_hash, |e| *e = false);
+ }
+ }
+ }
+ }
+ PageMovement::PageDown(multiplier) => {
+ for c in self.cursor_pos.2
+ ..std::cmp::min(self.cursor_pos.2 + rows * multiplier, self.length)
+ {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows.update_selection_with_env(
+ env_hash,
+ match modifier {
+ Modifier::SymmetricDifference => {
+ |e: &mut bool| *e = !*e
+ }
+ Modifier::Union => |e: &mut bool| *e = true,
+ Modifier::Difference => |e: &mut bool| *e = false,
+ Modifier::Intersection => |_: &mut bool| {},
+ },
+ );
+ }
+ }
+ if modifier == Modifier::Intersection {
+ for c in (0..self.cursor_pos.2).chain(
+ (std::cmp::min(
+ self.cursor_pos.2 + rows * multiplier,
+ self.length,
+ ) + 1)..self.length,
+ ) {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows
+ .update_selection_with_env(env_hash, |e| *e = false);
+ }
+ }
+ }
+ }
+ PageMovement::Right(_) | PageMovement::Left(_) => {}
+ PageMovement::Home => {
+ for c in 0..=self.cursor_pos.2 {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows.update_selection_with_env(
+ env_hash,
+ match modifier {
+ Modifier::SymmetricDifference => {
+ |e: &mut bool| *e = !*e
+ }
+ Modifier::Union => |e: &mut bool| *e = true,
+ Modifier::Difference => |e: &mut bool| *e = false,
+ Modifier::Intersection => |_: &mut bool| {},
+ },
+ );
+ }
+ }
+ if modifier == Modifier::Intersection {
+ for c in (self.cursor_pos.2)..self.length {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows
+ .update_selection_with_env(env_hash, |e| *e = false);
+ }
+ }
+ }
+ }
+ PageMovement::End => {
+ for c in self.cursor_pos.2..self.length {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows.update_selection_with_env(
+ env_hash,
+ match modifier {
+ Modifier::SymmetricDifference => {
+ |e: &mut bool| *e = !*e
+ }
+ Modifier::Union => |e: &mut bool| *e = true,
+ Modifier::Difference => |e: &mut bool| *e = false,
+ Modifier::Intersection => |_: &mut bool| {},
+ },
+ );
+ }
+ }
+ if modifier == Modifier::Intersection {
+ for c in 0..self.cursor_pos.2 {
+ if let Some(env_hash) = self.get_env_under_cursor(c) {
+ self.rows
+ .update_selection_with_env(env_hash, |e| *e = false);
+ }
+ }
+ }
+ }
+ }
+ }
+ self.force_draw = true;
+ }
+
if !self.rows.row_updates.is_empty() {
- let (upper_left, bottom_right) = area;
while let Some(env_hash) = self.rows.row_updates.pop() {
let row: usize = self.rows.env_order[&env_hash];
- let rows = get_y(bottom_right) - get_y(upper_left) + 1;
+ let envelope: EnvelopeRef = context.accounts[&self.cursor_pos.0]
+ .collection
+ .get_env(env_hash);
+ let row_attr = row_attr!(
+ self.color_cache,
+ row % 2 == 0,
+ !envelope.is_seen(),
+ false,
+ self.rows.selection[&env_hash]
+ );
+ self.rows.row_attr_cache.insert(row, row_attr);
let page_no = (self.new_cursor_pos.2).wrapping_div(rows);
let top_idx = page_no * rows;
- if row >= top_idx && row <= top_idx + rows {
- let new_area = nth_row_area(area, row % rows);
- self.data_columns.draw(
- grid,
- row,
- self.cursor_pos.2,
- grid.bounds_iter(new_area),
- );
- let envelope: EnvelopeRef = context.accounts[&self.cursor_pos.0]
- .collection
- .get_env(env_hash);
- let row_attr = row_attr!(
- self.color_cache,
- row % 2 == 0,
- !envelope.is_seen(),
- false,
- self.rows.selection[&env_hash]
- );
- self.rows.row_attr_cache.insert(row, row_attr);
-
- change_colors(grid, new_area, row_attr.fg, row_attr.bg);
- context.dirty_areas.push_back(new_area);
- }
+ self.force_draw |= row >= top_idx && row < top_idx + rows;
}
if self.force_draw {
/* Draw the entire list */
@@ -1149,6 +1308,7 @@ impl Component for PlainListing {
self.modifier_command = Some(Modifier::default());
} else if let Some(env_hash) = self.get_env_under_cursor(self.cursor_pos.2) {
self.rows.update_selection_with_env(env_hash, |e| *e = !*e);
+ self.set_dirty(true);
}
return true;
}
diff --git a/src/components/mail/listing/thread.rs b/src/components/mail/listing/thread.rs
index 29a99679..2f89bc88 100644
--- a/src/components/mail/listing/thread.rs
+++ b/src/components/mail/listing/thread.rs
@@ -1505,6 +1505,7 @@ impl Component for ThreadListing {
self.modifier_command = Some(Modifier::default());
} else if let Some(env_hash) = self.get_env_under_cursor(self.cursor_pos.2) {
self.rows.update_selection_with_env(env_hash, |e| *e = !*e);
+ self.set_dirty(true);
}
return true;
}