Skip to content

Commit 9323dfc

Browse files
WIP theming
1 parent f221ab3 commit 9323dfc

File tree

5 files changed

+406
-106
lines changed

5 files changed

+406
-106
lines changed

src/tui/app.rs

Lines changed: 84 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use crate::measurements::Measurement;
22
use crate::speedtest::{Metadata, TestType};
3+
use crate::tui::theme::{ThemedStyles, TokyoNight};
34
use crossbeam_channel::Receiver;
45
use crossterm::event::{self, Event, KeyCode, KeyEventKind};
56
use ratatui::{
67
backend::CrosstermBackend,
78
layout::{Constraint, Direction, Layout, Rect},
8-
style::{Color, Style},
99
widgets::{Block, Borders, Paragraph},
1010
Frame, Terminal,
1111
};
@@ -384,16 +384,20 @@ impl App {
384384
fn draw_title(&self, f: &mut Frame, area: Rect) {
385385
let title_text = if let Some(ref metadata) = self.state.metadata {
386386
format!(
387-
"Cloudflare Speed Test - {} {} | IP: {} | Colo: {}",
387+
" Cloudflare Speed Test - {} {} | IP: {} | Colo: {}",
388388
metadata.city, metadata.country, metadata.ip, metadata.colo
389389
)
390390
} else {
391-
"Cloudflare Speed Test - Loading...".to_string()
391+
" Cloudflare Speed Test - Loading...".to_string()
392392
};
393393

394394
let title = Paragraph::new(title_text)
395-
.style(Style::default().fg(Color::Cyan))
396-
.block(Block::default().borders(Borders::ALL));
395+
.style(ThemedStyles::title())
396+
.block(
397+
Block::default()
398+
.borders(Borders::ALL)
399+
.border_style(ThemedStyles::title_border()),
400+
);
397401
f.render_widget(title, area);
398402
}
399403

@@ -412,33 +416,36 @@ impl App {
412416
let upload_progress = self.calculate_adaptive_progress(TestType::Upload);
413417

414418
// Download status with progress bar and text
415-
let download_color = match self.state.progress.phase {
416-
TestPhase::Download => Color::Green,
417-
TestPhase::Completed if download_progress >= 1.0 => Color::Green,
418-
_ if download_progress >= 1.0 => Color::Green,
419-
_ => Color::Gray,
419+
let download_style = match self.state.progress.phase {
420+
TestPhase::Download => ThemedStyles::progress_download_active(),
421+
TestPhase::Completed if download_progress >= 1.0 => {
422+
ThemedStyles::progress_download_complete()
423+
}
424+
_ if download_progress >= 1.0 => ThemedStyles::progress_download_complete(),
425+
_ => ThemedStyles::progress_inactive(),
420426
};
421427

422-
let download_text = format!("Download: {}", self.state.progress.download_status);
423-
let download_paragraph =
424-
Paragraph::new(download_text).style(Style::default().fg(download_color));
428+
let download_text = format!(" Download: {}", self.state.progress.download_status);
429+
let download_paragraph = Paragraph::new(download_text).style(download_style);
425430
f.render_widget(download_paragraph, chunks[0]);
426431

427432
// Upload status with progress bar and text
428-
let upload_color = match self.state.progress.phase {
429-
TestPhase::Upload => Color::Blue,
430-
TestPhase::Completed if upload_progress >= 1.0 => Color::Blue,
431-
_ if upload_progress >= 1.0 => Color::Blue,
432-
_ => Color::Gray,
433+
let upload_style = match self.state.progress.phase {
434+
TestPhase::Upload => ThemedStyles::progress_upload_active(),
435+
TestPhase::Completed if upload_progress >= 1.0 => {
436+
ThemedStyles::progress_upload_complete()
437+
}
438+
_ if upload_progress >= 1.0 => ThemedStyles::progress_upload_complete(),
439+
_ => ThemedStyles::progress_inactive(),
433440
};
434441

435-
let upload_text = format!("Upload: {}", self.state.progress.upload_status);
436-
let upload_paragraph = Paragraph::new(upload_text).style(Style::default().fg(upload_color));
442+
let upload_text = format!(" Upload: {}", self.state.progress.upload_status);
443+
let upload_paragraph = Paragraph::new(upload_text).style(upload_style);
437444
f.render_widget(upload_paragraph, chunks[1]);
438445

439446
// Latency stats in a compact single line
440447
let latency_text = format!(
441-
"Latency: Current: {:.1}ms | Average: {:.1}ms | Min/Max: {:.1}ms / {:.1}ms",
448+
" Latency: Current: {:.1}ms | Average: {:.1}ms | Min/Max: {:.1}ms / {:.1}ms",
442449
self.state.current_latency,
443450
self.state.avg_latency,
444451
if self.state.min_latency == f64::MAX {
@@ -448,8 +455,7 @@ impl App {
448455
},
449456
self.state.max_latency
450457
);
451-
let latency_paragraph =
452-
Paragraph::new(latency_text).style(Style::default().fg(Color::Yellow));
458+
let latency_paragraph = Paragraph::new(latency_text).style(ThemedStyles::latency_stats());
453459
f.render_widget(latency_paragraph, chunks[2]);
454460
}
455461

@@ -539,15 +545,19 @@ impl App {
539545
let block = Block::default()
540546
.title(title)
541547
.borders(Borders::ALL)
542-
.border_style(Style::default().fg(Color::Green));
548+
.border_style(ThemedStyles::download_graph_border());
543549

544550
let inner = block.inner(area);
545551
f.render_widget(block, area);
546552

547553
if !self.state.download_speeds.is_empty() {
548554
let graph_widget = crate::tui::widgets::LineGraph::new(&self.state.download_speeds)
549-
.color(Color::Green);
555+
.color(TokyoNight::DOWNLOAD_PRIMARY);
550556
f.render_widget(graph_widget, inner);
557+
} else {
558+
let placeholder =
559+
Paragraph::new("Waiting for data...").style(ThemedStyles::graph_placeholder());
560+
f.render_widget(placeholder, inner);
551561
}
552562
}
553563

@@ -556,15 +566,19 @@ impl App {
556566
let block = Block::default()
557567
.title(title)
558568
.borders(Borders::ALL)
559-
.border_style(Style::default().fg(Color::Blue));
569+
.border_style(ThemedStyles::upload_graph_border());
560570

561571
let inner = block.inner(area);
562572
f.render_widget(block, area);
563573

564574
if !self.state.upload_speeds.is_empty() {
565-
let graph_widget =
566-
crate::tui::widgets::LineGraph::new(&self.state.upload_speeds).color(Color::Blue);
575+
let graph_widget = crate::tui::widgets::LineGraph::new(&self.state.upload_speeds)
576+
.color(TokyoNight::UPLOAD_PRIMARY);
567577
f.render_widget(graph_widget, inner);
578+
} else {
579+
let placeholder =
580+
Paragraph::new("Waiting for data...").style(ThemedStyles::graph_placeholder());
581+
f.render_widget(placeholder, inner);
568582
}
569583
}
570584

@@ -574,45 +588,68 @@ impl App {
574588
}
575589

576590
fn draw_status(&self, f: &mut Frame, area: Rect) {
577-
let status_text = match self.state.progress.phase {
578-
TestPhase::Idle => "Ready to start tests. Press 'q' to quit.".to_string(),
579-
TestPhase::Latency => "Running latency tests...".to_string(),
591+
let (status_text, status_style) = match self.state.progress.phase {
592+
TestPhase::Idle => (
593+
" Ready to start tests. Press 'q' to quit.".to_string(),
594+
ThemedStyles::status_idle(),
595+
),
596+
TestPhase::Latency => (
597+
" Running latency tests...".to_string(),
598+
ThemedStyles::status_active(),
599+
),
580600
TestPhase::Download => {
581601
if let (Some(payload_size), Some(_)) = (
582602
self.state.progress.current_payload_size,
583603
self.state.progress.current_test,
584604
) {
585-
format!(
586-
"Testing Download {}MB [{}/{}]",
587-
payload_size / 1_000_000,
588-
self.state.progress.current_iteration,
589-
self.state.progress.total_iterations
605+
(
606+
format!(
607+
" Testing Download {}MB [{}/{}]",
608+
payload_size / 1_000_000,
609+
self.state.progress.current_iteration,
610+
self.state.progress.total_iterations
611+
),
612+
ThemedStyles::status_active(),
590613
)
591614
} else {
592-
"Testing Download...".to_string()
615+
(
616+
" Testing Download...".to_string(),
617+
ThemedStyles::status_active(),
618+
)
593619
}
594620
}
595621
TestPhase::Upload => {
596622
if let (Some(payload_size), Some(_)) = (
597623
self.state.progress.current_payload_size,
598624
self.state.progress.current_test,
599625
) {
600-
format!(
601-
"Testing Upload {}MB [{}/{}]",
602-
payload_size / 1_000_000,
603-
self.state.progress.current_iteration,
604-
self.state.progress.total_iterations
626+
(
627+
format!(
628+
" Testing Upload {}MB [{}/{}]",
629+
payload_size / 1_000_000,
630+
self.state.progress.current_iteration,
631+
self.state.progress.total_iterations
632+
),
633+
ThemedStyles::status_active(),
605634
)
606635
} else {
607-
"Testing Upload...".to_string()
636+
(
637+
" Testing Upload...".to_string(),
638+
ThemedStyles::status_active(),
639+
)
608640
}
609641
}
610-
TestPhase::Completed => "All tests completed! Press 'q' to quit.".to_string(),
642+
TestPhase::Completed => (
643+
" All tests completed! Press 'q' to quit.".to_string(),
644+
ThemedStyles::status_complete(),
645+
),
611646
};
612647

613-
let paragraph = Paragraph::new(status_text)
614-
.style(Style::default().fg(Color::White))
615-
.block(Block::default().borders(Borders::ALL));
648+
let paragraph = Paragraph::new(status_text).style(status_style).block(
649+
Block::default()
650+
.borders(Borders::ALL)
651+
.border_style(ThemedStyles::status_border()),
652+
);
616653
f.render_widget(paragraph, area);
617654
}
618655
}

0 commit comments

Comments
 (0)