From df1d1dddc6759fcfdff8494f7350c4ecd3934670 Mon Sep 17 00:00:00 2001 From: Marco De Araujo Date: Fri, 9 Jan 2026 11:56:35 -0400 Subject: [PATCH] Scrollbar initial values --- src/ui/app.rs | 30 ++++++++++++++++++++---------- src/ui/components/monitor_list.rs | 4 ++-- src/ui/dashboard/model.rs | 7 +++++-- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/ui/app.rs b/src/ui/app.rs index 76dead9..4d2dbca 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -116,13 +116,19 @@ impl App { fn render(&mut self) { let _ = self.terminal.draw(|frame| { let area = frame.area(); + + const HEADER_HEIGHT: u16 = 3; + const FOOTER_HEIGHT: u16 = 3; + + let max_content_height = area.height.saturating_sub(HEADER_HEIGHT + FOOTER_HEIGHT); + let chunks = Layout::default() .direction(Direction::Vertical) .margin(1) .constraints([ - Constraint::Length(3), - Constraint::Min(1), - Constraint::Length(3), + Constraint::Length(HEADER_HEIGHT), + Constraint::Length(max_content_height.max(1)), + Constraint::Length(FOOTER_HEIGHT), ]) .split(area); @@ -177,7 +183,13 @@ impl App { .begin_symbol(Some("↑")) .end_symbol(Some("↓")); - frame.render_stateful_widget(scrollbar, area[1], &mut state.scroll_state); + frame.render_stateful_widget( + scrollbar, + area[1], + &mut state + .scroll_state + .viewport_content_length(area[0].height as usize), + ); } fn handle_events(&mut self) -> io::Result<()> { @@ -191,12 +203,10 @@ impl App { match key.code { KeyCode::Char('q') | KeyCode::Esc => self.should_quit = true, - KeyCode::Up | KeyCode::Char('k') => { - self.state.scroll_state.prev(); - } - KeyCode::Down | KeyCode::Char('j') => { - self.state.scroll_state.next(); - } + KeyCode::Up | KeyCode::Char('k') => self.state.scroll_state.prev(), + KeyCode::Down | KeyCode::Char('j') => self.state.scroll_state.next(), + KeyCode::Home => self.state.scroll_state.first(), + KeyCode::End => self.state.scroll_state.last(), _ => {} } } diff --git a/src/ui/components/monitor_list.rs b/src/ui/components/monitor_list.rs index 31dd468..0fc4256 100644 --- a/src/ui/components/monitor_list.rs +++ b/src/ui/components/monitor_list.rs @@ -3,7 +3,7 @@ use std::cmp::min; use crate::i18n::t; use crate::ui::dashboard::{ MonitorStatus, MonitorViewState, - model::{DashboardViewState, GroupViewState}, + model::{DashboardViewState, GroupViewState, BORDER_LINES_VIEW}, }; use ratatui::{ Frame, @@ -21,7 +21,7 @@ pub fn render_monitor_list(main_frame: &mut Frame, area: Rect, state: &Dashboard .groups .iter() .map(|g| { - let height_neeed = 3 + g.monitors.len(); + let height_neeed = BORDER_LINES_VIEW + g.monitors.len(); Constraint::Length(height_neeed as u16) }) .collect(); diff --git a/src/ui/dashboard/model.rs b/src/ui/dashboard/model.rs index c408c54..a375ed9 100644 --- a/src/ui/dashboard/model.rs +++ b/src/ui/dashboard/model.rs @@ -4,7 +4,7 @@ use crate::i18n::t; use ratatui::widgets::ScrollbarState; use rayon::prelude::*; -const BORDER_LINES_VIEW: usize = 3; +pub const BORDER_LINES_VIEW: usize = 3; #[derive(Debug, Clone, PartialEq)] pub enum MonitorStatus { @@ -37,6 +37,7 @@ pub struct DashboardViewState { pub error_message: Option, pub auto_refresh_interval: u32, pub scroll_state: ScrollbarState, + content_length: usize, } impl DashboardViewState { @@ -49,6 +50,7 @@ impl DashboardViewState { error_message: None, auto_refresh_interval: 300, scroll_state: ScrollbarState::new(0), + content_length: 0, } } @@ -75,6 +77,7 @@ impl DashboardViewState { error_message: None, auto_refresh_interval: data.auto_refresh_interval.max(30), scroll_state: ScrollbarState::new(content_length.saturating_sub(1)), + content_length, } } @@ -83,7 +86,7 @@ impl DashboardViewState { } pub fn show_vertical_scrollbar(&self, height: u16) -> bool { - height < self.get_all_monitors().len() as u16 + height < self.content_length as u16 } }