use color_eyre::Result; use ratatui::{ layout::Rect, style::{Style, Stylize}, text::Span, widgets::Paragraph, Frame, }; use super::Component; use crate::{ action::Action, widgets::{DotSpinner, OghamCenter, VerticalBlocks} }; #[derive(Debug, Clone, PartialEq)] pub struct Health { name: Option<String>, peers: Option<usize>, is_syncing: bool, should_have_peers: bool, tx_pool_length: usize, validators_count: u32, nominators_count: u32, } impl Default for Health { fn default() -> Self { Self::new() } } impl Health { pub fn new() -> Self { Self { name: None, peers: None, is_syncing: true, should_have_peers: false, tx_pool_length: 0, validators_count: 0, nominators_count: 0, } } pub fn is_syncing_as_string(&self) -> String { if self.is_syncing { format!("syncing {}", VerticalBlocks::default().to_string()) } else { String::from("synced") } } pub fn peers_as_string(&self) -> String { match self.peers { Some(peers) => peers.to_string(), None => DotSpinner::default().to_string(), } } pub fn name_as_string(&self) -> String { match &self.name { Some(name) => name.clone(), None => OghamCenter::default().to_string(), } } } impl Component for Health { fn update(&mut self, action: Action) -> Result<Option<Action>> { match action { Action::SetSystemHealth(peers, is_syncing, should_have_peers) => { self.peers = peers; self.is_syncing = is_syncing; self.should_have_peers = should_have_peers; }, Action::SetNodeName(name) => self.name = name, Action::SetPendingExtrinsicsLength(length) => self.tx_pool_length = length, Action::NominatorsNumber(number) => self.nominators_count = number, Action::ValidatorsNumber(number) => self.validators_count = number, _ => {} }; Ok(None) } fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> { let [place, _] = super::header_layout(area); let message = format!("{:^12} | tx.pool: {:^3} | peers: {:^3} | {:^9} | validators {:^4} | nominators {:^4} |", self.name_as_string(), self.tx_pool_length, self.peers_as_string(), self.is_syncing_as_string(), self.validators_count, self.nominators_count); let span = Span::styled(message, Style::new().dim()); let paragraph = Paragraph::new(span).left_aligned(); frame.render_widget(paragraph, place); Ok(()) } }