diff --git a/CHANGELOG.md b/CHANGELOG.md index bcfca60..2be86b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. - Added a flag to indicate whether the app is scanning the networks or not. - Changed the type of list that was send to the scan_networks function from main App `struct` to be `RwLock` wrapped type rather than Arc wrapped type. +- Removed the redundant key press kind. ### Changed diff --git a/src/apps/core/delete_handler.rs b/src/apps/core/delete_handler.rs index 4b207c5..832e21f 100644 --- a/src/apps/core/delete_handler.rs +++ b/src/apps/core/delete_handler.rs @@ -2,7 +2,6 @@ use super::App; use crate::utils::delete_connection::delete_connection; use crate::utils::scan::scan_networks; -use crossterm::event::KeyEventKind::Press; use crossterm::event::{self, Event, KeyCode, KeyEvent, poll}; use std::io; use std::time::Duration; @@ -27,69 +26,27 @@ impl App { /// // let _ = app.handle_delete_confirmation(); /// ``` pub fn handle_delete_confirmation(&mut self) -> io::Result<()> { - if poll(Duration::from_micros(1))? { - match event::read()? { - Event::Key(KeyEvent { - code: KeyCode::Enter, - kind: Press, - .. - }) => { + if poll(Duration::from_micros(1))? + && let Event::Key(KeyEvent { + code, modifiers, .. + }) = event::read()? + { + match (code, modifiers) { + (KeyCode::Enter, _) | (KeyCode::Char('Y'), _) | (KeyCode::Char('y'), _) => { self.delete_connection(); } - Event::Key(KeyEvent { - code: KeyCode::Char('Y'), - kind: Press, - .. - }) => { - self.delete_connection(); - } - Event::Key(KeyEvent { - code: KeyCode::Char('y'), - kind: Press, - .. - }) => { - self.delete_connection(); - } - Event::Key(KeyEvent { - code: KeyCode::Char('N'), - kind: Press, - .. - }) => { - self.flags.show_delete_confirmation = false; - } - Event::Key(KeyEvent { - code: KeyCode::Char('n'), - kind: Press, - .. - }) => { + (KeyCode::Char('N'), _) + | (KeyCode::Char('n'), _) + | (KeyCode::Esc, _) + | (KeyCode::Char('q'), _) => { self.flags.show_delete_confirmation = false; } - Event::Key(KeyEvent { - code: KeyCode::Char('c'), - kind: Press, - modifiers: event::KeyModifiers::CONTROL, - .. - }) => { + (KeyCode::Char('c'), event::KeyModifiers::CONTROL) => { self.exit(); } - Event::Key(KeyEvent { - code: KeyCode::Esc, - kind: Press, - .. - }) => { - self.flags.show_delete_confirmation = false; - } - Event::Key(KeyEvent { - code: KeyCode::Char('q'), - kind: Press, - .. - }) => { - self.flags.show_delete_confirmation = false; - } - _ => {} } - }; + } Ok(()) } /// Delete the currently selected connection and refresh the network list. diff --git a/src/apps/core/event_handlers.rs b/src/apps/core/event_handlers.rs index 7a9f8cd..3ea5c0b 100644 --- a/src/apps/core/event_handlers.rs +++ b/src/apps/core/event_handlers.rs @@ -1,7 +1,6 @@ use super::App; use crate::utils::scan::scan_networks; -use crossterm::event::KeyEventKind::Press; use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyModifiers, poll}; use std::io; use std::time::Duration; @@ -27,120 +26,60 @@ impl App { /// app.handle_events().unwrap(); /// ``` pub fn handle_events(&mut self) -> io::Result<()> { - if poll(Duration::from_micros(1))? { - match event::read()? { - Event::Key(KeyEvent { - code: KeyCode::Char('h'), - kind: Press, - .. - }) => { + if poll(Duration::from_micros(1))? + && let Event::Key(KeyEvent { + code, modifiers, .. + }) = event::read()? + { + match (code, modifiers) { + (KeyCode::Char('h'), _) => { self.flags.show_help = true; } - - Event::Key(KeyEvent { - code: KeyCode::Char('?'), - kind: Press, - .. - }) => { + (KeyCode::Char('?'), _) => { self.flags.show_help = true; } - Event::Key(KeyEvent { - code: KeyCode::Esc, - kind: Press, - .. - }) => { + (KeyCode::Esc, _) => { self.exit(); } - Event::Key(KeyEvent { - code: KeyCode::Char('c'), - modifiers: KeyModifiers::CONTROL, - kind: Press, - .. - }) => { + (KeyCode::Char('c'), KeyModifiers::CONTROL) => { self.exit(); } - Event::Key(KeyEvent { - code: KeyCode::Char('r'), - modifiers: KeyModifiers::CONTROL, - kind: Press, - .. - }) => { + (KeyCode::Char('r'), KeyModifiers::CONTROL) => { scan_networks(self.wifi_list.clone(), self.flags.is_scanning.clone()); } - Event::Key(KeyEvent { - code: KeyCode::Enter, - kind: Press, - .. - }) => { - self.prepare_to_connect(); - } - Event::Key(KeyEvent { - code: KeyCode::Char('o'), - kind: Press, - .. - }) => { + (KeyCode::Char('o'), _) | (KeyCode::Enter, _) => { self.prepare_to_connect(); } - Event::Key(KeyEvent { - code: KeyCode::Up, - kind: Press, - .. - }) => { + (KeyCode::Up, _) | (KeyCode::Char('k'), _) => { self.update_selected_network(-1); } - Event::Key(KeyEvent { - code: KeyCode::Down, - kind: Press, - .. - }) => { + (KeyCode::Down, _) | (KeyCode::Char('j'), _) => { self.update_selected_network(1); } - // vim style - Event::Key(KeyEvent { - code: KeyCode::Char('k'), - kind: Press, - .. - }) => { - self.update_selected_network(-1); - } - Event::Key(KeyEvent { - code: KeyCode::Char('j'), - kind: Press, - .. - }) => { - self.update_selected_network(1); + (KeyCode::Char('d'), _) => { + self.set_delete_confirmation(); } - Event::Key(KeyEvent { - code: KeyCode::Char('d'), - kind: Press, - .. - }) => { - if self - .wifi_list - .read() - .expect("Wifi list lock poisoned while deleting")[self.selected] - .is_saved - { - self.flags.show_delete_confirmation = true; - } - } - Event::Key(KeyEvent { - code: KeyCode::Char('s'), - kind: Press, - .. - }) => { + (KeyCode::Char('s'), _) => { self.open_saved_list(); } - Event::Key(KeyEvent { - code: KeyCode::Char('x'), - kind: Press, - .. - }) => { + (KeyCode::Char('x'), _) => { self.disconnect(); } _ => {} - }; + } } + Ok(()) } + + fn set_delete_confirmation(&mut self) { + if self + .wifi_list + .read() + .expect("Wifi list lock poisoned while deleting")[self.selected] + .is_saved + { + self.flags.show_delete_confirmation = true; + } + } } diff --git a/src/apps/core/help_handlers.rs b/src/apps/core/help_handlers.rs index 3d6be73..a8dec75 100644 --- a/src/apps/core/help_handlers.rs +++ b/src/apps/core/help_handlers.rs @@ -20,39 +20,22 @@ impl App { /// app.handle_help().unwrap(); /// ``` pub fn handle_help(&mut self) -> io::Result<()> { - if poll(Duration::from_micros(1))? { - match event::read()? { - Event::Key(KeyEvent { - code: event::KeyCode::Esc, - kind: event::KeyEventKind::Press, - .. - }) => { + if poll(Duration::from_micros(1))? + && let Event::Key(KeyEvent { + code, modifiers, .. + }) = event::read()? + { + match (code, modifiers) { + (event::KeyCode::Esc, _) + | (event::KeyCode::Enter, _) + | (event::KeyCode::Char('q'), _) => { self.close_help(); } - Event::Key(KeyEvent { - code: event::KeyCode::Enter, - kind: event::KeyEventKind::Press, - .. - }) => { - self.close_help(); - } - Event::Key(KeyEvent { - code: event::KeyCode::Char('q'), - kind: event::KeyEventKind::Press, - .. - }) => { - self.close_help(); - } - Event::Key(KeyEvent { - code: event::KeyCode::Char('c'), - kind: event::KeyEventKind::Press, - modifiers: event::KeyModifiers::CONTROL, - .. - }) => { + (event::KeyCode::Char('c'), event::KeyModifiers::CONTROL) => { self.exit(); } _ => {} - }; + } } Ok(()) } diff --git a/src/apps/core/saved_connection.rs b/src/apps/core/saved_connection.rs index aa24270..d0b1d34 100644 --- a/src/apps/core/saved_connection.rs +++ b/src/apps/core/saved_connection.rs @@ -83,91 +83,36 @@ impl App { /// let _ = app.handle_saved(); /// ``` pub fn handle_saved(&mut self) -> io::Result<()> { - if poll(Duration::from_micros(1))? { - match event::read()? { - Event::Key(KeyEvent { - code: event::KeyCode::Char('q'), - kind: event::KeyEventKind::Press, - .. - }) => { + if poll(Duration::from_micros(1))? + && let Event::Key(KeyEvent { + code, modifiers, .. + }) = event::read()? + { + match (code, modifiers) { + (event::KeyCode::Char('q'), _) | (event::KeyCode::Esc, _) => { self.close_saved_list(); } - Event::Key(KeyEvent { - code: event::KeyCode::Esc, - kind: event::KeyEventKind::Press, - .. - }) => { - self.close_saved_list(); - } - Event::Key(KeyEvent { - code: event::KeyCode::Char('c'), - kind: event::KeyEventKind::Press, - modifiers: event::KeyModifiers::CONTROL, - .. - }) => { + (event::KeyCode::Char('c'), event::KeyModifiers::CONTROL) => { self.exit(); } - Event::Key(KeyEvent { - code: event::KeyCode::Char('d'), - kind: event::KeyEventKind::Press, - .. - }) => { + (event::KeyCode::Char('d'), _) => { // this will evaluate to run the delete confirmation dialog from the core ui self.flags.show_delete_confirmation = true; } - - Event::Key(KeyEvent { - code: event::KeyCode::Char('j'), - kind: event::KeyEventKind::Press, - .. - }) => { - self.update_selected_saved_network(1); - } - Event::Key(KeyEvent { - code: event::KeyCode::Down, - kind: event::KeyEventKind::Press, - .. - }) => { + (event::KeyCode::Char('j'), _) | (event::KeyCode::Down, _) => { self.update_selected_saved_network(1); } - Event::Key(KeyEvent { - code: event::KeyCode::Char('k'), - kind: event::KeyEventKind::Press, - .. - }) => { + (event::KeyCode::Char('k'), _) | (event::KeyCode::Up, _) => { self.update_selected_saved_network(-1); } - Event::Key(KeyEvent { - code: event::KeyCode::Up, - kind: event::KeyEventKind::Press, - .. - }) => { - self.update_selected_saved_network(-1); - } - Event::Key(KeyEvent { - code: event::KeyCode::Char('h'), - kind: event::KeyEventKind::Press, - .. - }) => { + (event::KeyCode::Char('h'), _) | (event::KeyCode::Char('?'), _) => { self.flags.show_help = true; } - Event::Key(KeyEvent { - code: event::KeyCode::Char('?'), - kind: event::KeyEventKind::Press, - .. - }) => { - self.flags.show_help = true; - } - Event::Key(KeyEvent { - code: event::KeyCode::Char('r'), - kind: event::KeyEventKind::Press, - modifiers: event::KeyModifiers::CONTROL, - .. - }) => { + (event::KeyCode::Char('r'), event::KeyModifiers::CONTROL) => { self.saved_connection.fetch_saved_connections(); } _ => {} - }; + } } Ok(()) } diff --git a/src/apps/handlers/password_handler.rs b/src/apps/handlers/password_handler.rs index 9895dd6..4f8ab72 100644 --- a/src/apps/handlers/password_handler.rs +++ b/src/apps/handlers/password_handler.rs @@ -1,32 +1,24 @@ use super::WifiInputState; use super::utils::{delete_char, enter_char, move_cursor_right}; -use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind::Press, poll}; +use crossterm::event::{self, Event, KeyCode, KeyEvent, poll}; use std::io; use std::time::Duration; impl WifiInputState { pub fn handle_password_input(&mut self) -> io::Result<()> { - if poll(Duration::from_micros(1))? { - match event::read()? { - Event::Key(KeyEvent { - code: KeyCode::Left, - kind: Press, - .. - }) => { + if poll(Duration::from_micros(1))? + && let Event::Key(KeyEvent { + code, modifiers, .. + }) = event::read()? + { + match (code, modifiers) { + (KeyCode::Left, _) => { self.move_cursor_left(); } - Event::Key(KeyEvent { - code: KeyCode::Right, - kind: Press, - .. - }) => { + (KeyCode::Right, _) => { move_cursor_right(&self.password, &mut self.cursor_pos); } - Event::Key(KeyEvent { - code: KeyCode::Esc, - kind: Press, - .. - }) => { + (KeyCode::Esc, _) => { // if we go back from password input, we should show the ssid popup again // with the cursor at the end of the ssid self.flags.show_password_popup = false; @@ -35,33 +27,21 @@ impl WifiInputState { self.cursor_pos = self.ssid.chars().count() as u16; } } - Event::Key(KeyEvent { - code: KeyCode::Char(c), - kind: Press, - .. - }) => { + (KeyCode::Char(c), _) => { enter_char(&mut self.password, c, &self.cursor_pos); move_cursor_right(&self.password, &mut self.cursor_pos); } - Event::Key(KeyEvent { - code: KeyCode::Backspace, - kind: Press, - .. - }) => { + (KeyCode::Backspace, _) => { delete_char(&mut self.password, &mut self.cursor_pos); self.move_cursor_left() } - Event::Key(KeyEvent { - code: KeyCode::Enter, - kind: Press, - .. - }) => { + (KeyCode::Enter, _) => { if self.password.is_empty() || self.password.chars().count() >= 8 { self.prepare_to_connect(); } } _ => {} - }; + } } Ok(()) } diff --git a/src/apps/handlers/ssid_handler.rs b/src/apps/handlers/ssid_handler.rs index 6e8f0ea..cf74c3d 100644 --- a/src/apps/handlers/ssid_handler.rs +++ b/src/apps/handlers/ssid_handler.rs @@ -1,64 +1,46 @@ use super::utils::{delete_char, enter_char, move_cursor_right}; use crate::apps::handlers::WifiInputState; -use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind::Press, poll}; +use crossterm::event::{self, Event, KeyCode, KeyEvent, poll}; use std::io; use std::time::Duration; impl WifiInputState { pub fn handle_ssid_input(&mut self) -> io::Result<()> { - if poll(Duration::from_micros(1))? { - match event::read()? { - Event::Key(KeyEvent { - code: KeyCode::Left, - kind: Press, - .. - }) => { - self.move_cursor_left(); - } - Event::Key(KeyEvent { - code: KeyCode::Right, - kind: Press, - .. - }) => { - move_cursor_right(&self.ssid, &mut self.cursor_pos); - } - Event::Key(KeyEvent { - code: KeyCode::Esc, - kind: Press, - .. - }) => { + if poll(Duration::from_micros(1))? + && let Event::Key(KeyEvent { code, .. }) = event::read()? + { + match code { + KeyCode::Esc => { self.flags.show_ssid_popup = false; + return Ok(()); } - Event::Key(KeyEvent { - code: KeyCode::Char(c), - kind: Press, - .. - }) => { + KeyCode::Char(c) => { enter_char(&mut self.ssid, c, &self.cursor_pos); move_cursor_right(&self.ssid, &mut self.cursor_pos); + return Ok(()); } - Event::Key(KeyEvent { - code: KeyCode::Backspace, - kind: Press, - .. - }) => { + KeyCode::Backspace => { delete_char(&mut self.ssid, &mut self.cursor_pos); self.move_cursor_left(); + return Ok(()); } - Event::Key(KeyEvent { - code: KeyCode::Enter, - kind: Press, - .. - }) => { + KeyCode::Enter => { // when ssid is entered, we should show the password popup // but if the user had entered a password before, we should keep it // so that the user can go back and forth without losing the password self.flags.show_ssid_popup = false; self.flags.show_password_popup = true; self.cursor_pos = self.password.chars().count() as u16; + return Ok(()); + } + KeyCode::Left => { + self.move_cursor_left(); + } + KeyCode::Right => { + move_cursor_right(&self.ssid, &mut self.cursor_pos); } _ => {} - }; + } } Ok(()) } diff --git a/src/apps/handlers/status.rs b/src/apps/handlers/status.rs index 8832494..2c3a635 100644 --- a/src/apps/handlers/status.rs +++ b/src/apps/handlers/status.rs @@ -1,5 +1,5 @@ use super::WifiInputState; -use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind::Press, poll}; +use crossterm::event::{self, Event, KeyCode, KeyEvent, poll}; use std::io; use std::process::ExitStatus; use std::time::Duration; @@ -30,38 +30,18 @@ impl Status { impl WifiInputState { pub fn handle_status_message(&mut self) -> io::Result<()> { - if poll(Duration::from_micros(1))? { - match event::read()? { - Event::Key(KeyEvent { - code: KeyCode::Esc, - kind: Press, - .. - }) => { - self.flags.show_status_popup = false; - self.status.status_message.clear(); - self.status.status_code = ExitStatus::default(); - } - Event::Key(KeyEvent { - code: KeyCode::Char('q'), - kind: Press, - .. - }) => { - self.flags.show_status_popup = false; - self.status.status_message.clear(); - self.status.status_code = ExitStatus::default(); - } - Event::Key(KeyEvent { - code: KeyCode::Enter, - kind: Press, - .. - }) => { + if poll(Duration::from_micros(1))? + && let Event::Key(KeyEvent { code, .. }) = event::read()? + { + match code { + KeyCode::Esc | KeyCode::Char('q') | KeyCode::Enter => { self.flags.show_status_popup = false; self.status.status_message.clear(); self.status.status_code = ExitStatus::default(); } _ => {} } - }; + } Ok(()) } } diff --git a/src/utils/connect.rs b/src/utils/connect.rs index 895c127..dfe4820 100644 --- a/src/utils/connect.rs +++ b/src/utils/connect.rs @@ -1,24 +1,23 @@ -use crate::apps::handlers::WifiInputState; -use crate::apps::handlers::flags::Flags; -use crate::apps::handlers::status::Status; -use std::process::{Command, ExitStatus}; +use crate::apps::handlers::{WifiInputState, flags::Flags, status::Status}; +use std::io::Error; +use std::process::{Command, ExitStatus, Output}; -// Connect to a saved network without password -pub fn connect_to_saved_network(ssid: &str) -> Status { - let output = Command::new("nmcli") - .args(["dev", "wifi", "connect", ssid]) - .output(); - match output { - Ok(output) => { - let status = output.status; - if status.success() { - let stdout = format!("Successfully connected to '{}'", ssid); - Status::new(stdout.to_string(), status) - } else { - let stderr = String::from_utf8_lossy(&output.stderr); - Status::new(stderr.to_string(), status) - } - } +// handle the output of the command execution and return a Status object +fn handle_command_output(output: Output, ssid: &str) -> Status { + let status = output.status; + if status.success() { + let stdout = format!("Successfully connected to '{}'", ssid); + Status::new(stdout.to_string(), status) + } else { + let stderr = String::from_utf8_lossy(&output.stderr); + Status::new(stderr.to_string(), status) + } +} + +// handle the result of the command execution and return a Status object +fn handle_command_result(result: Result, ssid: &str) -> Status { + match result { + Ok(output) => handle_command_output(output, ssid), Err(e) => Status::new( format!("Failed to execute nmcli: {}", e), ExitStatus::default(), @@ -26,6 +25,14 @@ pub fn connect_to_saved_network(ssid: &str) -> Status { } } +// Connect to a saved network without password +pub fn connect_to_saved_network(ssid: &str) -> Status { + let output = Command::new("nmcli") + .args(["dev", "wifi", "connect", ssid]) + .output(); + handle_command_result(output, ssid) +} + // Connect to a network with given credentials pub fn connect_to_network(wifi_creadentials: &WifiInputState) -> Status { let WifiInputState { @@ -49,22 +56,5 @@ pub fn connect_to_network(wifi_creadentials: &WifiInputState) -> Status { .output() }; - match output { - Ok(output) => { - let status = output.status; - if status.success() { - // here this thing is creating some glitch in the ui when connecting successfully - // let stdout = String::from_utf8_lossy(&output.stdout); - let stdout = format!("Successfully connected to '{}'", ssid); - Status::new(stdout.to_string(), status) - } else { - let stderr = String::from_utf8_lossy(&output.stderr); - Status::new(stderr.to_string(), status) - } - } - Err(e) => Status::new( - format!("Failed to execute nmcli: {}", e), - ExitStatus::default(), - ), - } + handle_command_result(output, ssid) } diff --git a/src/utils/disconnect_connection.rs b/src/utils/disconnect_connection.rs index d32126a..20f674b 100644 --- a/src/utils/disconnect_connection.rs +++ b/src/utils/disconnect_connection.rs @@ -4,6 +4,29 @@ use std::{ sync::{Arc, RwLock}, }; +// handle the output of the command execution and return a Status object +fn handle_command_output(output: std::process::Output) -> Status { + let status = output.status; + if status.success() { + let stdout = String::from_utf8_lossy(&output.stdout); + Status::new(stdout.into(), status) + } else { + let stderr = String::from_utf8_lossy(&output.stderr); + Status::new(stderr.into(), status) + } +} + +// handle the result of the command execution and return a Status object +fn handle_command_result(result: Result) -> Status { + match result { + Ok(output) => handle_command_output(output), + Err(e) => Status::new( + format!("Failed to execute nmcli: {}", e), + ExitStatus::default(), + ), + } +} + pub fn disconnect_connected_network(wifi_list: Arc>>) -> Status { let list = wifi_list.read().expect("WifiNetworks lock poisoned"); @@ -13,23 +36,9 @@ pub fn disconnect_connected_network(wifi_list: Arc>>) -> let output = Command::new("nmcli") .args(["connection", "down", ssid]) .output(); - match output { - Ok(output) => { - let status = output.status; - if status.success() { - let stdout = String::from_utf8_lossy(&output.stdout); - return Status::new(stdout.into(), status); - } else { - let stderr = String::from_utf8_lossy(&output.stderr); - return Status::new(stderr.into(), status); - } - } - Err(e) => { - return Status::new( - format!("Failed to execute nmcli: {}", e), - ExitStatus::default(), - ); - } + let status = handle_command_result(output); + if status.status_code.success() { + return status; } } }