diff options
author | Aram Drevekenin <aram@poor.dev> | 2024-03-26 16:37:42 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-26 16:37:42 +0100 |
commit | 631ffd9bc46e9b4f79794525793e0cd2b76a10fa (patch) | |
tree | 831e987e3dfbc28a3097f5b5ebae93ef64ab67f1 | |
parent | 69835df5fc5892ff2c6587fd1a5c0a960e9da1da (diff) |
fix(ui): session manager UI fixes (#3226)
* fix(ui): display new session folder prompt always
* fix(ui): truncate session name and error on too long a name
* fix(ui): scrolling layout list in welcome screen
* style(fmt): rustfmt
-rw-r--r-- | default-plugins/session-manager/src/main.rs | 8 | ||||
-rw-r--r-- | default-plugins/session-manager/src/new_session_info.rs | 44 | ||||
-rw-r--r-- | default-plugins/session-manager/src/ui/components.rs | 41 |
3 files changed, 76 insertions, 17 deletions
diff --git a/default-plugins/session-manager/src/main.rs b/default-plugins/session-manager/src/main.rs index 7015144fd..9f37a34aa 100644 --- a/default-plugins/session-manager/src/main.rs +++ b/default-plugins/session-manager/src/main.rs @@ -383,6 +383,14 @@ impl State { fn handle_selection(&mut self) { match self.active_screen { ActiveScreen::NewSession => { + if self.new_session_info.name().len() >= 108 { + // this is due to socket path limitations + // TODO: get this from Zellij (for reference: this is part of the interprocess + // package, we should get if from there if possible because it's configurable + // through the package) + self.show_error("Session name must be shorter than 108 bytes"); + return; + } self.new_session_info.handle_selection(&self.session_name); }, ActiveScreen::AttachToSession => { diff --git a/default-plugins/session-manager/src/new_session_info.rs b/default-plugins/session-manager/src/new_session_info.rs index 02e539668..200ff0849 100644 --- a/default-plugins/session-manager/src/new_session_info.rs +++ b/default-plugins/session-manager/src/new_session_info.rs @@ -126,21 +126,28 @@ impl NewSessionInfo { pub fn update_layout_list(&mut self, layout_info: Vec<LayoutInfo>) { self.layout_list.update_layout_list(layout_info); } - pub fn layout_list(&self) -> Vec<(LayoutInfo, bool)> { + pub fn layout_list(&self, max_rows: usize) -> Vec<(LayoutInfo, bool)> { // bool - is_selected + let range_to_render = self.range_to_render( + max_rows, + self.layout_count(), + Some(self.layout_list.selected_layout_index), + ); self.layout_list .layout_list .iter() .enumerate() .map(|(i, l)| (l.clone(), i == self.layout_list.selected_layout_index)) + .take(range_to_render.1) + .skip(range_to_render.0) .collect() } - pub fn layouts_to_render(&self) -> Vec<(LayoutInfo, Vec<usize>, bool)> { + pub fn layouts_to_render(&self, max_rows: usize) -> Vec<(LayoutInfo, Vec<usize>, bool)> { // (layout_info, // search_indices, // is_selected) if self.is_searching() { - self.layout_search_results() + self.layout_search_results(max_rows) .into_iter() .map(|(layout_search_result, is_selected)| { ( @@ -151,21 +158,48 @@ impl NewSessionInfo { }) .collect() } else { - self.layout_list() + self.layout_list(max_rows) .into_iter() .map(|(layout_info, is_selected)| (layout_info, vec![], is_selected)) .collect() } } - pub fn layout_search_results(&self) -> Vec<(LayoutSearchResult, bool)> { + pub fn layout_search_results(&self, max_rows: usize) -> Vec<(LayoutSearchResult, bool)> { // bool - is_selected + let range_to_render = self.range_to_render( + max_rows, + self.layout_list.layout_search_results.len(), + Some(self.layout_list.selected_layout_index), + ); self.layout_list .layout_search_results .iter() .enumerate() .map(|(i, l)| (l.clone(), i == self.layout_list.selected_layout_index)) + .take(range_to_render.1) + .skip(range_to_render.0) .collect() } + // TODO: merge with similar function in resurrectable_sessions + fn range_to_render( + &self, + table_rows: usize, + results_len: usize, + selected_index: Option<usize>, + ) -> (usize, usize) { + if table_rows <= results_len { + let row_count_to_render = table_rows.saturating_sub(1); // 1 for the title + let first_row_index_to_render = selected_index + .unwrap_or(0) + .saturating_sub(row_count_to_render / 2); + let last_row_index_to_render = first_row_index_to_render + row_count_to_render; + (first_row_index_to_render, last_row_index_to_render) + } else { + let first_row_index_to_render = 0; + let last_row_index_to_render = results_len; + (first_row_index_to_render, last_row_index_to_render) + } + } pub fn is_searching(&self) -> bool { !self.layout_list.layout_search_term.is_empty() } diff --git a/default-plugins/session-manager/src/ui/components.rs b/default-plugins/session-manager/src/ui/components.rs index d44fddf44..5c265f542 100644 --- a/default-plugins/session-manager/src/ui/components.rs +++ b/default-plugins/session-manager/src/ui/components.rs @@ -709,6 +709,23 @@ pub fn render_new_session_block( long_instruction, ); } else { + let space_for_new_session_name = + max_cols_of_new_session_block.saturating_sub(prompt.width() + 18); + let new_session_name = if new_session_name.width() > space_for_new_session_name { + let mut truncated = String::new(); + for character in new_session_name.chars().rev() { + if truncated.width() + character.width().unwrap_or(0) + < space_for_new_session_name + { + truncated.push(character); + } else { + break; + } + } + format!("...{}", truncated.chars().rev().collect::<String>()) + } else { + new_session_name.to_owned() + }; println!( "\u{1b}[m{}{} {}_ {}", format!("\u{1b}[{};{}H", y + 1, x + 1), @@ -747,18 +764,23 @@ pub fn render_new_session_block( } render_layout_selection_list( new_session_info, - colors, - max_rows_of_new_session_block.saturating_sub(1), + max_rows_of_new_session_block.saturating_sub(8), max_cols_of_new_session_block, x, y + 1, ); } + render_new_session_folder_prompt( + new_session_info, + colors, + x, + (y + max_rows_of_new_session_block).saturating_sub(3), + max_cols_of_new_session_block, + ); } pub fn render_layout_selection_list( new_session_info: &NewSessionInfo, - colors: Colors, max_rows_of_new_session_block: usize, max_cols_of_new_session_block: usize, x: usize, @@ -786,8 +808,10 @@ pub fn render_layout_selection_list( print_text_with_coordinates(layout_indication_line, x, y + 1, None, None); println!(); let mut table = Table::new(); - for (i, (layout_info, indices, is_selected)) in - new_session_info.layouts_to_render().into_iter().enumerate() + for (i, (layout_info, indices, is_selected)) in new_session_info + .layouts_to_render(max_rows_of_new_session_block) + .into_iter() + .enumerate() { let layout_name = layout_info.name(); let layout_name_len = layout_name.width(); @@ -818,13 +842,6 @@ pub fn render_layout_selection_list( } let table_y = y + 3; print_table_with_coordinates(table, x, table_y, None, None); - render_new_session_folder_prompt( - new_session_info, - colors, - x, - (y + max_rows_of_new_session_block).saturating_sub(3), - max_cols_of_new_session_block, - ); } pub fn render_error(error_text: &str, rows: usize, columns: usize, x: usize, y: usize) { |