From 598e6eb5680edf1832ff2ebe45c761b5c6a73936 Mon Sep 17 00:00:00 2001 From: Rusty Pickle Date: Sat, 10 Feb 2024 05:48:03 +0600 Subject: [PATCH 1/4] Fix user table selection --- src/tg_handler/counter.rs | 2 +- src/ui_components/processor/states.rs | 33 +++++ src/ui_components/tab_ui/user_table.rs | 177 ++++++++++++++----------- 3 files changed, 131 insertions(+), 81 deletions(-) diff --git a/src/tg_handler/counter.rs b/src/tg_handler/counter.rs index 0783e41..343185e 100644 --- a/src/tg_handler/counter.rs +++ b/src/tg_handler/counter.rs @@ -87,7 +87,7 @@ impl TGClient { let mut start_at = if let Some(num) = start_num { num } else { -1 }; info!( - "Staring message num {}, ending message num {}", + "Starting message num {}, ending message num {}", start_at, end_at ); diff --git a/src/ui_components/processor/states.rs b/src/ui_components/processor/states.rs index 39147be..21928d3 100644 --- a/src/ui_components/processor/states.rs +++ b/src/ui_components/processor/states.rs @@ -167,6 +167,39 @@ impl ColumnName { ColumnName::Whitelisted => ColumnName::Name, } } + + pub fn get_previous(&self) -> Self { + match self { + ColumnName::Name => ColumnName::Whitelisted, + ColumnName::Username => ColumnName::Name, + ColumnName::UserID => ColumnName::Username, + ColumnName::TotalMessage => ColumnName::UserID, + ColumnName::TotalWord => ColumnName::TotalMessage, + ColumnName::TotalChar => ColumnName::TotalWord, + ColumnName::AverageWord => ColumnName::TotalChar, + ColumnName::AverageChar => ColumnName::AverageWord, + ColumnName::FirstMessageSeen => ColumnName::AverageChar, + ColumnName::LastMessageSeen => ColumnName::FirstMessageSeen, + ColumnName::Whitelisted => ColumnName::LastMessageSeen, + } + } + + pub fn from_num(num: i32) -> Self { + match num { + 0 => ColumnName::Name, + 1 => ColumnName::Username, + 2 => ColumnName::UserID, + 3 => ColumnName::TotalMessage, + 4 => ColumnName::TotalWord, + 5 => ColumnName::TotalChar, + 6 => ColumnName::AverageWord, + 7 => ColumnName::AverageChar, + 8 => ColumnName::FirstMessageSeen, + 9 => ColumnName::LastMessageSeen, + 10 => ColumnName::Whitelisted, + _ => unreachable!("Invalid enum variant for number {}", num), + } + } } #[derive(Default, PartialEq)] diff --git a/src/ui_components/tab_ui/user_table.rs b/src/ui_components/tab_ui/user_table.rs index 3d45259..7ba5edd 100644 --- a/src/ui_components/tab_ui/user_table.rs +++ b/src/ui_components/tab_ui/user_table.rs @@ -333,7 +333,12 @@ impl UserTableData { } /// Continuously called to select rows and columns when dragging has started - fn select_dragged_row_cell(&mut self, user_id: i64, column_name: &ColumnName) { + fn select_dragged_row_cell( + &mut self, + user_id: i64, + column_name: &ColumnName, + is_ctrl_pressed: bool, + ) { // If both same then the mouse is still on the same column on the same row so nothing to process if self.last_active_row == Some(user_id) && self.last_active_column == Some(column_name.clone()) @@ -348,17 +353,52 @@ impl UserTableData { let drag_start = self.drag_started_on.clone().unwrap(); self.select_single_row_cell(drag_start.0, &drag_start.1); - let min_col = self.active_columns.clone().into_iter().min(); - let max_col = self.active_columns.clone().into_iter().max(); - - // If column 1 and column 5 is selected, ensure the column in the middle are not missing from selection - // It can miss in case of fast mouse movement - if let (Some(min), Some(max)) = (min_col, max_col) { - let mut current_col = min; - while current_col != max { - let next_col = current_col.get_next(); - self.active_columns.insert(next_col.clone()); - current_col = next_col; + let drag_start_num = drag_start.1 as i32; + let ongoing_column_num = column_name.clone() as i32; + + let mut new_column_set = HashSet::new(); + + let get_previous = ongoing_column_num > drag_start_num; + let mut ongoing_val = Some(ColumnName::from_num(drag_start_num)); + + // row1: column(drag started here) column column + // row2: column column column + // row3: column column column + // row4: column column column (currently here) + // + // The goal of this is to ensure from the drag starting point to all the columns till the currently here + // are considered selected and the rest are removed from active selection even if it was considered active + // + // During fast mouse movement active rows can contain columns that are not in the range we are targeting + // We go from one point to the other point and ensure except those columns nothing else is selected + // + // No active row removal if ctrl is being pressed! + if is_ctrl_pressed { + self.active_columns.insert(column_name.clone()); + } else { + if ongoing_column_num == drag_start_num { + new_column_set.insert(ColumnName::from_num(drag_start_num)); + self.active_columns = new_column_set; + } else { + while ongoing_val.is_some() { + let col = ongoing_val.clone().unwrap(); + + let next_column = if get_previous { + col.get_next() + } else { + col.get_previous() + }; + + new_column_set.insert(col); + + if next_column == ColumnName::from_num(ongoing_column_num) { + new_column_set.insert(next_column); + ongoing_val = None; + } else { + ongoing_val = Some(next_column); + } + } + self.active_columns = new_column_set; } } @@ -372,6 +412,7 @@ impl UserTableData { // moved backwards from an active column to another active column. let row_contains_column = current_row.selected_columns.contains(column_name); + let mut no_checking = false; // If we have some data of the last row and column that the mouse was on, then try to unselect if row_contains_column && self.last_active_row.is_some() @@ -401,32 +442,9 @@ impl UserTableData { if user_id == last_row.id { if last_active_column != *column_name { self.last_active_column = Some(column_name.clone()); - - // Position where the mouse is - let current_row_index = - all_rows.iter().position(|row| row.id == user_id).unwrap(); - - // This solution is not perfect. - // In case of fast mouse movement it fails to call this function as if mouse was not over that cell - - // If current position is row 5 column 2 then check row from 4 to 1 or 4 till a row with no active column is found - // Remove the last selected column from the selection from all the rows are that found - self.remove_row_column_selection( - true, - &all_rows, - current_row_index, - &last_active_column, - ); - // If current position is row 5 column 2 then check row from 6 to final row or 6 till a row with no active column is found - // Remove the last selected column from the selection from all the rows are that found - self.remove_row_column_selection( - false, - &all_rows, - current_row_index, - &last_active_column, - ); } } else { + no_checking = true; // Mouse went 1 row above or below. So just clear all selection from that previous row last_row.selected_columns.clear(); } @@ -434,17 +452,20 @@ impl UserTableData { // We are in a new row which we have not selected before self.last_active_row = Some(user_id); self.last_active_column = Some(column_name.clone()); - for column in &self.active_columns { - current_row.selected_columns.insert(column.to_owned()); - } - let current_row_index = all_rows.iter().position(|row| row.id == user_id).unwrap(); + current_row.selected_columns = self.active_columns.clone(); + } - // Get the row number where the drag started on - let drag_start_index = all_rows - .iter() - .position(|row| row.id == drag_start.0) - .unwrap(); + let current_row_index = all_rows.iter().position(|row| row.id == user_id).unwrap(); + // Get the row number where the drag started on + let drag_start_index = all_rows + .iter() + .position(|row| row.id == drag_start.0) + .unwrap(); + + if no_checking { + self.remove_row_selection(&all_rows, current_row_index, drag_start_index); + } else { // If drag started on row 1, currently on row 5, check from row 4 to 1 and select all columns // else go through all rows till a row without any selected column is found. Applied both by incrementing or decrementing index. // In case of fast mouse movement following drag started point mitigates the risk of some rows not getting selected @@ -485,9 +506,10 @@ impl UserTableData { let target_row = self.rows.get_mut(¤t_row.id).unwrap(); if !unselected_row { - for column in &self.active_columns { - target_row.selected_columns.insert(column.to_owned()); - } + target_row.selected_columns = self.active_columns.clone(); + // for column in &self.active_columns { + // target_row.selected_columns.insert(column.to_owned()); + // } if check_previous { if index != 0 { self.check_row_selection(check_previous, rows, index, drag_start); @@ -498,40 +520,27 @@ impl UserTableData { } } - /// Recursively check the given rows by either increasing or decreasing the initial index - /// till the end point or an unselected row is found. Remove the given column from selection - /// from all rows that are selected. - fn remove_row_column_selection( + /// Checks all the rows and unselects rows that are not within the given range + fn remove_row_selection( &mut self, - check_previous: bool, - rows: &Vec, - index: usize, - target_column: &ColumnName, + rows: &[UserRowData], + current_index: usize, + drag_start: usize, ) { - if index == 0 && check_previous { - return; - } - - if index + 1 == rows.len() && !check_previous { - return; - } + for ongoing_index in 0..rows.len() { + let current_row = rows.get(ongoing_index).unwrap(); + let target_row = self.rows.get_mut(¤t_row.id).unwrap(); - let index = if check_previous { index - 1 } else { index + 1 }; - - let current_row = rows.get(index).unwrap(); - let unselected_row = current_row.selected_columns.is_empty(); - - let target_row = self.rows.get_mut(¤t_row.id).unwrap(); - - if !unselected_row { - target_row.selected_columns.remove(target_column); - - if check_previous { - if index != 0 { - self.remove_row_column_selection(check_previous, rows, index, target_column); + if current_index > drag_start { + if ongoing_index >= drag_start && ongoing_index <= current_index { + target_row.selected_columns = self.active_columns.clone(); + } else { + target_row.selected_columns = HashSet::new(); } - } else if index + 1 != rows.len() { - self.remove_row_column_selection(check_previous, rows, index, target_column); + } else if ongoing_index <= drag_start && ongoing_index >= current_index { + target_row.selected_columns = self.active_columns.clone(); + } else { + target_row.selected_columns = HashSet::new(); } } } @@ -769,6 +778,10 @@ impl MainWindow { self.user_table.beyond_drag_point = false; } + // Drag part handling has ended, need to handle click event from here. + // For some reason if both are added at once, only the one added later responds + label = label.interact(Sense::click()); + if label.clicked() { // If CTRL is not pressed down and the mouse right click is not pressed, unselect all cells if !ui.ctx().input(|i| i.modifiers.ctrl) @@ -788,8 +801,12 @@ impl MainWindow { || drag_start.1 != column_name || self.user_table.beyond_drag_point { - self.user_table - .select_dragged_row_cell(row_data.id, &column_name); + let is_ctrl_pressed = ui.ctx().input(|i| i.modifiers.ctrl); + self.user_table.select_dragged_row_cell( + row_data.id, + &column_name, + is_ctrl_pressed, + ); } } } From 34d18e41428599a262f952f32e075f17f6d9762d Mon Sep 17 00:00:00 2001 From: Rusty Pickle Date: Sat, 10 Feb 2024 18:16:17 +0600 Subject: [PATCH 2/4] Improve table dragging performance --- src/ui_components/tab_ui/user_table.rs | 204 ++++++++++++++----------- 1 file changed, 112 insertions(+), 92 deletions(-) diff --git a/src/ui_components/tab_ui/user_table.rs b/src/ui_components/tab_ui/user_table.rs index 7ba5edd..49bcf7f 100644 --- a/src/ui_components/tab_ui/user_table.rs +++ b/src/ui_components/tab_ui/user_table.rs @@ -123,23 +123,18 @@ pub struct UserTableData { sort_order: SortOrder, drag_started_on: Option<(i64, ColumnName)>, active_columns: HashSet, + active_rows: HashSet, last_active_row: Option, last_active_column: Option, // To track whether the mouse pointer went beyond the drag point at least once beyond_drag_point: bool, + indexed_user_ids: HashMap, } impl UserTableData { /// Clear all the rows pub fn clear_row_data(&mut self) { - self.rows.clear(); - self.sorted_by = ColumnName::default(); - self.sort_order = SortOrder::default(); - self.drag_started_on = None; - self.active_columns.clear(); - self.last_active_row = None; - self.last_active_column = None; - self.beyond_drag_point = false; + *self = UserTableData::default(); } /// Add a user to the table @@ -245,86 +240,17 @@ impl UserTableData { } /// Returns all existing row in the current sorted format in a vector - fn rows(&self) -> Vec { - let mut row_data: Vec = self.rows.values().cloned().collect(); - - match self.sorted_by { - ColumnName::UserID => match self.sort_order { - SortOrder::Ascending => row_data.sort_by(|a, b| a.id.cmp(&b.id)), - SortOrder::Descending => row_data.sort_by(|a, b| a.id.cmp(&b.id).reverse()), - }, - ColumnName::Name => match self.sort_order { - SortOrder::Ascending => row_data.sort_by(|a, b| a.name.cmp(&b.name)), - SortOrder::Descending => row_data.sort_by(|a, b| a.name.cmp(&b.name).reverse()), - }, - ColumnName::Username => match self.sort_order { - SortOrder::Ascending => row_data.sort_by(|a, b| a.username.cmp(&b.username)), - SortOrder::Descending => { - row_data.sort_by(|a, b| a.username.cmp(&b.username).reverse()); - } - }, - ColumnName::TotalMessage => match self.sort_order { - SortOrder::Ascending => { - row_data.sort_by(|a, b| a.total_message.cmp(&b.total_message)); - } - SortOrder::Descending => { - row_data.sort_by(|a, b| a.total_message.cmp(&b.total_message).reverse()); - } - }, - ColumnName::TotalWord => match self.sort_order { - SortOrder::Ascending => row_data.sort_by(|a, b| a.total_word.cmp(&b.total_word)), - SortOrder::Descending => { - row_data.sort_by(|a, b| a.total_word.cmp(&b.total_word).reverse()); - } - }, - ColumnName::TotalChar => match self.sort_order { - SortOrder::Ascending => row_data.sort_by(|a, b| a.total_char.cmp(&b.total_char)), - SortOrder::Descending => { - row_data.sort_by(|a, b| a.total_char.cmp(&b.total_char).reverse()); - } - }, - ColumnName::AverageChar => match self.sort_order { - SortOrder::Ascending => { - row_data.sort_by(|a, b| a.average_char.cmp(&b.average_char)); - } - SortOrder::Descending => { - row_data.sort_by(|a, b| a.average_char.cmp(&b.average_char).reverse()); - } - }, - ColumnName::AverageWord => match self.sort_order { - SortOrder::Ascending => { - row_data.sort_by(|a, b| a.average_word.cmp(&b.average_word)); - } - SortOrder::Descending => { - row_data.sort_by(|a, b| a.average_word.cmp(&b.average_word).reverse()); - } - }, - ColumnName::FirstMessageSeen => match self.sort_order { - SortOrder::Ascending => row_data.sort_by(|a, b| a.first_seen.cmp(&b.first_seen)), - SortOrder::Descending => { - row_data.sort_by(|a, b| a.first_seen.cmp(&b.first_seen).reverse()); - } - }, - ColumnName::LastMessageSeen => match self.sort_order { - SortOrder::Ascending => row_data.sort_by(|a, b| a.last_seen.cmp(&b.last_seen)), - SortOrder::Descending => { - row_data.sort_by(|a, b| a.last_seen.cmp(&b.last_seen).reverse()); - } - }, - ColumnName::Whitelisted => match self.sort_order { - SortOrder::Ascending => row_data.sort_by(|a, b| a.whitelisted.cmp(&b.whitelisted)), - SortOrder::Descending => { - row_data.sort_by(|a, b| a.whitelisted.cmp(&b.whitelisted).reverse()); - } - }, - } - - row_data + fn rows(&mut self) -> Vec { + // It needs to be sorted each load otherwise + // if pre-saved, it will contain outdated data + self.sort_rows() } /// Marks a single column of a row as selected fn select_single_row_cell(&mut self, user_id: i64, column_name: &ColumnName) { self.active_columns.insert(column_name.clone()); + self.active_rows.insert(user_id); + self.rows .get_mut(&user_id) .unwrap() @@ -455,13 +381,10 @@ impl UserTableData { current_row.selected_columns = self.active_columns.clone(); } - let current_row_index = all_rows.iter().position(|row| row.id == user_id).unwrap(); + let current_row_index = self.indexed_user_ids.get(&user_id).unwrap().to_owned(); // Get the row number where the drag started on - let drag_start_index = all_rows - .iter() - .position(|row| row.id == drag_start.0) - .unwrap(); + let drag_start_index = self.indexed_user_ids.get(&drag_start.0).unwrap().to_owned(); if no_checking { self.remove_row_selection(&all_rows, current_row_index, drag_start_index); @@ -507,9 +430,8 @@ impl UserTableData { if !unselected_row { target_row.selected_columns = self.active_columns.clone(); - // for column in &self.active_columns { - // target_row.selected_columns.insert(column.to_owned()); - // } + self.active_rows.insert(target_row.id); + if check_previous { if index != 0 { self.check_row_selection(check_previous, rows, index, drag_start); @@ -527,7 +449,9 @@ impl UserTableData { current_index: usize, drag_start: usize, ) { - for ongoing_index in 0..rows.len() { + let active_ids = self.active_rows.clone(); + for id in active_ids { + let ongoing_index = self.indexed_user_ids.get(&id).unwrap().to_owned(); let current_row = rows.get(ongoing_index).unwrap(); let target_row = self.rows.get_mut(¤t_row.id).unwrap(); @@ -536,11 +460,13 @@ impl UserTableData { target_row.selected_columns = self.active_columns.clone(); } else { target_row.selected_columns = HashSet::new(); + self.active_rows.remove(&target_row.id); } } else if ongoing_index <= drag_start && ongoing_index >= current_index { target_row.selected_columns = self.active_columns.clone(); } else { target_row.selected_columns = HashSet::new(); + self.active_rows.remove(&target_row.id); } } } @@ -553,12 +479,14 @@ impl UserTableData { self.active_columns.clear(); self.last_active_row = None; self.last_active_column = None; + self.active_rows.clear(); } /// Select all rows and columns fn select_all(&mut self) { let mut all_columns = vec![ColumnName::Name]; let mut current_column = ColumnName::Name.get_next(); + let mut all_rows = Vec::new(); while current_column != ColumnName::Name { all_columns.push(current_column.clone()); @@ -567,8 +495,11 @@ impl UserTableData { for (_, row) in self.rows.iter_mut() { row.selected_columns.extend(all_columns.clone()); + all_rows.push(row.id); } + self.active_columns.extend(all_columns); + self.active_rows.extend(all_rows); self.last_active_row = None; self.last_active_column = None; } @@ -578,6 +509,7 @@ impl UserTableData { self.unselected_all(); self.sorted_by = sort_by; self.sort_order = SortOrder::default(); + self.indexed_user_ids.clear(); } /// Change the order of row sorting. Called on header column click @@ -587,6 +519,7 @@ impl UserTableData { } else { self.sort_order = SortOrder::Ascending; } + self.indexed_user_ids.clear(); } /// Mark a row as whitelisted if exists @@ -602,6 +535,93 @@ impl UserTableData { row.whitelisted = false; } } + + fn sort_rows(&mut self) -> Vec { + let mut row_data: Vec = self.rows.values().cloned().collect(); + + match self.sorted_by { + ColumnName::UserID => match self.sort_order { + SortOrder::Ascending => row_data.sort_by(|a, b| a.id.cmp(&b.id)), + SortOrder::Descending => row_data.sort_by(|a, b| a.id.cmp(&b.id).reverse()), + }, + ColumnName::Name => match self.sort_order { + SortOrder::Ascending => row_data.sort_by(|a, b| a.name.cmp(&b.name)), + SortOrder::Descending => row_data.sort_by(|a, b| a.name.cmp(&b.name).reverse()), + }, + ColumnName::Username => match self.sort_order { + SortOrder::Ascending => row_data.sort_by(|a, b| a.username.cmp(&b.username)), + SortOrder::Descending => { + row_data.sort_by(|a, b| a.username.cmp(&b.username).reverse()); + } + }, + ColumnName::TotalMessage => match self.sort_order { + SortOrder::Ascending => { + row_data.sort_by(|a, b| a.total_message.cmp(&b.total_message)); + } + SortOrder::Descending => { + row_data.sort_by(|a, b| a.total_message.cmp(&b.total_message).reverse()); + } + }, + ColumnName::TotalWord => match self.sort_order { + SortOrder::Ascending => row_data.sort_by(|a, b| a.total_word.cmp(&b.total_word)), + SortOrder::Descending => { + row_data.sort_by(|a, b| a.total_word.cmp(&b.total_word).reverse()); + } + }, + ColumnName::TotalChar => match self.sort_order { + SortOrder::Ascending => row_data.sort_by(|a, b| a.total_char.cmp(&b.total_char)), + SortOrder::Descending => { + row_data.sort_by(|a, b| a.total_char.cmp(&b.total_char).reverse()); + } + }, + ColumnName::AverageChar => match self.sort_order { + SortOrder::Ascending => { + row_data.sort_by(|a, b| a.average_char.cmp(&b.average_char)); + } + SortOrder::Descending => { + row_data.sort_by(|a, b| a.average_char.cmp(&b.average_char).reverse()); + } + }, + ColumnName::AverageWord => match self.sort_order { + SortOrder::Ascending => { + row_data.sort_by(|a, b| a.average_word.cmp(&b.average_word)); + } + SortOrder::Descending => { + row_data.sort_by(|a, b| a.average_word.cmp(&b.average_word).reverse()); + } + }, + ColumnName::FirstMessageSeen => match self.sort_order { + SortOrder::Ascending => row_data.sort_by(|a, b| a.first_seen.cmp(&b.first_seen)), + SortOrder::Descending => { + row_data.sort_by(|a, b| a.first_seen.cmp(&b.first_seen).reverse()); + } + }, + ColumnName::LastMessageSeen => match self.sort_order { + SortOrder::Ascending => row_data.sort_by(|a, b| a.last_seen.cmp(&b.last_seen)), + SortOrder::Descending => { + row_data.sort_by(|a, b| a.last_seen.cmp(&b.last_seen).reverse()); + } + }, + ColumnName::Whitelisted => match self.sort_order { + SortOrder::Ascending => row_data.sort_by(|a, b| a.whitelisted.cmp(&b.whitelisted)), + SortOrder::Descending => { + row_data.sort_by(|a, b| a.whitelisted.cmp(&b.whitelisted).reverse()); + } + }, + } + + if self.indexed_user_ids.is_empty() { + let indexed_data = row_data.iter() + .enumerate() + .map(|(index, row)| (row.id, index)) + .collect(); + + self.indexed_user_ids = indexed_data; + } + + row_data + } + } impl MainWindow { From 532cd20a146ed85cec31944db056a6806002636a Mon Sep 17 00:00:00 2001 From: Rusty Pickle Date: Sat, 10 Feb 2024 18:45:45 +0600 Subject: [PATCH 3/4] Fix crash when table is actively updated --- src/ui_components/tab_ui/user_table.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/ui_components/tab_ui/user_table.rs b/src/ui_components/tab_ui/user_table.rs index 49bcf7f..388706e 100644 --- a/src/ui_components/tab_ui/user_table.rs +++ b/src/ui_components/tab_ui/user_table.rs @@ -279,6 +279,7 @@ impl UserTableData { let drag_start = self.drag_started_on.clone().unwrap(); self.select_single_row_cell(drag_start.0, &drag_start.1); + // number of the column of drag starting point and the current cell that we are trying to select let drag_start_num = drag_start.1 as i32; let ongoing_column_num = column_name.clone() as i32; @@ -336,6 +337,11 @@ impl UserTableData { // If this row already selects the column that we are trying to select, it means the mouse // moved backwards from an active column to another active column. + // + // Row: column1 column2 (mouse is here) column3 column4 + // + // In this case, if column 3 or 4 is also found in the active selection then + // the mouse moved backwards let row_contains_column = current_row.selected_columns.contains(column_name); let mut no_checking = false; @@ -398,8 +404,7 @@ impl UserTableData { } /// Recursively check the rows by either increasing or decreasing the initial index - /// till the end point or an unselected row is found. Add all columns that are selected by at least one row as selected - /// for the rows that have at least one column selected. + /// till the end point or an unselected row is found. Add active columns to the rows that have at least one column selected. fn check_row_selection( &mut self, check_previous: bool, @@ -442,7 +447,7 @@ impl UserTableData { } } - /// Checks all the rows and unselects rows that are not within the given range + /// Checks the active rows and unselects rows that are not within the given range fn remove_row_selection( &mut self, rows: &[UserRowData], @@ -536,6 +541,7 @@ impl UserTableData { } } + /// Sorts row data based on the current sort order fn sort_rows(&mut self) -> Vec { let mut row_data: Vec = self.rows.values().cloned().collect(); @@ -610,7 +616,8 @@ impl UserTableData { }, } - if self.indexed_user_ids.is_empty() { + // Will only be empty when sorting style is changed + if self.indexed_user_ids.is_empty() || self.indexed_user_ids.len() < row_data.len() { let indexed_data = row_data.iter() .enumerate() .map(|(index, row)| (row.id, index)) From c99fe2719d596849d5b70bfe0a9498f445311817 Mon Sep 17 00:00:00 2001 From: Rusty Pickle Date: Sun, 11 Feb 2024 01:54:18 +0600 Subject: [PATCH 4/4] clean up --- src/ui_components/processor/tg_comms.rs | 4 +- src/ui_components/tab_ui/user_table.rs | 69 ++++++++++++------------- src/ui_components/tab_ui/whitelist.rs | 6 +-- 3 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/ui_components/processor/tg_comms.rs b/src/ui_components/processor/tg_comms.rs index eeddf15..f962bfb 100644 --- a/src/ui_components/processor/tg_comms.rs +++ b/src/ui_components/processor/tg_comms.rs @@ -81,7 +81,7 @@ impl MainWindow { .add_user(sender, local_time_date, count_data.name()); if user_id != 0 && self.whitelist_data.is_user_whitelisted(&user_id) { - self.user_table.set_as_whitelisted(&user_id); + self.user_table.set_as_whitelisted(user_id); } let chart_user = { @@ -249,7 +249,7 @@ impl MainWindow { chat.seen_by, ); self.whitelist_data.clear_text_box(); - self.user_table.set_as_whitelisted(&user_id); + self.user_table.set_as_whitelisted(user_id); self.process_state = ProcessState::AddedToWhitelist; } ProcessResult::ChatExists(chat_name, start_at, end_at) => { diff --git a/src/ui_components/tab_ui/user_table.rs b/src/ui_components/tab_ui/user_table.rs index 388706e..7fa9035 100644 --- a/src/ui_components/tab_ui/user_table.rs +++ b/src/ui_components/tab_ui/user_table.rs @@ -302,31 +302,29 @@ impl UserTableData { // No active row removal if ctrl is being pressed! if is_ctrl_pressed { self.active_columns.insert(column_name.clone()); + } else if ongoing_column_num == drag_start_num { + new_column_set.insert(ColumnName::from_num(drag_start_num)); + self.active_columns = new_column_set; } else { - if ongoing_column_num == drag_start_num { - new_column_set.insert(ColumnName::from_num(drag_start_num)); - self.active_columns = new_column_set; - } else { - while ongoing_val.is_some() { - let col = ongoing_val.clone().unwrap(); - - let next_column = if get_previous { - col.get_next() - } else { - col.get_previous() - }; - - new_column_set.insert(col); - - if next_column == ColumnName::from_num(ongoing_column_num) { - new_column_set.insert(next_column); - ongoing_val = None; - } else { - ongoing_val = Some(next_column); - } + while ongoing_val.is_some() { + let col = ongoing_val.clone().unwrap(); + + let next_column = if get_previous { + col.get_next() + } else { + col.get_previous() + }; + + new_column_set.insert(col); + + if next_column == ColumnName::from_num(ongoing_column_num) { + new_column_set.insert(next_column); + ongoing_val = None; + } else { + ongoing_val = Some(next_column); } - self.active_columns = new_column_set; } + self.active_columns = new_column_set; } // The rows in the current sorted format @@ -339,7 +337,7 @@ impl UserTableData { // moved backwards from an active column to another active column. // // Row: column1 column2 (mouse is here) column3 column4 - // + // // In this case, if column 3 or 4 is also found in the active selection then // the mouse moved backwards let row_contains_column = current_row.selected_columns.contains(column_name); @@ -519,6 +517,7 @@ impl UserTableData { /// Change the order of row sorting. Called on header column click fn change_sort_order(&mut self) { + self.unselected_all(); if let SortOrder::Ascending = self.sort_order { self.sort_order = SortOrder::Descending; } else { @@ -528,15 +527,15 @@ impl UserTableData { } /// Mark a row as whitelisted if exists - pub fn set_as_whitelisted(&mut self, user_id: &i64) { - if let Some(row) = self.rows.get_mut(user_id) { + pub fn set_as_whitelisted(&mut self, user_id: i64) { + if let Some(row) = self.rows.get_mut(&user_id) { row.whitelisted = true; } } /// Remove whitelist status from a row if exists - pub fn remove_whitelist(&mut self, user_id: &i64) { - if let Some(row) = self.rows.get_mut(user_id) { + pub fn remove_whitelist(&mut self, user_id: i64) { + if let Some(row) = self.rows.get_mut(&user_id) { row.whitelisted = false; } } @@ -617,18 +616,18 @@ impl UserTableData { } // Will only be empty when sorting style is changed - if self.indexed_user_ids.is_empty() || self.indexed_user_ids.len() < row_data.len() { - let indexed_data = row_data.iter() - .enumerate() - .map(|(index, row)| (row.id, index)) - .collect(); + if self.indexed_user_ids.is_empty() || self.indexed_user_ids.len() != row_data.len() { + let indexed_data = row_data + .iter() + .enumerate() + .map(|(index, row)| (row.id, index)) + .collect(); self.indexed_user_ids = indexed_data; } - + row_data } - } impl MainWindow { @@ -1011,7 +1010,7 @@ impl MainWindow { for row in selected_rows { let cloned_row = row.clone(); - self.user_table.set_as_whitelisted(&row.id); + self.user_table.set_as_whitelisted(row.id); self.whitelist_data.add_to_whitelist( row.name, row.username, diff --git a/src/ui_components/tab_ui/whitelist.rs b/src/ui_components/tab_ui/whitelist.rs index 56b8ff4..c20d2e3 100644 --- a/src/ui_components/tab_ui/whitelist.rs +++ b/src/ui_components/tab_ui/whitelist.rs @@ -210,7 +210,7 @@ then right click on User Table to whitelist", let deleted = self.whitelist_data.remove_selected(); let total_to_remove = deleted.len(); for i in deleted { - self.user_table.remove_whitelist(&i); + self.user_table.remove_whitelist(i); } self.process_state = ProcessState::WhitelistedUserRemoved(total_to_remove); }; @@ -222,7 +222,7 @@ then right click on User Table to whitelist", let deleted = self.whitelist_data.remove_all(); for i in deleted { - self.user_table.remove_whitelist(&i); + self.user_table.remove_whitelist(i); } self.process_state = ProcessState::AllWhitelistRemoved; }; @@ -311,7 +311,7 @@ then right click on User Table to whitelist", let deleted = self.whitelist_data.remove_selected(); for i in deleted { - self.user_table.remove_whitelist(&i); + self.user_table.remove_whitelist(i); } ui.close_menu(); }