diff --git a/tui/src/state.rs b/tui/src/state.rs index ca405162..c495e2be 100644 --- a/tui/src/state.rs +++ b/tui/src/state.rs @@ -33,6 +33,7 @@ pub struct AppState { /// widget selection: ListState, filter: Filter, + drawable: bool, } pub enum Focus { @@ -60,11 +61,55 @@ impl AppState { visit_stack: vec![root_id], selection: ListState::default().with_selected(Some(0)), filter: Filter::new(), + drawable: false, }; state.update_items(); state } pub fn draw(&mut self, frame: &mut Frame) { + let terminal_size = frame.area(); + let min_width = 77; // Minimum width threshold + let min_height = 19; // Minimum height threshold + + if terminal_size.width < min_width || terminal_size.height < min_height { + let size_warning_message = format!( + "Terminal size too small:\nWidth = {} Height = {}\n\nMinimum size:\nWidth = {} Height = {}", + terminal_size.width, + terminal_size.height, + min_width, + min_height, + ); + + let warning_paragraph = Paragraph::new(size_warning_message.clone()) + .alignment(Alignment::Center) + .style(Style::default().fg(ratatui::style::Color::Red).bold()) + .wrap(ratatui::widgets::Wrap { trim: true }); + + // Get the maximum width and height of text lines + let text_lines: Vec = size_warning_message + .lines() + .map(|line| line.to_string()) + .collect(); + let max_line_length = text_lines.iter().map(|line| line.len()).max().unwrap_or(0); + let num_lines = text_lines.len(); + + // Calculate the centered area + let centered_area = ratatui::layout::Rect { + x: terminal_size.x + (terminal_size.width - max_line_length as u16) / 2, + y: terminal_size.y + (terminal_size.height - num_lines as u16) / 2, + width: max_line_length as u16, + height: num_lines as u16, + }; + frame.render_widget(warning_paragraph, centered_area); + self.drawable = false; + } else { + self.drawable = true; + } + + if !self.drawable { + return; + } + let label_block = Block::default() .borders(Borders::all()) @@ -187,6 +232,21 @@ impl AppState { } pub fn handle_key(&mut self, key: &KeyEvent) -> bool { + // This should be defined first to allow closing + // the application even when not drawable ( If terminal is small ) + if matches!(self.focus, Focus::TabList | Focus::List) { + if key.code == KeyCode::Char('q') + || key.code == KeyCode::Char('c') && key.modifiers.contains(KeyModifiers::CONTROL) + { + return false; + } + } + + // If UI is not drawable returning true will mark as the key handled + if !self.drawable { + return true; + } + match &mut self.focus { Focus::FloatingWindow(command) => { if command.handle_key_event(key) {