Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 16 additions & 77 deletions src/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ use ratatui::{
},
};

use crate::{app::ColorMode, config::Config};
use crate::{
app::ColorMode,
config::Config,
keybindings::{Keybinding, build_keybindings},
};

#[derive(Debug)]
pub struct Help {
block_height: usize,
state: TableState,
keys: Vec<(Cell<'static>, &'static str)>,
keys: Vec<Keybinding>,
}

impl Help {
Expand All @@ -27,79 +31,7 @@ impl Help {
Self {
block_height: 0,
state,
keys: vec![
(
Cell::from("## Global").style(Style::new().bold().fg(Color::Yellow)),
"",
),
(Cell::from("Esc").bold(), "Dismiss different pop-ups"),
(
Cell::from("Tab or h/l").bold(),
"Switch between different sections",
),
(Cell::from("j or Down").bold(), "Scroll down"),
(Cell::from("k or Up").bold(), "Scroll up"),
(
Cell::from(config.toggle_scanning.to_string()).bold(),
"Start/Stop scanning",
),
(Cell::from("?").bold(), "Show help"),
(Cell::from("ctrl+c or q").bold(), "Quit"),
(Cell::from(""), ""),
(
Cell::from("## Adapters").style(Style::new().bold().fg(Color::Yellow)),
"",
),
(
Cell::from(config.adapter.toggle_pairing.to_string()).bold(),
"Enable/Disable the pairing",
),
(
Cell::from(config.adapter.toggle_power.to_string()).bold(),
"Power on/off the adapter",
),
(
Cell::from(config.adapter.toggle_discovery.to_string()).bold(),
"Enable/Disable the discovery",
),
(Cell::from(""), ""),
(
Cell::from("## Paired devices").style(Style::new().bold().fg(Color::Yellow)),
"",
),
(
Cell::from(config.paired_device.unpair.to_string()).bold(),
"Unpair the device",
),
(
Cell::from({
if config.paired_device.toggle_connect == ' ' {
"Space".to_string()
} else {
config.paired_device.toggle_connect.to_string()
}
})
.bold(),
"Connect/Disconnect the device",
),
(
Cell::from(config.paired_device.toggle_trust.to_string()).bold(),
"Trust/Untrust the device",
),
(
Cell::from(config.paired_device.rename.to_string()).bold(),
"Rename the device",
),
(Cell::from(""), ""),
(
Cell::from("## New devices").style(Style::default().bold().fg(Color::Yellow)),
"",
),
(
Cell::from(config.new_device.pair.to_string()).bold(),
"Pair the device",
),
],
keys: build_keybindings(&config),
}
}

Expand Down Expand Up @@ -153,8 +85,15 @@ impl Help {
let rows: Vec<Row> = self
.keys
.iter()
.map(|key| {
Row::new(vec![key.0.to_owned(), key.1.into()]).style(match color_mode {
.map(|keybinding| {
let key_cell = if keybinding.is_section {
Cell::from(keybinding.key.clone())
.style(Style::default().bold().fg(Color::Yellow))
} else {
Cell::from(keybinding.key.clone()).style(Style::default().bold())
};
let description_cell = Cell::from(keybinding.description);
Row::new(vec![key_cell, description_cell]).style(match color_mode {
ColorMode::Dark => Style::default().fg(Color::White),
ColorMode::Light => Style::default().fg(Color::Black),
})
Expand Down
148 changes: 148 additions & 0 deletions src/keybindings.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
use crate::config::Config;

#[derive(Debug)]
pub struct Keybinding {
pub key: String,
pub description: &'static str,
pub is_section: bool,
}

pub fn build_keybindings(config: &Config) -> Vec<Keybinding> {
let human_readable_key = |c: char| match c {
' ' => "Space".to_string(),
'\n' => "Enter".to_string(),
'\t' => "Tab".to_string(),
other => other.to_string(),
};

let keys = vec![
Keybinding {
key: "## Global".into(),
description: "",
is_section: true,
},
Keybinding {
key: "Esc".into(),
description: "Dismiss different pop-ups",
is_section: false,
},
Keybinding {
key: "Tab or h/l".into(),
description: "Switch between different sections",
is_section: false,
},
Keybinding {
key: "j or Down".into(),
description: "Scroll down",
is_section: false,
},
Keybinding {
key: "k or Up".into(),
description: "Scroll up",
is_section: false,
},
Keybinding {
key: human_readable_key(config.toggle_scanning),
description: "Start/Stop scanning",
is_section: false,
},
Keybinding {
key: "?".into(),
description: "Show help",
is_section: false,
},
Keybinding {
key: "ctrl+c or q".into(),
description: "Quit",
is_section: false,
},
Keybinding {
key: "".into(),
description: "",
is_section: false,
},
Keybinding {
key: "## Adapters".into(),
description: "",
is_section: true,
},
Keybinding {
key: human_readable_key(config.adapter.toggle_pairing),
description: "Enable/Disable the pairing",
is_section: false,
},
Keybinding {
key: human_readable_key(config.adapter.toggle_power),
description: "Power on/off the adapter",
is_section: false,
},
Keybinding {
key: human_readable_key(config.adapter.toggle_discovery),
description: "Enable/Disable the discovery",
is_section: false,
},
Keybinding {
key: "".into(),
description: "",
is_section: false,
},
Keybinding {
key: "## Paired devices".into(),
description: "",
is_section: true,
},
Keybinding {
key: human_readable_key(config.paired_device.unpair),
description: "Unpair the device",
is_section: false,
},
Keybinding {
key: human_readable_key(config.paired_device.toggle_connect),
description: "Connect/Disconnect the device",
is_section: false,
},
Keybinding {
key: human_readable_key(config.paired_device.toggle_trust),
description: "Trust/Untrust the device",
is_section: false,
},
Keybinding {
key: human_readable_key(config.paired_device.rename),
description: "Rename the device",
is_section: false,
},
Keybinding {
key: "".into(),
description: "",
is_section: false,
},
Keybinding {
key: "## New devices".into(),
description: "",
is_section: true,
},
Keybinding {
key: human_readable_key(config.new_device.pair),
description: "Pair the device",
is_section: false,
},
];

keys
}

pub fn keybindings_string(config: &Config) -> String {
let bindings = build_keybindings(config);
let mut s = String::from("Hotkeys:\n\n");

for kb in bindings {
if kb.is_section {
s.push_str(&format!("{}\n", kb.key));
} else if kb.key.is_empty() && kb.description.is_empty() {
s.push('\n');
} else {
s.push_str(&format!(" {:18} {}\n", kb.key, kb.description));
}
}
s
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@ pub mod config;
pub mod rfkill;

pub mod confirmation;

pub mod keybindings;
4 changes: 3 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use bluetui::{
config::Config,
event::{Event, EventHandler},
handler::handle_key_events,
keybindings::keybindings_string,
rfkill,
tui::Tui,
};
Expand All @@ -12,13 +13,14 @@ use std::{io, sync::Arc};

#[tokio::main]
async fn main() -> AppResult<()> {
let config = Arc::new(Config::new());
Command::new("bluetui")
.version(crate_version!())
.after_help(keybindings_string(&config))
.get_matches();

rfkill::check()?;

let config = Arc::new(Config::new());
let mut app = App::new(config.clone()).await?;
let backend = CrosstermBackend::new(io::stdout());
let terminal = Terminal::new(backend)?;
Expand Down