use std::collections::HashMap;
use ratatui::layout::Rect;
use super::data::{DataSource, MessageTail};
use super::filter::FilterState;
use super::grid::EventsGrid;
use super::icons::IconSet;
use super::layout::PanelLayout;
use super::mouse::DragState;
use super::theme::Theme;
use super::tree::{SessionTree, TreeItem};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FocusedPane {
Sessions,
Events,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum InputMode {
Normal,
FilterInput,
Visual,
}
pub struct App<'a> {
pub theme: &'a Theme,
pub icons: &'a IconSet,
pub data: Box<dyn DataSource>,
pub focus: FocusedPane,
pub tree: SessionTree,
pub grid: EventsGrid<'a>,
pub filter: Option<FilterState>,
pub input_mode: InputMode,
pub sessions_visible: bool,
pub sessions_width_ratio: f64,
pub drag_state: DragState,
pub quit: bool,
pub tree_area: Rect,
pub grid_area: Rect,
pub grid_layout: Option<PanelLayout>,
pub tails: HashMap<String, Box<dyn MessageTail>>,
}
impl<'a> App<'a> {
pub fn new(
theme: &'a Theme,
icons: &'a IconSet,
data: Box<dyn DataSource>,
sessions_width_ratio: f64,
) -> anyhow::Result<Self> {
let rows = data.list_sessions()?;
let active_ids: Vec<String> = rows
.iter()
.filter(|r| r.alive)
.map(|r| r.info.id.clone())
.collect();
let mut tree = SessionTree::from_sessions(rows);
let mut grid = EventsGrid::new(theme, icons);
for id in &active_ids {
grid.open_panel(id.clone());
}
let first_active =
tree.visible_items()
.iter()
.enumerate()
.find_map(|(i, item)| match item {
TreeItem::Session { row, .. } if row.alive => Some(i),
_ => None,
});
if let Some(cursor) = first_active {
tree.cursor = cursor;
}
Ok(Self {
theme,
icons,
data,
focus: FocusedPane::Sessions,
tree,
grid,
filter: None,
input_mode: InputMode::Normal,
sessions_visible: true,
sessions_width_ratio,
drag_state: DragState::Idle,
quit: false,
tree_area: Rect::default(),
grid_area: Rect::default(),
grid_layout: None,
tails: HashMap::new(),
})
}
}