aboutsummaryrefslogtreecommitdiff
path: root/src/tui.rs
diff options
context:
space:
mode:
authorUMTS at Teleco <crt@teleco.ch>2026-03-08 22:11:52 +0100
committerUMTS at Teleco <crt@teleco.ch>2026-03-08 22:11:52 +0100
commit17c6bd803dbbecb8975b1b98532d25a807a7b3fb (patch)
treebc0e339ca514414261ce211ab0f74101e6d8aefa /src/tui.rs
parentee17cec85d3d9ef2abc0d7a50c980d82b429b59d (diff)
docs and font fix
Diffstat (limited to 'src/tui.rs')
-rw-r--r--src/tui.rs534
1 files changed, 404 insertions, 130 deletions
diff --git a/src/tui.rs b/src/tui.rs
index f6d9238..6c068dc 100644
--- a/src/tui.rs
+++ b/src/tui.rs
@@ -1,5 +1,8 @@
use crossterm::{
- event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind, KeyModifiers, MouseButton, MouseEvent, MouseEventKind},
+ event::{
+ self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind, KeyModifiers,
+ MouseButton, MouseEvent, MouseEventKind,
+ },
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
@@ -19,12 +22,14 @@ use crate::cli::Args;
use crate::config::Config;
use crate::config::FavoriteEntry;
use crate::lookup;
-use crate::tlds::{apply_top_tlds, get_tlds_or_default, list_names, default_list_name};
+use crate::tlds::{apply_top_tlds, default_list_name, get_tlds_or_default, list_names};
use crate::types::{DomainResult, DomainStatus, ErrorKind};
// note : this will be the worst shitshow of code you will probably have looked at in youre entire life
-// it works and is somewhat stable but i didnt feel like sorting it into nice modules and all.
-// have fun
+// it works and is somewhat stable but i didnt feel like sorting it into nice modules and all mostly just relying
+// on copy pasting shit where i need it
+//
+// have fun and may you forgive me for this extremly large ahh file.
// names and labels
const APP_NAME: &str = "hoardom";
@@ -36,7 +41,6 @@ const SEARCH_BUTTON_LABEL: &str = "[Search]";
const STOP_BUTTON_LABEL: &str = "[Stop](s)";
const CLEAR_BUTTON_LABEL: &str = "[Clear](C)";
-
// Layout tuning constants
const TOPBAR_HEIGHT: u16 = 1;
const SEARCH_PANEL_HEIGHT: u16 = 3;
@@ -88,8 +92,7 @@ fn export_favorites_txt(path: &Path, favorites: &[FavoriteEntry]) -> Result<(),
.map_err(|e| format!("Failed to create export directory: {}", e))?;
}
let text: Vec<&str> = favorites.iter().map(|f| f.domain.as_str()).collect();
- std::fs::write(path, text.join("\n"))
- .map_err(|e| format!("Failed to export favorites: {}", e))
+ std::fs::write(path, text.join("\n")).map_err(|e| format!("Failed to export favorites: {}", e))
}
fn export_results_csv(path: &Path, results: &[&DomainResult]) -> Result<(), String> {
@@ -108,8 +111,7 @@ fn export_results_csv(path: &Path, results: &[&DomainResult]) -> Result<(), Stri
));
}
- std::fs::write(path, lines.join("\n"))
- .map_err(|e| format!("Failed to export results: {}", e))
+ std::fs::write(path, lines.join("\n")).map_err(|e| format!("Failed to export results: {}", e))
}
#[derive(Debug, Clone, PartialEq)]
@@ -125,7 +127,6 @@ enum ExportMode {
}
impl ExportMode {
-
fn default_file_name(self) -> &'static str {
match self {
ExportMode::FavoritesTxt => "hoardom-favorites.txt",
@@ -229,7 +230,16 @@ struct PanelRects {
}
impl App {
- fn new(args: &Args, config: &Config, config_path: PathBuf, can_save: bool, cache_path: Option<PathBuf>, force_refresh: bool, whois_overrides: crate::tlds::WhoisOverrides, noretry: Vec<ErrorKind>) -> Self {
+ fn new(
+ args: &Args,
+ config: &Config,
+ config_path: PathBuf,
+ can_save: bool,
+ cache_path: Option<PathBuf>,
+ force_refresh: bool,
+ whois_overrides: crate::tlds::WhoisOverrides,
+ noretry: Vec<ErrorKind>,
+ ) -> Self {
let tld_list_name = args
.tld_list
.as_ref()
@@ -271,7 +281,11 @@ impl App {
verbose: args.verbose,
delay: args.effective_delay(),
retries: args.effective_retry(),
- jobs: if args.jobs.is_some() { args.effective_jobs() } else { config.settings.jobs.max(1) },
+ jobs: if args.jobs.is_some() {
+ args.effective_jobs()
+ } else {
+ config.settings.jobs.max(1)
+ },
panel_rects: PanelRects::default(),
stream_rx: None,
stream_task: None,
@@ -421,7 +435,11 @@ impl App {
last_res_export_path: self.last_res_export_path.clone(),
top_tlds: self.top_tlds.clone().unwrap_or_default(),
jobs: self.jobs,
- noretry: self.noretry.iter().map(|k| k.to_config_str().to_string()).collect(),
+ noretry: self
+ .noretry
+ .iter()
+ .map(|k| k.to_config_str().to_string())
+ .collect(),
backups: self.backups_enabled,
backup_count: self.backup_count,
},
@@ -437,7 +455,9 @@ impl App {
let d = domain.to_lowercase();
if !self.favorites.iter().any(|f| f.domain == d) {
// check if we just looked this domain up - inherit its status
- let status = self.results.iter()
+ let status = self
+ .results
+ .iter()
.find(|(_, r)| r.full.to_lowercase() == d)
.map(|(_, r)| r.status_str().to_string())
.unwrap_or_else(|| "unknown".to_string());
@@ -477,7 +497,11 @@ impl App {
if self.show_unavailable {
self.results.iter().map(|(_, r)| r).collect()
} else {
- self.results.iter().filter(|(_, r)| r.is_available()).map(|(_, r)| r).collect()
+ self.results
+ .iter()
+ .filter(|(_, r)| r.is_available())
+ .map(|(_, r)| r)
+ .collect()
}
}
@@ -598,7 +622,16 @@ pub async fn run_tui(
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
- let mut app = App::new(args, config, paths.config_file.clone(), paths.can_save, cache_file, force_refresh, whois_overrides, noretry);
+ let mut app = App::new(
+ args,
+ config,
+ paths.config_file.clone(),
+ paths.can_save,
+ cache_file,
+ force_refresh,
+ whois_overrides,
+ noretry,
+ );
if !paths.can_save {
app.status_msg = Some("Warning: favorites and settings wont be saved".to_string());
@@ -608,10 +641,7 @@ pub async fn run_tui(
// put the terminal back to normal
if !args.no_mouse {
- execute!(
- terminal.backend_mut(),
- DisableMouseCapture
- )?;
+ execute!(terminal.backend_mut(), DisableMouseCapture)?;
while event::poll(std::time::Duration::from_millis(0))? {
let _ = event::read();
@@ -638,7 +668,10 @@ async fn run_app(
}
if let Some(popup) = app.export_popup.as_ref() {
- if popup.close_at.is_some_and(|deadline| Instant::now() >= deadline) {
+ if popup
+ .close_at
+ .is_some_and(|deadline| Instant::now() >= deadline)
+ {
app.export_popup = None;
}
}
@@ -693,7 +726,9 @@ async fn run_app(
Ok(lookup::StreamMsg::Result { result, .. }) => {
// Update the matching favorite's status
let domain_lower = result.full.to_lowercase();
- if let Some(fav) = app.favorites.iter_mut().find(|f| f.domain == domain_lower) {
+ if let Some(fav) =
+ app.favorites.iter_mut().find(|f| f.domain == domain_lower)
+ {
let new_status = result.status_str().to_string();
if fav.status != new_status && fav.status != "unknown" {
fav.changed = true;
@@ -786,7 +821,11 @@ async fn run_app(
app.dropdown = DropdownState::Closed;
app.set_focus(match app.focus {
Focus::Search => {
- if app.show_notes_panel { Focus::Scratchpad } else { Focus::Results }
+ if app.show_notes_panel {
+ Focus::Scratchpad
+ } else {
+ Focus::Results
+ }
}
Focus::Scratchpad => Focus::Results,
Focus::Results => Focus::Favorites,
@@ -800,7 +839,11 @@ async fn run_app(
Focus::Search => Focus::Settings,
Focus::Scratchpad => Focus::Search,
Focus::Results => {
- if app.show_notes_panel { Focus::Scratchpad } else { Focus::Search }
+ if app.show_notes_panel {
+ Focus::Scratchpad
+ } else {
+ Focus::Search
+ }
}
Focus::Favorites => Focus::Results,
Focus::Settings => Focus::Favorites,
@@ -901,7 +944,11 @@ fn handle_export_popup_key(app: &mut App, key: KeyCode) {
popup.selected_row = (popup.selected_row + 1) % 4;
}
KeyCode::BackTab | KeyCode::Up => {
- popup.selected_row = if popup.selected_row == 0 { 3 } else { popup.selected_row - 1 };
+ popup.selected_row = if popup.selected_row == 0 {
+ 3
+ } else {
+ popup.selected_row - 1
+ };
}
KeyCode::Left => {
if popup.selected_row == 0 {
@@ -1057,7 +1104,9 @@ async fn handle_search_key(app: &mut App, key: KeyCode) {
}
}
KeyCode::Delete => {
- if app.cursor_pos < app.search_input.len() && app.search_input.is_char_boundary(app.cursor_pos) {
+ if app.cursor_pos < app.search_input.len()
+ && app.search_input.is_char_boundary(app.cursor_pos)
+ {
app.search_input.remove(app.cursor_pos);
}
}
@@ -1100,7 +1149,11 @@ fn handle_results_key(app: &mut App, key: KeyCode) {
KeyCode::Up => {
let i = match app.results_state.selected() {
Some(i) => {
- if i > 0 { i - 1 } else { 0 }
+ if i > 0 {
+ i - 1
+ } else {
+ 0
+ }
}
None => 0,
};
@@ -1109,7 +1162,11 @@ fn handle_results_key(app: &mut App, key: KeyCode) {
KeyCode::Down => {
let i = match app.results_state.selected() {
Some(i) => {
- if i + 1 < len { i + 1 } else { i }
+ if i + 1 < len {
+ i + 1
+ } else {
+ i
+ }
}
None => 0,
};
@@ -1139,7 +1196,11 @@ fn handle_favorites_key(app: &mut App, key: KeyCode) {
KeyCode::Up => {
let i = match app.favorites_state.selected() {
Some(i) => {
- if i > 0 { i - 1 } else { 0 }
+ if i > 0 {
+ i - 1
+ } else {
+ 0
+ }
}
None => 0,
};
@@ -1148,7 +1209,11 @@ fn handle_favorites_key(app: &mut App, key: KeyCode) {
KeyCode::Down => {
let i = match app.favorites_state.selected() {
Some(i) => {
- if i + 1 < len { i + 1 } else { i }
+ if i + 1 < len {
+ i + 1
+ } else {
+ i
+ }
}
None => 0,
};
@@ -1257,26 +1322,24 @@ fn handle_settings_key(app: &mut App, key: KeyCode) {
_ => {}
}
}
- KeyCode::Char(' ') => {
- match app.settings_selected.unwrap_or(0) {
- 1 => {
- app.show_unavailable = !app.show_unavailable;
- app.save_config();
- }
- 2 => {
- app.show_notes_panel = !app.show_notes_panel;
- if !app.show_notes_panel && app.focus == Focus::Scratchpad {
- app.set_focus(Focus::Results);
- }
- app.save_config();
- }
- 3 => {
- app.clear_on_search = !app.clear_on_search;
- app.save_config();
+ KeyCode::Char(' ') => match app.settings_selected.unwrap_or(0) {
+ 1 => {
+ app.show_unavailable = !app.show_unavailable;
+ app.save_config();
+ }
+ 2 => {
+ app.show_notes_panel = !app.show_notes_panel;
+ if !app.show_notes_panel && app.focus == Focus::Scratchpad {
+ app.set_focus(Focus::Results);
}
- _ => {}
+ app.save_config();
}
- }
+ 3 => {
+ app.clear_on_search = !app.clear_on_search;
+ app.save_config();
+ }
+ _ => {}
+ },
KeyCode::Char('+') | KeyCode::Char('=') => {
if app.settings_selected == Some(4) {
app.jobs = if app.jobs >= 99 { 99 } else { app.jobs + 1 };
@@ -1502,7 +1565,11 @@ fn handle_mouse(app: &mut App, mouse: MouseEvent) {
app.set_focus(Focus::Results);
let visible_len = app.visible_results().len();
let content_start = results_rect.y + 1;
- let progress_offset = if app.searching && app.search_progress.1 > 0 { 1 } else { 0 };
+ let progress_offset = if app.searching && app.search_progress.1 > 0 {
+ 1
+ } else {
+ 0
+ };
let header_offset = if visible_len > 0 { 1 } else { 0 };
let list_start = content_start + progress_offset + header_offset;
@@ -1653,14 +1720,18 @@ fn start_fav_check(app: &mut App) {
app.checking_favorites = true;
// Build a batch: each favorite is "name.tld" -> lookup (name, [tld])
- let batches: lookup::LookupBatch = app.favorites.iter().filter_map(|fav| {
- let parts: Vec<&str> = fav.domain.splitn(2, '.').collect();
- if parts.len() == 2 {
- Some((parts[0].to_string(), vec![parts[1].to_string()]))
- } else {
- None
- }
- }).collect();
+ let batches: lookup::LookupBatch = app
+ .favorites
+ .iter()
+ .filter_map(|fav| {
+ let parts: Vec<&str> = fav.domain.splitn(2, '.').collect();
+ if parts.len() == 2 {
+ Some((parts[0].to_string(), vec![parts[1].to_string()]))
+ } else {
+ None
+ }
+ })
+ .collect();
if batches.is_empty() {
app.checking_favorites = false;
@@ -1793,7 +1864,10 @@ fn draw_ui(f: &mut Frame, app: &mut App) {
.split(size);
let content_area = main_chunks[1];
- let desired_sidebar = content_area.width.saturating_mul(SIDEBAR_TARGET_WIDTH_PERCENT) / 100;
+ let desired_sidebar = content_area
+ .width
+ .saturating_mul(SIDEBAR_TARGET_WIDTH_PERCENT)
+ / 100;
let mut sidebar_width = clamp_panel_size(desired_sidebar, SIDEBAR_MIN_WIDTH, SIDEBAR_MAX_WIDTH)
.min(content_area.width.saturating_sub(RESULTS_MIN_WIDTH));
if sidebar_width == 0 {
@@ -1809,7 +1883,10 @@ fn draw_ui(f: &mut Frame, app: &mut App) {
let (scratchpad_chunk, results_chunk) = if app.show_notes_panel {
let center_width = content_area.width.saturating_sub(sidebar_width);
- let desired_scratchpad = content_area.width.saturating_mul(SCRATCHPAD_TARGET_WIDTH_PERCENT) / 100;
+ let desired_scratchpad = content_area
+ .width
+ .saturating_mul(SCRATCHPAD_TARGET_WIDTH_PERCENT)
+ / 100;
let mut scratchpad_width = clamp_panel_size(
desired_scratchpad,
SCRATCHPAD_MIN_WIDTH,
@@ -1941,11 +2018,15 @@ fn draw_terminal_too_small(f: &mut Frame, area: Rect) {
let text = vec![
Line::from(Span::styled(
fit_cell_center("HELP ! HELP ! HELP !", content_width),
- Style::default().fg(Color::White).add_modifier(Modifier::BOLD),
+ Style::default()
+ .fg(Color::White)
+ .add_modifier(Modifier::BOLD),
)),
Line::from(Span::styled(
fit_cell_center("I AM BEING CRUSHED!", content_width),
- Style::default().fg(Color::White).add_modifier(Modifier::BOLD),
+ Style::default()
+ .fg(Color::White)
+ .add_modifier(Modifier::BOLD),
)),
Line::from(fit_cell_center("", content_width)),
Line::from(Span::styled(
@@ -1953,21 +2034,31 @@ fn draw_terminal_too_small(f: &mut Frame, area: Rect) {
Style::default().fg(Color::White),
)),
Line::from(Span::styled(
- fit_cell_center(&format!("Need {}x{} of space", MIN_UI_WIDTH, MIN_UI_HEIGHT), content_width),
+ fit_cell_center(
+ &format!("Need {}x{} of space", MIN_UI_WIDTH, MIN_UI_HEIGHT),
+ content_width,
+ ),
Style::default().fg(Color::White),
)),
Line::from(Span::styled(
- fit_cell_center(&format!("Current: {}x{}", area.width, area.height), content_width),
+ fit_cell_center(
+ &format!("Current: {}x{}", area.width, area.height),
+ content_width,
+ ),
Style::default().fg(Color::DarkGray),
)),
Line::from(fit_cell_center("", content_width)),
Line::from(Span::styled(
fit_cell_center("REFUSING TO WORK TILL YOU", content_width),
- Style::default().fg(Color::White).add_modifier(Modifier::BOLD),
+ Style::default()
+ .fg(Color::White)
+ .add_modifier(Modifier::BOLD),
)),
Line::from(Span::styled(
fit_cell_center("GIVE ME BACK MY SPACE! >:(", content_width),
- Style::default().fg(Color::White).add_modifier(Modifier::BOLD),
+ Style::default()
+ .fg(Color::White)
+ .add_modifier(Modifier::BOLD),
)),
];
@@ -1981,14 +2072,49 @@ fn draw_topbar(f: &mut Frame, area: Rect) {
let right = format!("{} {}", EXPORT_BUTTON_LABEL, HELP_BUTTON_LABEL);
let gap = width.saturating_sub(left.chars().count() + right.chars().count());
let paragraph = Paragraph::new(Line::from(vec![
- Span::styled(CLOSE_BUTTON_LABEL, Style::default().fg(Color::Red).bg(Color::Gray).add_modifier(Modifier::BOLD)),
- Span::styled(format!(" {}", title), Style::default().fg(Color::White).bg(Color::Red).add_modifier(Modifier::BOLD)),
- Span::styled(" ".repeat(gap), Style::default().bg(Color::Red).add_modifier(Modifier::BOLD)),
- Span::styled(EXPORT_BUTTON_LABEL, Style::default().fg(Color::LightGreen).bg(Color::Red).add_modifier(Modifier::BOLD)),
- Span::styled(" ", Style::default().bg(Color::Red).add_modifier(Modifier::BOLD)),
- Span::styled(HELP_BUTTON_LABEL, Style::default().fg(Color::LightGreen).bg(Color::Red).add_modifier(Modifier::BOLD)),
+ Span::styled(
+ CLOSE_BUTTON_LABEL,
+ Style::default()
+ .fg(Color::Red)
+ .bg(Color::Gray)
+ .add_modifier(Modifier::BOLD),
+ ),
+ Span::styled(
+ format!(" {}", title),
+ Style::default()
+ .fg(Color::White)
+ .bg(Color::Red)
+ .add_modifier(Modifier::BOLD),
+ ),
+ Span::styled(
+ " ".repeat(gap),
+ Style::default().bg(Color::Red).add_modifier(Modifier::BOLD),
+ ),
+ Span::styled(
+ EXPORT_BUTTON_LABEL,
+ Style::default()
+ .fg(Color::LightGreen)
+ .bg(Color::Red)
+ .add_modifier(Modifier::BOLD),
+ ),
+ Span::styled(
+ " ",
+ Style::default().bg(Color::Red).add_modifier(Modifier::BOLD),
+ ),
+ Span::styled(
+ HELP_BUTTON_LABEL,
+ Style::default()
+ .fg(Color::LightGreen)
+ .bg(Color::Red)
+ .add_modifier(Modifier::BOLD),
+ ),
]))
- .style(Style::default().fg(Color::White).bg(Color::Red).add_modifier(Modifier::BOLD));
+ .style(
+ Style::default()
+ .fg(Color::White)
+ .bg(Color::Red)
+ .add_modifier(Modifier::BOLD),
+ );
f.render_widget(paragraph, area);
}
@@ -2000,22 +2126,60 @@ fn draw_help_overlay(f: &mut Frame, app: &mut App, area: Rect) {
let text = vec![
Line::from(Span::styled(" ", Style::default().fg(Color::White))),
Line::from(Span::styled("Global :", Style::default().fg(Color::White))),
- Line::from(Span::styled("F1 or Help button Toggle this help", Style::default().fg(Color::White))),
- Line::from(Span::styled("F2 or Export button Open export popup", Style::default().fg(Color::White))),
- Line::from(Span::styled("Ctrl+C Quit the app", Style::default().fg(Color::White))),
- Line::from(Span::styled("s Stop/cancel running search", Style::default().fg(Color::White))),
- Line::from(Span::styled("Esc Clear selection or close help", Style::default().fg(Color::White))),
- Line::from(Span::styled("Tab or Shift+Tab Move between panels", Style::default().fg(Color::White))),
- Line::from(Span::styled("Up and Down arrows Navigate results", Style::default().fg(Color::White))),
+ Line::from(Span::styled(
+ "F1 or Help button Toggle this help",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "F2 or Export button Open export popup",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "Ctrl+C Quit the app",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "s Stop/cancel running search",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "Esc Clear selection or close help",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "Tab or Shift+Tab Move between panels",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "Up and Down arrows Navigate results",
+ Style::default().fg(Color::White),
+ )),
Line::from(Span::styled(" ", Style::default().fg(Color::White))),
- Line::from(Span::styled("Mouse Click Elements duh", Style::default().fg(Color::White))),
- Line::from(Span::styled("Scrolling Scroll through elements (yea)", Style::default().fg(Color::White))),
-
+ Line::from(Span::styled(
+ "Mouse Click Elements duh",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "Scrolling Scroll through elements (yea)",
+ Style::default().fg(Color::White),
+ )),
Line::from(Span::styled(" ", Style::default().fg(Color::White))),
- Line::from(Span::styled("In Results :", Style::default().fg(Color::White))),
- Line::from(Span::styled("Enter Add highlighted result to Favorites", Style::default().fg(Color::White))),
- Line::from(Span::styled("In Favorites :", Style::default().fg(Color::White))),
- Line::from(Span::styled("Backspace or Delete Remove focused favorite", Style::default().fg(Color::White))),
+ Line::from(Span::styled(
+ "In Results :",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "Enter Add highlighted result to Favorites",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "In Favorites :",
+ Style::default().fg(Color::White),
+ )),
+ Line::from(Span::styled(
+ "Backspace or Delete Remove focused favorite",
+ Style::default().fg(Color::White),
+ )),
];
let block = Block::default()
@@ -2066,7 +2230,10 @@ fn draw_export_popup(f: &mut Frame, app: &mut App, area: Rect) {
style
};
- let subtitle = fit_cell_center("Choose what to export and where to save it.", chunks[0].width as usize);
+ let subtitle = fit_cell_center(
+ "Choose what to export and where to save it.",
+ chunks[0].width as usize,
+ );
f.render_widget(
Paragraph::new(subtitle).style(Style::default().fg(Color::DarkGray)),
chunks[0],
@@ -2118,9 +2285,13 @@ fn draw_export_popup(f: &mut Frame, app: &mut App, area: Rect) {
);
let status_style = if popup_state.status_success {
- Style::default().fg(Color::Green).add_modifier(Modifier::BOLD)
+ Style::default()
+ .fg(Color::Green)
+ .add_modifier(Modifier::BOLD)
} else if popup_state.confirm_overwrite {
- Style::default().fg(Color::Yellow).add_modifier(Modifier::BOLD)
+ Style::default()
+ .fg(Color::Yellow)
+ .add_modifier(Modifier::BOLD)
} else if popup_state.status.is_some() {
Style::default().fg(Color::Red)
} else {
@@ -2132,7 +2303,6 @@ fn draw_export_popup(f: &mut Frame, app: &mut App, area: Rect) {
chunks[3],
);
-
let cancel_label = "[Cancel]";
let button_gap = " ";
let save_label = "[Save]";
@@ -2158,18 +2328,28 @@ fn draw_export_popup(f: &mut Frame, app: &mut App, area: Rect) {
Span::styled(
cancel_label,
if popup_state.selected_row == 2 {
- Style::default().fg(Color::Green).bg(Color::DarkGray).add_modifier(Modifier::BOLD)
+ Style::default()
+ .fg(Color::Green)
+ .bg(Color::DarkGray)
+ .add_modifier(Modifier::BOLD)
} else {
- Style::default().fg(Color::Green).add_modifier(Modifier::BOLD)
+ Style::default()
+ .fg(Color::Green)
+ .add_modifier(Modifier::BOLD)
},
),
Span::raw(button_gap),
Span::styled(
save_label,
if popup_state.selected_row == 3 {
- Style::default().fg(Color::Green).bg(Color::DarkGray).add_modifier(Modifier::BOLD)
+ Style::default()
+ .fg(Color::Green)
+ .bg(Color::DarkGray)
+ .add_modifier(Modifier::BOLD)
} else {
- Style::default().fg(Color::Green).add_modifier(Modifier::BOLD)
+ Style::default()
+ .fg(Color::Green)
+ .add_modifier(Modifier::BOLD)
},
),
]);
@@ -2207,7 +2387,12 @@ fn draw_results(f: &mut Frame, app: &mut App, area: Rect) {
Some(d) => format!(" | Took: {:.1}s", d.as_secs_f64()),
None => String::new(),
};
- format!(" Results ({} available / {} total{}) ", avail, app.results.len(), duration_str)
+ format!(
+ " Results ({} available / {} total{}) ",
+ avail,
+ app.results.len(),
+ duration_str
+ )
};
let block = Block::default()
@@ -2251,13 +2436,34 @@ fn draw_results(f: &mut Frame, app: &mut App, area: Rect) {
fn draw_results_list(f: &mut Frame, app: &mut App, area: Rect) {
let show_note_column = app.show_unavailable;
let selected_idx = app.results_state.selected();
- let selected_bg = Color::Black;
+ let selected_bg = Color::Black;
// collect visible results
let visible_data: Vec<(String, String, String, DomainStatus)> = if app.show_unavailable {
- app.results.iter().map(|(_, r)| (r.full.clone(), r.status_str().to_string(), r.note_str(), r.status.clone())).collect()
+ app.results
+ .iter()
+ .map(|(_, r)| {
+ (
+ r.full.clone(),
+ r.status_str().to_string(),
+ r.note_str(),
+ r.status.clone(),
+ )
+ })
+ .collect()
} else {
- app.results.iter().filter(|(_, r)| r.is_available()).map(|(_, r)| (r.full.clone(), r.status_str().to_string(), r.note_str(), r.status.clone())).collect()
+ app.results
+ .iter()
+ .filter(|(_, r)| r.is_available())
+ .map(|(_, r)| {
+ (
+ r.full.clone(),
+ r.status_str().to_string(),
+ r.note_str(),
+ r.status.clone(),
+ )
+ })
+ .collect()
};
if visible_data.is_empty() && !app.searching {
@@ -2311,18 +2517,38 @@ fn draw_results_list(f: &mut Frame, app: &mut App, area: Rect) {
if let Some(header_area) = header_area {
let mut header_spans = vec![
- Span::styled(format!(" {}", fit_cell("Domain", domain_w)), Style::default().fg(Color::Gray).add_modifier(Modifier::BOLD)),
+ Span::styled(
+ format!(" {}", fit_cell("Domain", domain_w)),
+ Style::default()
+ .fg(Color::Gray)
+ .add_modifier(Modifier::BOLD),
+ ),
Span::styled(" │ ", Style::default().fg(Color::DarkGray)),
- Span::styled(fit_cell("Status", status_w), Style::default().fg(Color::Gray).add_modifier(Modifier::BOLD)),
+ Span::styled(
+ fit_cell("Status", status_w),
+ Style::default()
+ .fg(Color::Gray)
+ .add_modifier(Modifier::BOLD),
+ ),
];
if show_note_column {
header_spans.push(Span::styled(" │ ", Style::default().fg(Color::DarkGray)));
- header_spans.push(Span::styled(fit_cell("Details", note_w), Style::default().fg(Color::Gray).add_modifier(Modifier::BOLD)));
+ header_spans.push(Span::styled(
+ fit_cell("Details", note_w),
+ Style::default()
+ .fg(Color::Gray)
+ .add_modifier(Modifier::BOLD),
+ ));
}
header_spans.push(Span::styled(" │ ", Style::default().fg(Color::DarkGray)));
- header_spans.push(Span::styled(" ✓ ", Style::default().fg(Color::Gray).add_modifier(Modifier::BOLD)));
+ header_spans.push(Span::styled(
+ " ✓ ",
+ Style::default()
+ .fg(Color::Gray)
+ .add_modifier(Modifier::BOLD),
+ ));
f.render_widget(Paragraph::new(Line::from(header_spans)), header_area);
}
@@ -2361,22 +2587,40 @@ fn draw_results_list(f: &mut Frame, app: &mut App, area: Rect) {
};
let mut spans = vec![
- Span::styled(format!(" {}", fit_cell(full, domain_w)), apply_bg(domain_style)),
+ Span::styled(
+ format!(" {}", fit_cell(full, domain_w)),
+ apply_bg(domain_style),
+ ),
Span::styled(" \u{2502} ", apply_bg(Style::default().fg(Color::Gray))),
Span::styled(fit_cell(status_str, status_w), apply_bg(status_style)),
];
if show_note_column {
- spans.push(Span::styled(" \u{2502} ", apply_bg(Style::default().fg(Color::Gray))));
- spans.push(Span::styled(fit_cell(note, note_w), apply_bg(Style::default().fg(Color::White))));
+ spans.push(Span::styled(
+ " \u{2502} ",
+ apply_bg(Style::default().fg(Color::Gray)),
+ ));
+ spans.push(Span::styled(
+ fit_cell(note, note_w),
+ apply_bg(Style::default().fg(Color::White)),
+ ));
}
- spans.push(Span::styled(" \u{2502} ", apply_bg(Style::default().fg(Color::Gray))));
+ spans.push(Span::styled(
+ " \u{2502} ",
+ apply_bg(Style::default().fg(Color::Gray)),
+ ));
spans.push(match status {
- DomainStatus::Available => Span::styled(" ✓ ", apply_bg(Style::default().fg(Color::Green))),
- DomainStatus::Registered { .. } => Span::styled(" ✗ ", apply_bg(Style::default().fg(Color::Red))),
+ DomainStatus::Available => {
+ Span::styled(" ✓ ", apply_bg(Style::default().fg(Color::Green)))
+ }
+ DomainStatus::Registered { .. } => {
+ Span::styled(" ✗ ", apply_bg(Style::default().fg(Color::Red)))
+ }
DomainStatus::Error { kind, .. } => match kind {
- ErrorKind::InvalidTld => Span::styled(" ? ", apply_bg(Style::default().fg(Color::Yellow))),
+ ErrorKind::InvalidTld => {
+ Span::styled(" ? ", apply_bg(Style::default().fg(Color::Yellow)))
+ }
_ => Span::styled(" ! ", apply_bg(Style::default().fg(Color::Blue))),
},
});
@@ -2553,8 +2797,7 @@ fn draw_scratchpad(f: &mut Frame, app: &mut App, area: Rect) {
};
f.render_widget(block, area);
f.render_widget(
- Paragraph::new(text)
- .style(Style::default().fg(Color::White)),
+ Paragraph::new(text).style(Style::default().fg(Color::White)),
inner,
);
@@ -2623,17 +2866,17 @@ fn draw_favorites(f: &mut Frame, app: &mut App, area: Rect) {
})
.collect();
- let list = List::new(items)
- .highlight_style(
- Style::default()
- .add_modifier(Modifier::REVERSED),
- );
+ let list = List::new(items).highlight_style(Style::default().add_modifier(Modifier::REVERSED));
f.render_widget(block, area);
f.render_stateful_widget(list, list_area, &mut app.favorites_state);
// Draw the check button at the bottom
- let btn_label = if app.checking_favorites { "checking..." } else { "[c]heck all" };
+ let btn_label = if app.checking_favorites {
+ "checking..."
+ } else {
+ "[c]heck all"
+ };
let btn_style = if app.checking_favorites {
Style::default().fg(Color::DarkGray)
} else {
@@ -2688,13 +2931,17 @@ fn draw_settings(f: &mut Frame, app: &mut App, area: Rect) {
};
let tld_row_style = if selected == Some(0) {
- Style::default().bg(Color::DarkGray).add_modifier(Modifier::BOLD)
+ Style::default()
+ .bg(Color::DarkGray)
+ .add_modifier(Modifier::BOLD)
} else {
Style::default()
};
let jobs_row_style = if selected == Some(4) {
- Style::default().bg(Color::DarkGray).add_modifier(Modifier::BOLD)
+ Style::default()
+ .bg(Color::DarkGray)
+ .add_modifier(Modifier::BOLD)
} else {
Style::default()
};
@@ -2801,23 +3048,44 @@ fn draw_search(f: &mut Frame, app: &mut App, area: Rect) {
let cancel_enabled = app.searching;
let search_style = if search_enabled {
- Style::default().fg(Color::Black).bg(Color::Green).add_modifier(Modifier::BOLD)
+ Style::default()
+ .fg(Color::Black)
+ .bg(Color::Green)
+ .add_modifier(Modifier::BOLD)
} else {
Style::default().fg(Color::DarkGray).bg(Color::Black)
};
let stop_style = if cancel_enabled {
- Style::default().fg(Color::Black).bg(Color::Yellow).add_modifier(Modifier::BOLD)
+ Style::default()
+ .fg(Color::Black)
+ .bg(Color::Yellow)
+ .add_modifier(Modifier::BOLD)
} else {
Style::default().fg(Color::DarkGray).bg(Color::Black)
};
- let clear_style = Style::default().fg(Color::White).bg(Color::Red).add_modifier(Modifier::BOLD);
+ let clear_style = Style::default()
+ .fg(Color::White)
+ .bg(Color::Red)
+ .add_modifier(Modifier::BOLD);
- f.render_widget(Paragraph::new(SEARCH_BUTTON_LABEL).style(search_style), chunks[1]);
+ f.render_widget(
+ Paragraph::new(SEARCH_BUTTON_LABEL).style(search_style),
+ chunks[1],
+ );
if app.clear_on_search {
- f.render_widget(Paragraph::new(STOP_BUTTON_LABEL).style(stop_style), chunks[3]);
+ f.render_widget(
+ Paragraph::new(STOP_BUTTON_LABEL).style(stop_style),
+ chunks[3],
+ );
} else {
- f.render_widget(Paragraph::new(STOP_BUTTON_LABEL).style(stop_style), chunks[3]);
- f.render_widget(Paragraph::new(CLEAR_BUTTON_LABEL).style(clear_style), chunks[5]);
+ f.render_widget(
+ Paragraph::new(STOP_BUTTON_LABEL).style(stop_style),
+ chunks[3],
+ );
+ f.render_widget(
+ Paragraph::new(CLEAR_BUTTON_LABEL).style(clear_style),
+ chunks[5],
+ );
}
// show cursor in search bar when focused
@@ -2836,7 +3104,10 @@ fn draw_dropdown(f: &mut Frame, app: &mut App, settings_area: Rect, selected: us
let dropdown_full = Rect {
x: settings_area.x + 1,
y: settings_area.y + 1,
- width: settings_area.width.saturating_sub(2).min(DROPDOWN_MAX_WIDTH),
+ width: settings_area
+ .width
+ .saturating_sub(2)
+ .min(DROPDOWN_MAX_WIDTH),
height: (options.len() as u16 + 2).min(DROPDOWN_MAX_HEIGHT),
};
@@ -2861,9 +3132,12 @@ fn draw_dropdown(f: &mut Frame, app: &mut App, settings_area: Rect, selected: us
.title(" TLD List ");
f.render_widget(Clear, dropdown_full);
- let list = List::new(items)
- .block(block)
- .highlight_style(Style::default().fg(Color::White).bg(Color::Red).add_modifier(Modifier::BOLD));
+ let list = List::new(items).block(block).highlight_style(
+ Style::default()
+ .fg(Color::White)
+ .bg(Color::Red)
+ .add_modifier(Modifier::BOLD),
+ );
let mut state = ListState::default();
state.select(Some(selected));
f.render_stateful_widget(list, dropdown_full, &mut state);