Working scrollbar

This commit is contained in:
Marco De Araujo 2026-01-10 11:19:19 -04:00
parent df1d1dddc6
commit 000e31a14f
4 changed files with 58 additions and 26 deletions

View file

@ -174,7 +174,6 @@ impl App {
}
if area.len() <= 1 {
let _formgen = area[0].height;
dbg!(area[0].height);
return;
}

View file

@ -9,7 +9,11 @@ use ratatui::{
use crate::i18n::t;
use chrono::Local;
pub fn render_footer(frame: &mut Frame, area: Rect, seconds_until_update: u64) {
pub fn render_footer(
frame: &mut Frame,
area: Rect,
seconds_until_update: u64
) {
let now = Local::now();
let datatime_str = now.format("%Y-%m-%d %H:%M:%S").to_string();
let countdown_str = format!("{}s", seconds_until_update);

View file

@ -3,7 +3,7 @@ use std::cmp::min;
use crate::i18n::t;
use crate::ui::dashboard::{
MonitorStatus, MonitorViewState,
model::{DashboardViewState, GroupViewState, BORDER_LINES_VIEW},
model::{BORDER_LINES_VIEW, DashboardViewState, GroupViewState},
};
use ratatui::{
Frame,
@ -16,26 +16,51 @@ use ratatui::{
const STATUS_LINE_LENGTH: usize = 100;
const MAX_NAME_LENGTH: usize = 30;
pub fn render_monitor_list(main_frame: &mut Frame, area: Rect, state: &DashboardViewState) {
let constraints: Vec<Constraint> = state
.groups
.iter()
.map(|g| {
let height_neeed = BORDER_LINES_VIEW + g.monitors.len();
Constraint::Length(height_neeed as u16)
})
.collect();
pub fn render_monitor_list(main_frame: &mut Frame, area: Rect, state: &mut DashboardViewState) {
let available_height = area.height as usize;
let total_lenght = state.get_total_lenght();
if constraints.is_empty() {
return;
if (state.scroll_state.get_position() + available_height) > total_lenght {
state.scroll_state = state.scroll_state.position(total_lenght - available_height);
}
let group_areas = Layout::vertical(constraints).split(area);
let scroll_pos = state.scroll_state.get_position();
let mut current_y = area.y as usize;
let mut rendered_height = 0;
let mut lines_skipped = 0;
for (i, (group, &group_area)) in state.groups.iter().zip(group_areas.iter()).enumerate() {
if group_area.height > 0 {
render_group(main_frame, group_area, group, i == 0);
for (i, group) in state.groups.iter().enumerate() {
let group_height = group.monitors.len() + BORDER_LINES_VIEW;
if lines_skipped + group_height <= scroll_pos {
lines_skipped += group_height;
continue;
}
let visible_height = if lines_skipped < scroll_pos {
group_height - (scroll_pos - lines_skipped)
} else {
group_height
}
.min(available_height - rendered_height);
let group_area = Rect {
x: area.x,
y: current_y as u16,
width: area.width,
height: visible_height as u16,
};
render_group(
main_frame,
group_area,
group,
i == 0 && lines_skipped >= scroll_pos,
);
current_y += visible_height;
rendered_height += visible_height;
lines_skipped += group_height;
}
}

View file

@ -37,7 +37,7 @@ pub struct DashboardViewState {
pub error_message: Option<String>,
pub auto_refresh_interval: u32,
pub scroll_state: ScrollbarState,
content_length: usize,
total_length: usize,
}
impl DashboardViewState {
@ -50,7 +50,7 @@ impl DashboardViewState {
error_message: None,
auto_refresh_interval: 300,
scroll_state: ScrollbarState::new(0),
content_length: 0,
total_length: 0,
}
}
@ -64,10 +64,10 @@ impl DashboardViewState {
});
}
let content_length = groups
let total_length: usize = groups
.iter()
.map(|g| g.monitors.len() + BORDER_LINES_VIEW)
.sum::<usize>();
.sum();
Self {
title: data.title,
@ -76,17 +76,21 @@ impl DashboardViewState {
is_loading: false,
error_message: None,
auto_refresh_interval: data.auto_refresh_interval.max(30),
scroll_state: ScrollbarState::new(content_length.saturating_sub(1)),
content_length,
scroll_state: ScrollbarState::new(total_length.saturating_sub(1)),
total_length,
}
}
pub fn get_total_lenght(&self) -> usize {
self.total_length
}
pub fn get_all_monitors(&self) -> Vec<&MonitorViewState> {
self.groups.iter().flat_map(|g| g.monitors.iter()).collect()
}
pub fn show_vertical_scrollbar(&self, height: u16) -> bool {
height < self.content_length as u16
pub fn show_vertical_scrollbar(&self, available_height: u16) -> bool {
self.total_length as u16 > available_height
}
}