diff --git a/boot_diags/src/app.rs b/boot_diags/src/app.rs index baed950..14e8e4f 100644 --- a/boot_diags/src/app.rs +++ b/boot_diags/src/app.rs @@ -39,6 +39,8 @@ use core::{ tui::{Event, Tui}, }; use std::{ + array, + collections::HashMap, env, iter::zip, path::PathBuf, @@ -74,6 +76,7 @@ pub struct App { boot_modes: Vec, selections: Vec>, system32: String, + results: Arc>>, tasks: Tasks, } @@ -81,6 +84,16 @@ impl App { pub fn new(tick_rate: f64, frame_rate: f64) -> Result { let (action_tx, action_rx) = mpsc::unbounded_channel(); let disk_list_arc = Arc::new(Mutex::new(Vec::new())); + let mut results_fake = HashMap::new(); + results_fake.insert(String::from("1. One"), String::from("Line one,\nline two")); + results_fake.insert( + String::from("2. Two"), + String::from("Another example?\n¯\\_(ツ)_/¯"), + ); + let too_many_lines: [usize; 75] = array::from_fn(|i| i + 1); + let too_many_lines: Vec = too_many_lines.iter().map(|x| format!("{x}")).collect(); + results_fake.insert(String::from("3. Three"), too_many_lines.join("\n")); + let results_arc = Arc::new(Mutex::new(results_fake)); let tasks = Tasks::new(action_tx.clone(), disk_list_arc.clone()); let mut list = StatefulList::default(); list.set_items(vec![ @@ -101,7 +114,9 @@ impl App { Box::new(Footer::new()), Box::new(popup::Popup::new()), Box::new(crate::components::progress::Progress::new()), - Box::new(crate::components::results::Results::new()), + Box::new(crate::components::results::Results::new( + results_arc.clone(), + )), ], config: Config::new()?, diag_groups: diags::Groups::new(), @@ -117,6 +132,7 @@ impl App { boot_modes: vec![SafeMode::Enable, SafeMode::Disable], system32: String::new(), selections: vec![None, None], + results: results_arc, tasks, }) } @@ -582,6 +598,7 @@ impl App { "Program Files", "Program Files (x86)", "ProgramData", + "Haha.....no", "Windows\\System32\\config", ] .iter() @@ -657,14 +674,14 @@ impl App { fn render(&mut self, tui: &mut Tui) -> Result<()> { tui.draw(|frame| { - if let [header, _body, footer, left, right, popup, progress] = + if let [header, _body, footer, left, right, popup, progress, results] = get_chunks(frame.area())[..] { let component_areas = vec![ header, // Title Bar header, // FPS Counter left, right, footer, popup, // core - progress, header, // boot-diags + progress, results, // boot-diags ]; for (component, area) in zip(self.components.iter_mut(), component_areas) { if let Err(err) = component.draw(frame, area) { @@ -732,6 +749,9 @@ fn get_chunks(r: Rect) -> Vec { // Progress chunks.push(centered_rect(60, 80, chunks[1])); + // Results + chunks.push(centered_rect(60, 80, chunks[1])); + // Done chunks } diff --git a/boot_diags/src/components/results.rs b/boot_diags/src/components/results.rs index badd97a..759f8c3 100644 --- a/boot_diags/src/components/results.rs +++ b/boot_diags/src/components/results.rs @@ -14,20 +14,38 @@ // along with Deja-Vu. If not, see . // use color_eyre::Result; -use ratatui::{Frame, layout::Rect}; +use ratatui::{ + Frame, + layout::{Constraint, Direction, Layout, Rect}, + style::{Style, Stylize}, + widgets::{Block, Clear, Padding, Paragraph, Tabs}, +}; -use core::{action::Action, components::Component}; +use core::{action::Action, components::Component, state::Mode}; +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; #[derive(Default, Debug, Clone)] pub struct Results { // command_tx: Option>, // config: Config, + key_index: usize, + line_index: u16, + results: Arc>>, + show: bool, } impl Results { #[must_use] - pub fn new() -> Self { - Self::default() + pub fn new(results: Arc>>) -> Self { + Results { + key_index: 0, + line_index: 0, + results, + show: false, + } } // fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<()> { @@ -42,11 +60,74 @@ impl Results { } impl Component for Results { - fn update(&mut self, _action: Action) -> Result> { + fn update(&mut self, action: Action) -> Result> { + match action { + Action::KeyUp => { + if self.line_index > 0 { + self.line_index = self.line_index - 1; + } + } + Action::KeyDown => { + self.line_index = self.line_index + 1; + } + Action::KeyLeft => { + if self.key_index > 0 { + self.key_index -= 1; + self.line_index = 0; + } + } + Action::KeyRight => { + if self.key_index < 2 { + self.key_index += 1; + self.line_index = 0; + } + } + Action::SetMode(mode) => { + self.show = mode == Mode::BootDiags; + } + _ => {} + }; Ok(None) } - fn draw(&mut self, _frame: &mut Frame, _area: Rect) -> Result<()> { + fn draw(&mut self, frame: &mut Frame, rect: Rect) -> Result<()> { + if !self.show { + return Ok(()); + } + let areas = Layout::default() + .direction(Direction::Vertical) + .constraints([Constraint::Length(3), Constraint::Min(0)]) + .split(rect) + .to_vec(); + + if let Ok(results_hashmap) = self.results.lock() { + // Labels + let mut tab_labels: Vec<&str> = results_hashmap.keys().map(|k| k.as_str()).collect(); + tab_labels.sort(); + let hash_key = tab_labels.get(self.key_index).unwrap().to_string(); + let tabs = Tabs::new(tab_labels) + .block(Block::bordered()) + .style(Style::default().white()) + .highlight_style(Style::default().green()) + .select(self.key_index) + .divider("") + .padding(" [", "] "); + + // Details + let details = if let Some(lines) = results_hashmap.get(&hash_key) { + lines.clone() + } else { + String::from("¯\\_(ツ)_/¯") + }; + let paragraph = Paragraph::new(details) + .scroll((self.line_index, 0)) + .block(Block::bordered().padding(Padding::horizontal(1))); + + // Render + frame.render_widget(Clear, rect); + frame.render_widget(tabs, areas[0]); + frame.render_widget(paragraph, areas[1]); + } Ok(()) } } diff --git a/config/config.json5 b/config/config.json5 index 802c914..f0befab 100644 --- a/config/config.json5 +++ b/config/config.json5 @@ -109,6 +109,8 @@ "": "Process", "": "KeyUp", "": "KeyDown", + "": "KeyLeft", + "": "KeyRight", "": "BootScan", "": "Quit", "": "Quit", diff --git a/core/src/action.rs b/core/src/action.rs index 4a2c7d4..d067140 100644 --- a/core/src/action.rs +++ b/core/src/action.rs @@ -66,6 +66,8 @@ pub enum Action { Help, KeyDown, KeyUp, + KeyLeft, + KeyRight, Quit, Render, Resize(u16, u16),