From 41c4305e851526e223c048af3f007a228d802281 Mon Sep 17 00:00:00 2001 From: Colm Rafferty Date: Wed, 8 Jul 2026 08:53:27 -0700 Subject: [PATCH] feature: added configurable colors to config.toml --- Cargo.lock | 200 +++++++++++++++--- Cargo.toml | 2 +- Readme.md | 13 +- src/adapter.rs | 12 +- src/config.rs | 71 +++++++ src/device.rs | 10 +- src/mode/ap.rs | 33 +-- src/mode/station.rs | 26 ++- src/mode/station/auth/entreprise.rs | 24 ++- src/mode/station/auth/entreprise/eduroam.rs | 22 +- src/mode/station/auth/entreprise/peap.rs | 46 ++-- src/mode/station/auth/entreprise/pwd.rs | 16 +- .../entreprise/requests/key_passphrase.rs | 16 +- .../auth/entreprise/requests/password.rs | 13 +- .../requests/username_and_password.rs | 14 +- src/mode/station/auth/entreprise/tls.rs | 31 +-- src/mode/station/auth/entreprise/ttls.rs | 46 ++-- src/mode/station/auth/psk.rs | 15 +- src/mode/station/hidden_network.rs | 12 +- src/mode/station/share.rs | 14 +- src/notification.rs | 13 +- src/reset.rs | 15 +- src/ui.rs | 27 +-- 23 files changed, 486 insertions(+), 205 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f32e4e..8319116 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,7 +77,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -88,7 +88,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -148,9 +148,9 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix", + "rustix 1.1.4", "slab", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -179,7 +179,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix", + "rustix 1.1.4", ] [[package]] @@ -205,10 +205,10 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix", + "rustix 1.1.4", "signal-hook-registry", "slab", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -296,6 +296,9 @@ name = "bitflags" version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +dependencies = [ + "serde_core", +] [[package]] name = "block-buffer" @@ -471,6 +474,7 @@ dependencies = [ "itoa", "rustversion", "ryu", + "serde", "static_assertions", ] @@ -513,6 +517,23 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.11.1", + "crossterm_winapi", + "mio", + "parking_lot", + "rustix 0.38.44", + "serde", + "signal-hook", + "signal-hook-mio", + "winapi", +] + [[package]] name = "crossterm" version = "0.29.0" @@ -526,7 +547,8 @@ dependencies = [ "futures-core", "mio", "parking_lot", - "rustix", + "rustix 1.1.4", + "serde", "signal-hook", "signal-hook-mio", "winapi", @@ -660,7 +682,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -741,7 +763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -1100,7 +1122,7 @@ dependencies = [ "async-channel", "chrono", "clap", - "crossterm", + "crossterm 0.29.0", "dirs", "env_logger", "futures", @@ -1284,6 +1306,12 @@ dependencies = [ "bitflags 2.11.1", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -1375,7 +1403,7 @@ dependencies = [ "libc", "log", "wasi", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -1446,6 +1474,12 @@ dependencies = [ "libc", ] +[[package]] +name = "numtoa" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aa2c4e539b869820a2b82e1aef6ff40aa85e65decdd5185e83fb4b1249cd00f" + [[package]] name = "object" version = "0.37.3" @@ -1649,8 +1683,8 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix", - "windows-sys", + "rustix 1.1.4", + "windows-sys 0.61.2", ] [[package]] @@ -1763,8 +1797,10 @@ dependencies = [ "ratatui-core", "ratatui-crossterm", "ratatui-macros", + "ratatui-termion", "ratatui-termwiz", "ratatui-widgets", + "serde", ] [[package]] @@ -1780,6 +1816,7 @@ dependencies = [ "itertools", "kasuari", "lru", + "serde", "strum 0.27.2", "thiserror 2.0.18", "unicode-segmentation", @@ -1794,7 +1831,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "577c9b9f652b4c121fb25c6a391dd06406d3b092ba68827e6d2f09550edc54b3" dependencies = [ "cfg-if", - "crossterm", + "crossterm 0.28.1", + "crossterm 0.29.0", "instability", "ratatui-core", ] @@ -1809,6 +1847,17 @@ dependencies = [ "ratatui-widgets", ] +[[package]] +name = "ratatui-termion" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cade85a8591fbc911e147951422f0d6fd40f4948b271b6216c7dc01838996f8" +dependencies = [ + "instability", + "ratatui-core", + "termion", +] + [[package]] name = "ratatui-termwiz" version = "0.1.0" @@ -1832,6 +1881,7 @@ dependencies = [ "itertools", "line-clipping", "ratatui-core", + "serde", "strum 0.27.2", "time", "unicode-segmentation", @@ -1902,6 +1952,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.11.1", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + [[package]] name = "rustix" version = "1.1.4" @@ -1911,8 +1974,8 @@ dependencies = [ "bitflags 2.11.1", "errno", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.12.1", + "windows-sys 0.61.2", ] [[package]] @@ -2084,7 +2147,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -2172,8 +2235,8 @@ dependencies = [ "fastrand", "getrandom 0.4.2", "once_cell", - "rustix", - "windows-sys", + "rustix 1.1.4", + "windows-sys 0.61.2", ] [[package]] @@ -2188,6 +2251,17 @@ dependencies = [ "phf_codegen", ] +[[package]] +name = "termion" +version = "4.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f44138a9ae08f0f502f24104d82517ef4da7330c35acd638f1f29d3cd5475ecb" +dependencies = [ + "libc", + "numtoa", + "serde", +] + [[package]] name = "termios" version = "0.3.3" @@ -2222,6 +2296,7 @@ dependencies = [ "pest", "pest_derive", "phf", + "serde", "sha2", "signal-hook", "siphasher", @@ -2323,7 +2398,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -2447,7 +2522,7 @@ version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bd014a652e31cf25ea68d11b10a7b09549863449b19387505c9933f11eb05fa" dependencies = [ - "crossterm", + "crossterm 0.29.0", "unicode-segmentation", "unicode-width", ] @@ -2483,7 +2558,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ "memoffset", "tempfile", - "windows-sys", + "windows-sys 0.61.2", ] [[package]] @@ -2682,6 +2757,7 @@ checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7" dependencies = [ "getrandom 0.3.4", "mac_address", + "serde", "sha2", "thiserror 1.0.69", "uuid", @@ -2696,6 +2772,7 @@ dependencies = [ "csscolorparser", "deltae", "lazy_static", + "serde", "wezterm-dynamic", ] @@ -2817,6 +2894,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.61.2" @@ -2826,6 +2912,70 @@ dependencies = [ "windows-link", ] +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winnow" version = "1.0.3" @@ -2951,13 +3101,13 @@ dependencies = [ "hex", "libc", "ordered-stream", - "rustix", + "rustix 1.1.4", "serde", "serde_repr", "tracing", "uds_windows", "uuid", - "windows-sys", + "windows-sys 0.61.2", "winnow", "zbus_macros", "zbus_names", diff --git a/Cargo.toml b/Cargo.toml index c2406f6..c10d574 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ async-channel = "2" crossterm = { version = "0.29", default-features = false, features = [ "event-stream", ] } -ratatui = "0.30" +ratatui = { version = "0.30", features = ["serde"] } tui-input = { version = "0.15", features = [ "crossterm", ], default-features = false } diff --git a/Readme.md b/Readme.md index 6eaac5e..4b46fe3 100644 --- a/Readme.md +++ b/Readme.md @@ -68,9 +68,9 @@ This will produce an executable file at `target/release/impala` that you can cop $ impala ``` -## 🛠️Custom keybindings +## 🛠️Custom keybindings and themes -Keybindings can be customized in the config file `$HOME/.config/impala/config.toml` +Keybindings and themes can be customized in the config file `$HOME/.config/impala/config.toml` ```toml @@ -98,6 +98,15 @@ share = "p" [station.new_network] show_all = "a" connect_hidden = "" + +[theme] +background = "dark gray" +border = "green" +text_color = "white" +hidden_color = "dark gray" +info_color = "green" +warning_color = "yellow" +error_color = "red" ``` ## Contributing diff --git a/src/adapter.rs b/src/adapter.rs index f72521f..ea0684b 100644 --- a/src/adapter.rs +++ b/src/adapter.rs @@ -7,7 +7,7 @@ use iwdrs::{adapter::Adapter as iwdAdapter, session::Session}; use ratatui::{ Frame, layout::{Alignment, Constraint, Direction, Flex, Layout}, - style::{Color, Style}, + style::Style, widgets::{Block, BorderType, Borders, Cell, Clear, Padding, Row, Table}, }; @@ -54,7 +54,7 @@ impl Adapter { Ok(()) } - pub fn render(&self, frame: &mut Frame, device_addr: String) { + pub fn render(&self, frame: &mut Frame, device_addr: String, config: Arc) { let popup_layout = Layout::default() .direction(ratatui::layout::Direction::Vertical) .constraints([ @@ -113,11 +113,15 @@ impl Adapter { .title_alignment(Alignment::Center) .padding(Padding::uniform(1)) .borders(Borders::ALL) - .border_style(Style::default().fg(Color::Green)) + .border_style(Style::default().fg(config.theme.border)) .border_type(BorderType::Thick), ) .column_spacing(3) - .row_highlight_style(Style::default().bg(Color::DarkGray).fg(Color::White)); + .row_highlight_style( + Style::default() + .bg(config.theme.background) + .fg(config.theme.text_color), + ); frame.render_widget(Clear, area); frame.render_widget(device_infos_table, area); diff --git a/src/config.rs b/src/config.rs index 2748089..72a7237 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,4 @@ +use ratatui::style::Color; use toml; use dirs; @@ -22,6 +23,9 @@ pub struct Config { #[serde(default)] pub ap: AccessPoint, + + #[serde(default)] + pub theme: Theme, } fn default_switch_mode() -> char { @@ -150,6 +154,73 @@ fn default_ap_stop() -> char { 'x' } +// Theme +#[derive(Deserialize, Debug)] +pub struct Theme { + #[serde(default = "default_background")] + pub background: Color, + + #[serde(default = "default_border")] + pub border: Color, + + #[serde(default = "default_text_color")] + pub text_color: Color, + + #[serde(default = "default_hidden_color")] + pub hidden_color: Color, + + #[serde(default = "default_info_color")] + pub info_color: Color, + + #[serde(default = "default_warning_color")] + pub warning_color: Color, + + #[serde(default = "default_error_color")] + pub error_color: Color, +} + +fn default_background() -> Color { + Color::DarkGray +} + +fn default_border() -> Color { + Color::Green +} + +fn default_text_color() -> Color { + Color::White +} + +fn default_hidden_color() -> Color { + Color::DarkGray +} + +fn default_info_color() -> Color { + Color::Green +} + +fn default_warning_color() -> Color { + Color::Yellow +} + +fn default_error_color() -> Color { + Color::Red +} + +impl Default for Theme { + fn default() -> Self { + Self { + background: default_background(), + border: default_border(), + text_color: default_text_color(), + hidden_color: default_hidden_color(), + info_color: default_info_color(), + warning_color: default_warning_color(), + error_color: default_error_color(), + } + } +} + impl Config { pub fn new() -> Self { let conf_path = dirs::config_dir() diff --git a/src/device.rs b/src/device.rs index f390174..91f2922 100644 --- a/src/device.rs +++ b/src/device.rs @@ -7,7 +7,7 @@ use iwdrs::{device::Device as iwdDevice, modes::Mode, session::Session}; use ratatui::{ Frame, layout::{Constraint, Direction, Flex, Layout}, - style::{Color, Style, Stylize}, + style::{Style, Stylize}, text::{Line, Span}, widgets::{Block, BorderType, Borders, Padding, Row, Table, TableState}, }; @@ -147,13 +147,17 @@ impl Device { .title(" Device ") .title_style(Style::default().bold()) .borders(Borders::ALL) - .border_style(Style::default().fg(Color::Green)) + .border_style(Style::default().fg(config.theme.border)) .border_type(BorderType::Thick) .padding(Padding::horizontal(1)), ) .column_spacing(1) .flex(Flex::SpaceAround) - .row_highlight_style(Style::default().bg(Color::DarkGray).fg(Color::White)); + .row_highlight_style( + Style::default() + .bg(config.theme.background) + .fg(config.theme.text_color), + ); let mut device_state = TableState::default().with_selected(0); frame.render_stateful_widget(device_table, device_block, &mut device_state); diff --git a/src/mode/ap.rs b/src/mode/ap.rs index 8489ecf..e7e133e 100644 --- a/src/mode/ap.rs +++ b/src/mode/ap.rs @@ -7,7 +7,7 @@ use tokio::sync::mpsc::UnboundedSender; use ratatui::{ Frame, layout::{Alignment, Constraint, Direction, Flex, Layout}, - style::{Color, Style, Stylize}, + style::{Style, Stylize}, text::{Line, Span, Text}, widgets::{ Block, BorderType, Borders, Clear, List, Padding, Paragraph, Row, Table, TableState, @@ -96,7 +96,7 @@ impl AccessPoint { }) } - pub fn render_input(&self, frame: &mut Frame) { + pub fn render_input(&self, frame: &mut Frame, config: Arc) { let popup_layout = Layout::default() .direction(Direction::Vertical) .constraints( @@ -180,23 +180,23 @@ impl AccessPoint { let ssid_msg = Paragraph::new(ssid_text) .alignment(Alignment::Left) - .style(Style::default().fg(Color::White)) + .style(Style::default().fg(config.theme.text_color)) .block(Block::new().padding(Padding::left(2))); let ssid_input = Paragraph::new(self.ssid.value()) .alignment(Alignment::Center) - .style(Style::default().fg(Color::White)) - .block(Block::new().style(Style::default().bg(Color::DarkGray))); + .style(Style::default().fg(config.theme.text_color)) + .block(Block::new().style(Style::default().bg(config.theme.background))); let psk_msg = Paragraph::new(psk_text) .alignment(Alignment::Left) - .style(Style::default().fg(Color::White)) + .style(Style::default().fg(config.theme.text_color)) .block(Block::new().padding(Padding::left(2))); let psk_input = Paragraph::new(self.psk.value()) .alignment(Alignment::Center) - .style(Style::default().fg(Color::White)) - .block(Block::new().style(Style::default().bg(Color::DarkGray))); + .style(Style::default().fg(config.theme.text_color)) + .block(Block::new().style(Style::default().bg(config.theme.background))); frame.render_widget(Clear, area); @@ -204,8 +204,7 @@ impl AccessPoint { Block::new() .borders(Borders::ALL) .border_type(BorderType::Thick) - .style(Style::default().green()) - .border_style(Style::default().fg(Color::Green)), + .style(Style::default().fg(config.theme.border)), area, ); frame.render_widget(ssid_msg, ssid_msg_area); @@ -391,7 +390,7 @@ impl AccessPoint { .padding(Padding::horizontal(1)) .border_style({ if focused_block == FocusedBlock::Device { - Style::default().fg(Color::Green) + Style::default().fg(config.theme.border) } else { Style::default() } @@ -407,7 +406,9 @@ impl AccessPoint { .column_spacing(2) .flex(Flex::SpaceAround) .row_highlight_style(if focused_block == FocusedBlock::Device { - Style::default().bg(Color::DarkGray).fg(Color::White) + Style::default() + .bg(config.theme.background) + .fg(config.theme.text_color) } else { Style::default() }); @@ -495,7 +496,7 @@ impl AccessPoint { .borders(Borders::ALL) .border_style({ if focused_block == FocusedBlock::AccessPoint { - Style::default().fg(Color::Green) + Style::default().fg(config.theme.border) } else { Style::default() } @@ -512,7 +513,9 @@ impl AccessPoint { .column_spacing(2) .flex(Flex::SpaceAround) .row_highlight_style(if focused_block == FocusedBlock::AccessPoint { - Style::default().bg(Color::DarkGray).fg(Color::White) + Style::default() + .bg(config.theme.background) + .fg(config.theme.text_color) } else { Style::default() }); @@ -540,7 +543,7 @@ impl AccessPoint { .borders(Borders::ALL) .border_style({ if focused_block == FocusedBlock::AccessPointConnectedDevices { - Style::default().fg(Color::Green) + Style::default().fg(config.theme.border) } else { Style::default() } diff --git a/src/mode/station.rs b/src/mode/station.rs index 57c6413..59c2f81 100644 --- a/src/mode/station.rs +++ b/src/mode/station.rs @@ -17,7 +17,7 @@ use iwdrs::{ use ratatui::{ Frame, layout::{Constraint, Direction, Flex, Layout}, - style::{Color, Style, Stylize}, + style::{Style, Stylize}, text::{Line, Span}, widgets::{Block, BorderType, Borders, Padding, Paragraph, Row, Table, TableState}, }; @@ -457,7 +457,7 @@ impl Station { .borders(Borders::ALL) .border_style({ if focused_block == FocusedBlock::Device { - Style::default().fg(Color::Green) + Style::default().fg(config.theme.border) } else { Style::default() } @@ -474,7 +474,9 @@ impl Station { .column_spacing(1) .flex(Flex::SpaceAround) .row_highlight_style(if focused_block == FocusedBlock::Device { - Style::default().bg(Color::DarkGray).fg(Color::White) + Style::default() + .bg(config.theme.background) + .fg(config.theme.text_color) } else { Style::default() }); @@ -547,7 +549,7 @@ impl Station { Line::from(""), Line::from(""), ]) - .fg(Color::DarkGray); + .fg(config.theme.hidden_color); rows.push(row); }); @@ -600,7 +602,7 @@ impl Station { .borders(Borders::ALL) .border_style({ if focused_block == FocusedBlock::KnownNetworks { - Style::default().fg(Color::Green) + Style::default().fg(config.theme.border) } else { Style::default() } @@ -617,7 +619,9 @@ impl Station { .column_spacing(1) .flex(Flex::SpaceAround) .row_highlight_style(if focused_block == FocusedBlock::KnownNetworks { - Style::default().bg(Color::DarkGray).fg(Color::White) + Style::default() + .bg(config.theme.background) + .fg(config.theme.text_color) } else { Style::default() }); @@ -681,7 +685,7 @@ impl Station { }) .centered(), ]) - .dark_gray(), + .fg(config.theme.hidden_color), ) }) }; @@ -724,7 +728,7 @@ impl Station { .borders(Borders::ALL) .border_style({ if focused_block == FocusedBlock::NewNetworks { - Style::default().fg(Color::Green) + Style::default().fg(config.theme.border) } else { Style::default() } @@ -741,7 +745,9 @@ impl Station { .column_spacing(1) .flex(Flex::SpaceAround) .row_highlight_style(if focused_block == FocusedBlock::NewNetworks { - Style::default().bg(Color::DarkGray).fg(Color::White) + Style::default() + .bg(config.theme.background) + .fg(config.theme.text_color) } else { Style::default() }); @@ -947,7 +953,7 @@ impl Station { // Share if let Some(share) = &self.share { - share.render(frame); + share.render(frame, config.clone()); } } } diff --git a/src/mode/station/auth/entreprise.rs b/src/mode/station/auth/entreprise.rs index 3d6738d..e3c71ef 100644 --- a/src/mode/station/auth/entreprise.rs +++ b/src/mode/station/auth/entreprise.rs @@ -8,9 +8,10 @@ use ratatui::{ text::Text, widgets::{Block, Borders, Clear}, }; +use std::sync::Arc; use tui_input::Input; -use crate::event::Event; +use crate::{config::Config, event::Event}; pub mod eduroam; pub mod peap; @@ -448,7 +449,7 @@ impl WPAEntreprise { } } - pub fn render(&mut self, frame: &mut Frame) { + pub fn render(&mut self, frame: &mut Frame, config: Arc) { let layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -494,7 +495,7 @@ impl WPAEntreprise { Block::default() .borders(Borders::ALL) .border_type(ratatui::widgets::BorderType::Thick) - .border_style(Style::default().green()), + .border_style(Style::default().fg(config.theme.border)), block, ); @@ -512,7 +513,7 @@ impl WPAEntreprise { }; let choice = if self.focused_section == FocusedSection::EapChoice { - choice.bold().green() + choice.bold().fg(config.theme.border) } else { choice }; @@ -527,24 +528,27 @@ impl WPAEntreprise { match &mut self.eap { Eap::TLS(v) => { - v.render(frame, eap_block); + v.render(frame, eap_block, config.clone()); } Eap::PWD(v) => { - v.render(frame, eap_block); + v.render(frame, eap_block, config.clone()); } Eap::TTLS(v) => { - v.render(frame, eap_block); + v.render(frame, eap_block, config.clone()); } Eap::PEAP(v) => { - v.render(frame, eap_block); + v.render(frame, eap_block, config.clone()); } Eap::Eduroam(v) => { - v.render(frame, eap_block); + v.render(frame, eap_block, config.clone()); } } let text = if self.focused_section == FocusedSection::Apply { - Text::from("APPLY").centered().green().bold() + Text::from("APPLY") + .centered() + .fg(config.theme.border) + .bold() } else { Text::from("APPLY").centered() }; diff --git a/src/mode/station/auth/entreprise/eduroam.rs b/src/mode/station/auth/entreprise/eduroam.rs index dab09e0..082d9f8 100644 --- a/src/mode/station/auth/entreprise/eduroam.rs +++ b/src/mode/station/auth/entreprise/eduroam.rs @@ -1,18 +1,18 @@ use anyhow::{Result, anyhow}; -use std::{fs::OpenOptions, io::Write}; +use std::{fs::OpenOptions, io::Write, sync::Arc}; use crossterm::event::{KeyCode, KeyEvent}; use ratatui::{ Frame, layout::{Constraint, Direction, Layout, Rect}, - style::{Color, Stylize}, + style::Stylize, text::{Line, Span}, widgets::{HighlightSpacing, List, ListState}, }; use tui_input::{Input, backend::crossterm::EventHandler}; -use crate::mode::station::auth::entreprise::ERROR_PADDING; +use crate::{config::Config, mode::station::auth::entreprise::ERROR_PADDING}; fn pad_string(input: &str, length: usize) -> String { let current_length = input.chars().count(); @@ -166,7 +166,7 @@ AutoConnect=true", } } - pub fn render(&mut self, frame: &mut Frame, area: Rect) { + pub fn render(&mut self, frame: &mut Frame, area: Rect, config: Arc) { let layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -191,9 +191,9 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" Identity", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.identity.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.identity.field.value(), 50)).bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.identity.error { @@ -206,9 +206,10 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" Phase2 Identity", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.phase2_identity.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.phase2_identity.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.phase2_identity.error { @@ -221,9 +222,10 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" Phase2 Password", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.phase2_password.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.phase2_password.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.phase2_password.error { diff --git a/src/mode/station/auth/entreprise/peap.rs b/src/mode/station/auth/entreprise/peap.rs index f14ad6d..8429dc8 100644 --- a/src/mode/station/auth/entreprise/peap.rs +++ b/src/mode/station/auth/entreprise/peap.rs @@ -1,11 +1,11 @@ use anyhow::{Result, anyhow}; -use std::{fs::OpenOptions, io::Write, path::Path}; +use std::{fs::OpenOptions, io::Write, path::Path, sync::Arc}; use crossterm::event::{KeyCode, KeyEvent}; use ratatui::{ Frame, layout::{Margin, Rect}, - style::{Color, Stylize}, + style::Stylize, text::{Line, Span}, widgets::{HighlightSpacing, List, ListState}, }; @@ -13,6 +13,7 @@ use ratatui::{ use tui_input::backend::crossterm::EventHandler; use crate::{ + config::Config, iwd_network_name, mode::station::auth::entreprise::{ERROR_PADDING, UserInputField}, }; @@ -340,14 +341,14 @@ EAP-PEAP-Phase2-Password={} } } - pub fn render(&mut self, frame: &mut Frame, area: Rect) { + pub fn render(&mut self, frame: &mut Frame, area: Rect, config: Arc) { let items = [ Line::from(vec![ Span::from(pad_string(" Identity", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.identity.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.identity.field.value(), 50)).bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.identity.error { @@ -360,10 +361,10 @@ EAP-PEAP-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Server Domain Mask", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), Span::from(pad_string(self.server_domain_mask.field.value(), 50)) - .bg(Color::DarkGray), + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.server_domain_mask.error { @@ -376,9 +377,9 @@ EAP-PEAP-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" CA Cert", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.ca_cert.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.ca_cert.field.value(), 50)).bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.ca_cert.error { @@ -391,9 +392,10 @@ EAP-PEAP-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Client Cert", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.client_cert.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.client_cert.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.client_cert.error { @@ -406,9 +408,10 @@ EAP-PEAP-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Client Key", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.client_key.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.client_key.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.client_key.error { @@ -421,9 +424,10 @@ EAP-PEAP-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Key Passphrase", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.key_passphrase.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.key_passphrase.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.key_passphrase.error { @@ -436,7 +440,7 @@ EAP-PEAP-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Phase2 Method", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), Span::from(format!("< {} >", self.phase2_method)), ]), @@ -444,9 +448,10 @@ EAP-PEAP-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Phase2 Identity", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.phase2_identity.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.phase2_identity.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.phase2_identity.error { @@ -459,9 +464,10 @@ EAP-PEAP-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Phase2 Password", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.phase2_password.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.phase2_password.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.phase2_password.error { diff --git a/src/mode/station/auth/entreprise/pwd.rs b/src/mode/station/auth/entreprise/pwd.rs index dc0f1a9..327b964 100644 --- a/src/mode/station/auth/entreprise/pwd.rs +++ b/src/mode/station/auth/entreprise/pwd.rs @@ -1,18 +1,18 @@ use anyhow::{Result, anyhow}; -use std::{fs::OpenOptions, io::Write}; +use std::{fs::OpenOptions, io::Write, sync::Arc}; use crossterm::event::{KeyCode, KeyEvent}; use ratatui::{ Frame, layout::{Constraint, Direction, Layout, Rect}, - style::{Color, Stylize}, + style::Stylize, text::{Line, Span}, widgets::{HighlightSpacing, List, ListState}, }; use tui_input::{Input, backend::crossterm::EventHandler}; -use crate::{iwd_network_name, mode::station::auth::entreprise::ERROR_PADDING}; +use crate::{config::Config, iwd_network_name, mode::station::auth::entreprise::ERROR_PADDING}; fn pad_string(input: &str, length: usize) -> String { let current_length = input.chars().count(); @@ -147,7 +147,7 @@ AutoConnect=true", } } - pub fn render(&mut self, frame: &mut Frame, area: Rect) { + pub fn render(&mut self, frame: &mut Frame, area: Rect, config: Arc) { let layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -172,9 +172,9 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" Identity", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.identity.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.identity.field.value(), 50)).bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.identity.error { @@ -187,9 +187,9 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" Password", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.password.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.password.field.value(), 50)).bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.password.error { diff --git a/src/mode/station/auth/entreprise/requests/key_passphrase.rs b/src/mode/station/auth/entreprise/requests/key_passphrase.rs index fe79968..3eb6b78 100644 --- a/src/mode/station/auth/entreprise/requests/key_passphrase.rs +++ b/src/mode/station/auth/entreprise/requests/key_passphrase.rs @@ -1,10 +1,11 @@ -use crate::agent::AuthAgent; +use crate::{agent::AuthAgent, config::Config}; use anyhow::Result; +use std::sync::Arc; use ratatui::{ Frame, layout::{Alignment, Constraint, Direction, Layout}, - style::{Color, Style, Stylize}, + style::{Style, Stylize}, text::{Line, Span, Text}, widgets::{Block, BorderType, Borders, Clear, Padding, Paragraph}, }; @@ -43,7 +44,7 @@ impl RequestKeyPassphrase { self.passphrase.reset(); Ok(()) } - pub fn render(&self, frame: &mut Frame) { + pub fn render(&self, frame: &mut Frame, config: Arc) { let popup_layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -106,7 +107,7 @@ impl RequestKeyPassphrase { let text = Paragraph::new(text.centered()) .alignment(Alignment::Center) - .style(Style::default().fg(Color::White)) + .style(Style::default().fg(config.theme.text_color)) .block(Block::new().padding(Padding::uniform(1))); let passkey = Paragraph::new({ @@ -117,8 +118,8 @@ impl RequestKeyPassphrase { } }) .alignment(Alignment::Center) - .style(Style::default().fg(Color::White)) - .block(Block::new().style(Style::default().bg(Color::DarkGray))); + .style(Style::default().fg(config.theme.text_color)) + .block(Block::new().style(Style::default().bg(config.theme.background))); let show_password_icon = if self.show_password { Text::from(" ").centered() @@ -132,8 +133,7 @@ impl RequestKeyPassphrase { Block::new() .borders(Borders::ALL) .border_type(BorderType::Thick) - .style(Style::default().green()) - .border_style(Style::default().fg(Color::Green)), + .style(Style::default().fg(config.theme.border)), area, ); frame.render_widget(text, text_area); diff --git a/src/mode/station/auth/entreprise/requests/password.rs b/src/mode/station/auth/entreprise/requests/password.rs index 8a77347..84952cf 100644 --- a/src/mode/station/auth/entreprise/requests/password.rs +++ b/src/mode/station/auth/entreprise/requests/password.rs @@ -1,13 +1,14 @@ -use crate::agent::AuthAgent; +use crate::{agent::AuthAgent, config::Config}; use anyhow::Result; use ratatui::{ Frame, layout::{Constraint, Direction, Layout, Margin}, - style::{Color, Style, Stylize}, + style::{Style, Stylize}, text::{Line, Span, Text}, widgets::{Block, BorderType, Borders, Clear, List}, }; +use std::sync::Arc; use tui_input::Input; #[derive(Debug)] @@ -45,7 +46,7 @@ impl RequestPassword { self.password.reset(); Ok(()) } - pub fn render(&self, frame: &mut Frame) { + pub fn render(&self, frame: &mut Frame, config: Arc) { let popup_layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -96,7 +97,7 @@ impl RequestPassword { { if let Some(user_name) = &self.user_name { Line::from(vec![ - Span::raw(" Username ").bold().bg(Color::DarkGray), + Span::raw(" Username ").bold().bg(config.theme.background), Span::from(" "), Span::from(user_name), ]) @@ -106,7 +107,7 @@ impl RequestPassword { }, Line::from(""), Line::from(vec![ - Span::raw(" Password ").bold().bg(Color::DarkGray), + Span::raw(" Password ").bold().bg(config.theme.background), Span::from(" "), Span::from({ if self.show_password { @@ -132,7 +133,7 @@ impl RequestPassword { Block::new() .borders(Borders::ALL) .border_type(BorderType::Thick) - .border_style(Style::default().fg(Color::Green)), + .border_style(Style::default().fg(config.theme.border)), area, ); frame.render_widget( diff --git a/src/mode/station/auth/entreprise/requests/username_and_password.rs b/src/mode/station/auth/entreprise/requests/username_and_password.rs index 93769fa..b7a8e2b 100644 --- a/src/mode/station/auth/entreprise/requests/username_and_password.rs +++ b/src/mode/station/auth/entreprise/requests/username_and_password.rs @@ -1,6 +1,6 @@ -use crate::agent::AuthAgent; -use crate::event::Event; +use crate::{agent::AuthAgent, config::Config, event::Event}; use anyhow::Result; +use std::sync::Arc; use tokio::sync::mpsc::UnboundedSender; use crossterm::event::{KeyCode, KeyEvent}; @@ -8,7 +8,7 @@ use crossterm::event::{KeyCode, KeyEvent}; use ratatui::{ Frame, layout::{Constraint, Direction, Layout, Margin}, - style::{Color, Style, Stylize}, + style::{Style, Stylize}, text::{Line, Span, Text}, widgets::{Block, BorderType, Borders, Clear, List}, }; @@ -108,7 +108,7 @@ impl RequestUsernameAndPassword { self.password.reset(); Ok(()) } - pub fn render(&self, frame: &mut Frame) { + pub fn render(&self, frame: &mut Frame, config: Arc) { let popup_layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -157,13 +157,13 @@ impl RequestUsernameAndPassword { let items = vec![ Line::from(vec![ - Span::raw(" Username ").bold().bg(Color::DarkGray), + Span::raw(" Username ").bold().bg(config.theme.background), Span::from(" "), Span::from(self.username.value()), ]), Line::from(""), Line::from(vec![ - Span::raw(" Password ").bold().bg(Color::DarkGray), + Span::raw(" Password ").bold().bg(config.theme.background), Span::from(" "), Span::from({ if self.show_password { @@ -189,7 +189,7 @@ impl RequestUsernameAndPassword { Block::new() .borders(Borders::ALL) .border_type(BorderType::Thick) - .border_style(Style::default().fg(Color::Green)), + .border_style(Style::default().fg(config.theme.border)), area, ); frame.render_widget( diff --git a/src/mode/station/auth/entreprise/tls.rs b/src/mode/station/auth/entreprise/tls.rs index 0c658f0..3f345ae 100644 --- a/src/mode/station/auth/entreprise/tls.rs +++ b/src/mode/station/auth/entreprise/tls.rs @@ -1,18 +1,18 @@ use anyhow::{Result, anyhow}; -use std::{fs::OpenOptions, io::Write, path::Path}; +use std::{fs::OpenOptions, io::Write, path::Path, sync::Arc}; use crossterm::event::{KeyCode, KeyEvent}; use ratatui::{ Frame, layout::{Constraint, Direction, Layout, Rect}, - style::{Color, Stylize}, + style::Stylize, text::{Line, Span}, widgets::{HighlightSpacing, List, ListState}, }; use tui_input::{Input, backend::crossterm::EventHandler}; -use crate::{iwd_network_name, mode::station::auth::entreprise::ERROR_PADDING}; +use crate::{config::Config, iwd_network_name, mode::station::auth::entreprise::ERROR_PADDING}; fn pad_string(input: &str, length: usize) -> String { let current_length = input.chars().count(); @@ -242,7 +242,7 @@ AutoConnect=true", } } - pub fn render(&mut self, frame: &mut Frame, area: Rect) { + pub fn render(&mut self, frame: &mut Frame, area: Rect, config: Arc) { let layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -267,9 +267,9 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" CA Cert", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.ca_cert.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.ca_cert.field.value(), 50)).bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.ca_cert.error { @@ -282,9 +282,9 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" Identity", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.identity.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.identity.field.value(), 50)).bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.identity.error { @@ -297,9 +297,10 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" Client Cert", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.client_cert.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.client_cert.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.client_cert.error { @@ -312,9 +313,10 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" Client Key", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.client_key.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.client_key.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.client_key.error { @@ -327,9 +329,10 @@ AutoConnect=true", Line::from(vec![ Span::from(pad_string(" Key Passphrase", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.key_passphrase.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.key_passphrase.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.key_passphrase.error { diff --git a/src/mode/station/auth/entreprise/ttls.rs b/src/mode/station/auth/entreprise/ttls.rs index 01bb2e7..0681736 100644 --- a/src/mode/station/auth/entreprise/ttls.rs +++ b/src/mode/station/auth/entreprise/ttls.rs @@ -1,11 +1,11 @@ use anyhow::{Result, anyhow}; -use std::{fs::OpenOptions, io::Write, path::Path}; +use std::{fs::OpenOptions, io::Write, path::Path, sync::Arc}; use crossterm::event::{KeyCode, KeyEvent}; use ratatui::{ Frame, layout::{Margin, Rect}, - style::{Color, Stylize}, + style::Stylize, text::{Line, Span}, widgets::{HighlightSpacing, List, ListState}, }; @@ -13,6 +13,7 @@ use ratatui::{ use tui_input::backend::crossterm::EventHandler; use crate::{ + config::Config, iwd_network_name, mode::station::auth::entreprise::{ERROR_PADDING, UserInputField, pad_string}, }; @@ -352,14 +353,14 @@ EAP-TTLS-Phase2-Password={} } } - pub fn render(&mut self, frame: &mut Frame, area: Rect) { + pub fn render(&mut self, frame: &mut Frame, area: Rect, config: Arc) { let items = [ Line::from(vec![ Span::from(pad_string(" Identity", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.identity.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.identity.field.value(), 50)).bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.identity.error { @@ -372,10 +373,10 @@ EAP-TTLS-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Server Domain Mask", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), Span::from(pad_string(self.server_domain_mask.field.value(), 50)) - .bg(Color::DarkGray), + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.server_domain_mask.error { @@ -388,9 +389,9 @@ EAP-TTLS-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" CA Cert", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.ca_cert.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.ca_cert.field.value(), 50)).bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.ca_cert.error { @@ -403,9 +404,10 @@ EAP-TTLS-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Client Cert", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.client_cert.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.client_cert.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.client_cert.error { @@ -418,9 +420,10 @@ EAP-TTLS-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Client Key", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.client_key.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.client_key.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.client_key.error { @@ -433,9 +436,10 @@ EAP-TTLS-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Key Passphrase", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.key_passphrase.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.key_passphrase.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.key_passphrase.error { @@ -448,7 +452,7 @@ EAP-TTLS-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Phase2 Method", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), Span::from(format!("< {} >", self.phase2_method)), ]), @@ -456,9 +460,10 @@ EAP-TTLS-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Phase2 Identity", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.phase2_identity.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.phase2_identity.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.phase2_identity.error { @@ -471,9 +476,10 @@ EAP-TTLS-Phase2-Password={} Line::from(vec![ Span::from(pad_string(" Phase2 Password", 20)) .bold() - .bg(Color::DarkGray), + .bg(config.theme.background), Span::from(" "), - Span::from(pad_string(self.phase2_password.field.value(), 50)).bg(Color::DarkGray), + Span::from(pad_string(self.phase2_password.field.value(), 50)) + .bg(config.theme.background), ]), Line::from(vec![Span::from(ERROR_PADDING), { if let Some(error) = &self.phase2_password.error { diff --git a/src/mode/station/auth/psk.rs b/src/mode/station/auth/psk.rs index 20cfad8..f8a8e07 100644 --- a/src/mode/station/auth/psk.rs +++ b/src/mode/station/auth/psk.rs @@ -1,10 +1,12 @@ use crate::agent::AuthAgent; +use crate::config::Config; use anyhow::Result; +use std::sync::Arc; use ratatui::{ Frame, layout::{Alignment, Constraint, Direction, Layout}, - style::{Color, Style, Stylize}, + style::{Style, Stylize}, text::{Line, Span, Text}, widgets::{Block, BorderType, Borders, Clear, Padding, Paragraph}, }; @@ -44,7 +46,7 @@ impl Psk { self.passphrase.reset(); Ok(()) } - pub fn render(&self, frame: &mut Frame, network_name: Option) { + pub fn render(&self, frame: &mut Frame, network_name: Option, config: Arc) { let popup_layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -111,7 +113,7 @@ impl Psk { let text = Paragraph::new(text.centered()) .alignment(Alignment::Center) - .style(Style::default().fg(Color::White)) + .style(Style::default().fg(config.theme.text_color)) .block(Block::new().padding(Padding::uniform(1))); let passphrase_str = if self.show_password { @@ -124,8 +126,8 @@ impl Psk { let passkey = Paragraph::new(passphrase_str) .alignment(Alignment::Center) - .style(Style::default().fg(Color::White)) - .block(Block::new().style(Style::default().bg(Color::DarkGray))); + .style(Style::default().fg(config.theme.text_color)) + .block(Block::new().style(Style::default().bg(config.theme.background))); let show_password_icon = if self.show_password { Text::from("󰈈 ").centered() @@ -139,8 +141,7 @@ impl Psk { Block::new() .borders(Borders::ALL) .border_type(BorderType::Thick) - .style(Style::default().green()) - .border_style(Style::default().fg(Color::Green)), + .style(Style::default().fg(config.theme.border)), area, ); frame.render_widget(text, text_area); diff --git a/src/mode/station/hidden_network.rs b/src/mode/station/hidden_network.rs index a9a9716..7c6fe7b 100644 --- a/src/mode/station/hidden_network.rs +++ b/src/mode/station/hidden_network.rs @@ -1,4 +1,6 @@ +use crate::config::Config; use crate::event::Event; +use std::sync::Arc; use crossterm::event::{KeyCode, KeyEvent}; use tokio::sync::mpsc::UnboundedSender; @@ -6,7 +8,7 @@ use tokio::sync::mpsc::UnboundedSender; use ratatui::{ Frame, layout::{Constraint, Direction, Layout, Margin}, - style::{Color, Style, Stylize}, + style::{Style, Stylize}, text::Text, widgets::{Block, BorderType, Borders, Clear}, }; @@ -66,7 +68,7 @@ impl ConnectHiddenNetwork { } } - pub fn render(&self, frame: &mut Frame) { + pub fn render(&self, frame: &mut Frame, config: Arc) { let popup_layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -106,7 +108,9 @@ impl ConnectHiddenNetwork { let message = Text::from("Enter the SSID of the hidden network").centered(); - let ssid = Text::from(self.ssid.value()).bg(Color::DarkGray).centered(); + let ssid = Text::from(self.ssid.value()) + .bg(config.theme.background) + .centered(); let error = Text::from(self.ssid.error.clone().unwrap_or_default()) .red() .centered(); @@ -117,7 +121,7 @@ impl ConnectHiddenNetwork { Block::new() .borders(Borders::ALL) .border_type(BorderType::Thick) - .border_style(Style::default().fg(Color::Green)), + .border_style(Style::default().fg(config.theme.border)), area, ); frame.render_widget( diff --git a/src/mode/station/share.rs b/src/mode/station/share.rs index 54e22a2..0a75e01 100644 --- a/src/mode/station/share.rs +++ b/src/mode/station/share.rs @@ -1,17 +1,17 @@ use anyhow::Result; use qrcode::QrCode; -use std::{cmp, fs}; +use std::{cmp, fs, sync::Arc}; use tui_qrcode::{Colors, QrCodeWidget}; use ratatui::{ Frame, layout::{Constraint, Direction, Flex, Layout, Rect}, - style::{Color, Style, Stylize}, + style::{Style, Stylize}, text::{Line, Span, Text}, widgets::{Block, BorderType, Borders, Clear}, }; -use crate::iwd_network_name; +use crate::{config::Config, iwd_network_name}; #[derive(Clone)] pub struct Share { @@ -56,7 +56,7 @@ impl Share { } } - pub fn render(&self, frame: &mut Frame) { + pub fn render(&self, frame: &mut Frame, config: Arc) { let widget = QrCodeWidget::new(self.qr_code.clone()).colors(Colors::Inverted); let sim_area = Rect::new(0, 0, 50, 50); let size = widget.size(sim_area); @@ -103,7 +103,7 @@ impl Share { Block::new() .borders(Borders::all()) .border_type(BorderType::Thick) - .border_style(Style::new().green()), + .border_style(Style::new().fg(config.theme.border)), block, ); frame.render_widget( @@ -129,7 +129,9 @@ impl Share { Line::from(""), Line::from(vec![ Span::from("Passphrase: "), - Span::from(&self.passphrase).bold().bg(Color::DarkGray), + Span::from(&self.passphrase) + .bold() + .bg(config.theme.background), ]) .centered(), ]); diff --git a/src/notification.rs b/src/notification.rs index 878efa5..c4d55f1 100644 --- a/src/notification.rs +++ b/src/notification.rs @@ -2,13 +2,14 @@ use anyhow::Result; use ratatui::{ Frame, layout::{Alignment, Constraint, Direction, Layout, Rect}, - style::{Color, Modifier, Style}, + style::{Modifier, Style}, text::{Line, Text}, widgets::{Block, BorderType, Borders, Clear, Paragraph, Wrap}, }; +use std::sync::Arc; use tokio::sync::mpsc::UnboundedSender; -use crate::event::Event; +use crate::{config::Config, event::Event}; #[derive(Debug, Clone)] pub struct Notification { @@ -25,11 +26,11 @@ pub enum NotificationLevel { } impl Notification { - pub fn render(&self, index: usize, frame: &mut Frame) { + pub fn render(&self, index: usize, frame: &mut Frame, config: Arc) { let (color, title) = match self.level { - NotificationLevel::Info => (Color::Green, "Info"), - NotificationLevel::Warning => (Color::Yellow, "Warning"), - NotificationLevel::Error => (Color::Red, "Error"), + NotificationLevel::Info => (config.theme.info_color, "Info"), + NotificationLevel::Warning => (config.theme.warning_color, "Warning"), + NotificationLevel::Error => (config.theme.error_color, "Error"), }; let mut text = Text::from(vec![ diff --git a/src/reset.rs b/src/reset.rs index 4b49530..7dbd442 100644 --- a/src/reset.rs +++ b/src/reset.rs @@ -1,11 +1,13 @@ +use crate::config::Config; use iwdrs::modes::Mode; use ratatui::{ Frame, layout::{Alignment, Constraint, Direction, Layout}, - style::{Color, Style}, + style::Style, text::Text, widgets::{Block, BorderType, Borders, Clear, Padding, Paragraph}, }; +use std::sync::Arc; #[derive(Debug)] pub struct Reset { @@ -23,7 +25,7 @@ impl Reset { } } - pub fn render(&self, frame: &mut Frame) { + pub fn render(&self, frame: &mut Frame, config: Arc) { let popup_layout = Layout::default() .direction(Direction::Vertical) .constraints([ @@ -118,15 +120,15 @@ impl Reset { let message = Paragraph::new("Select the desired mode:") .alignment(Alignment::Center) - .style(Style::default().fg(Color::White)) + .style(Style::default().fg(config.theme.text_color)) .block(Block::new().padding(Padding::uniform(1))); let station_choice = Paragraph::new(station_text) - .style(Style::default().fg(Color::White)) + .style(Style::default().fg(config.theme.text_color)) .block(Block::new().padding(Padding::horizontal(10))); let ap_choice = Paragraph::new(ap_text) - .style(Style::default().fg(Color::White)) + .style(Style::default().fg(config.theme.text_color)) .block(Block::new().padding(Padding::horizontal(10))); let help = Paragraph::new( @@ -143,8 +145,7 @@ impl Reset { Block::new() .borders(Borders::ALL) .border_type(BorderType::Rounded) - .style(Style::default().green()) - .border_style(Style::default().fg(Color::Green)), + .style(Style::default().fg(config.theme.border)), area, ); frame.render_widget(message, message_area); diff --git a/src/ui.rs b/src/ui.rs index a12644e..b64b26b 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -7,7 +7,7 @@ use crate::app::{App, FocusedBlock}; pub fn render(app: &mut App, frame: &mut Frame) { if app.reset.enable { - app.reset.render(frame); + app.reset.render(frame, app.config.clone()); } else { if !app.device.is_powered { app.device @@ -24,7 +24,7 @@ pub fn render(app: &mut App, frame: &mut Frame) { if let Some(ap) = &mut app.device.ap { ap.render(frame, app.focused_block, &device, app.config.clone()); if app.focused_block == FocusedBlock::AccessPointInput { - ap.render_input(frame); + ap.render_input(frame, app.config.clone()); } } } @@ -34,19 +34,22 @@ pub fn render(app: &mut App, frame: &mut Frame) { if app.focused_block == FocusedBlock::WpaEntrepriseAuth && let Some(eap) = &mut app.auth.eap { - eap.render(frame); + eap.render(frame, app.config.clone()); } if app.focused_block == FocusedBlock::AdapterInfos { - app.adapter.render(frame, app.device.address.clone()); + app.adapter + .render(frame, app.device.address.clone(), app.config.clone()); } if app.agent.psk_required.load(Ordering::Relaxed) { app.focused_block = FocusedBlock::PskAuthKey; - app.auth - .psk - .render(frame, app.network_name_requiring_auth.clone()); + app.auth.psk.render( + frame, + app.network_name_requiring_auth.clone(), + app.config.clone(), + ); } if app @@ -55,13 +58,13 @@ pub fn render(app: &mut App, frame: &mut Frame) { .load(Ordering::Relaxed) && let Some(req) = &app.auth.request_key_passphrase { - req.render(frame); + req.render(frame, app.config.clone()); } if app.agent.password_required.load(Ordering::Relaxed) && let Some(req) = &app.auth.request_password { - req.render(frame); + req.render(frame, app.config.clone()); } if app @@ -70,18 +73,18 @@ pub fn render(app: &mut App, frame: &mut Frame) { .load(Ordering::Relaxed) && let Some(req) = &app.auth.request_username_and_password { - req.render(frame); + req.render(frame, app.config.clone()); } if let Some(station) = &app.device.station && let Some(conn) = &station.connct_hidden_network { - conn.render(frame); + conn.render(frame, app.config.clone()); } // Notifications for (index, notification) in app.notifications.iter().enumerate() { - notification.render(index, frame); + notification.render(index, frame, app.config.clone()); } } }