diff --git a/socktop/src/app.rs b/socktop/src/app.rs index d2fe40d..654a7bc 100644 --- a/socktop/src/app.rs +++ b/socktop/src/app.rs @@ -67,6 +67,9 @@ pub struct App { // For reconnects ws_url: String, + // Security / status flags + pub is_tls: bool, + pub has_token: bool, } impl App { @@ -97,6 +100,8 @@ impl App { disks_interval: Duration::from_secs(5), metrics_interval: Duration::from_millis(500), ws_url: String::new(), + is_tls: false, + has_token: false, } } @@ -110,6 +115,12 @@ impl App { self } + pub fn with_status(mut self, is_tls: bool, has_token: bool) -> Self { + self.is_tls = is_tls; + self.has_token = has_token; + self + } + pub async fn run( &mut self, url: &str, @@ -363,7 +374,15 @@ impl App { .split(area); // Header - draw_header(f, rows[0], self.last_metrics.as_ref()); + draw_header( + f, + rows[0], + self.last_metrics.as_ref(), + self.is_tls, + self.has_token, + self.metrics_interval, + self.procs_interval, + ); // Top row: left CPU avg, right Per-core (full top-right) let top_lr = ratatui::layout::Layout::default() @@ -485,6 +504,8 @@ impl Default for App { disks_interval: Duration::from_secs(5), metrics_interval: Duration::from_millis(500), ws_url: String::new(), + is_tls: false, + has_token: false, } } } diff --git a/socktop/src/main.rs b/socktop/src/main.rs index 1779626..c1f6c67 100644 --- a/socktop/src/main.rs +++ b/socktop/src/main.rs @@ -272,7 +272,11 @@ async fn main() -> Result<(), Box> { return Ok(()); } }; - let mut app = App::new().with_intervals(metrics_interval_ms, processes_interval_ms); + let is_tls = url.starts_with("wss://"); + let has_token = url.contains("token="); + let mut app = App::new() + .with_intervals(metrics_interval_ms, processes_interval_ms) + .with_status(is_tls, has_token); if parsed.dry_run { return Ok(()); } diff --git a/socktop/src/ui/header.rs b/socktop/src/ui/header.rs index c830bfe..0f9a027 100644 --- a/socktop/src/ui/header.rs +++ b/socktop/src/ui/header.rs @@ -1,13 +1,22 @@ //! Top header with hostname and CPU temperature indicator. use crate::types::Metrics; +use std::time::Duration; use ratatui::{ layout::Rect, widgets::{Block, Borders}, }; -pub fn draw_header(f: &mut ratatui::Frame<'_>, area: Rect, m: Option<&Metrics>) { - let title = if let Some(mm) = m { +pub fn draw_header( + f: &mut ratatui::Frame<'_>, + area: Rect, + m: Option<&Metrics>, + is_tls: bool, + has_token: bool, + metrics_interval: Duration, + procs_interval: Duration, +) { + let base = if let Some(mm) = m { let temp = mm .cpu_temp_c .map(|t| { @@ -21,12 +30,19 @@ pub fn draw_header(f: &mut ratatui::Frame<'_>, area: Rect, m: Option<&Metrics>) format!("CPU Temp: {t:.1}°C {icon}") }) .unwrap_or_else(|| "CPU Temp: N/A".into()); - format!( - "socktop — host: {} | {} (press 'q' to quit)", - mm.hostname, temp - ) + format!("socktop — host: {} | {}", mm.hostname, temp) } else { - "socktop — connecting... (press 'q' to quit)".into() + "socktop — connecting...".into() }; + let tls_txt = if is_tls { "🔒TLS" } else { "🔓WS" }; + let tok_txt = if has_token { "🔑token" } else { "" }; + let mi = metrics_interval.as_millis(); + let pi = procs_interval.as_millis(); + let intervals = format!("⏱{mi}ms metrics | {pi}ms procs"); + let mut parts = vec![base, tls_txt.into()]; + if !tok_txt.is_empty() { parts.push(tok_txt.into()); } + parts.push(intervals); + parts.push("(q to quit)".into()); + let title = parts.join(" | "); f.render_widget(Block::default().title(title).borders(Borders::BOTTOM), area); }