From 25606934acd9721182e8d37b764edd883b4fbd3e Mon Sep 17 00:00:00 2001 From: Aashish Thapa Date: Sun, 15 Feb 2026 01:05:36 -0600 Subject: [PATCH 1/5] fix: fix navigation bug when connecting to ethernet --- src/handler.rs | 140 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 108 insertions(+), 32 deletions(-) diff --git a/src/handler.rs b/src/handler.rs index 7ffc0f1..9a94414 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -68,12 +68,22 @@ pub async fn toggle_connect(app: &mut App, sender: UnboundedSender) -> Re FocusedBlock::KnownNetworks => match &station.connected_network { Some(connected_net) => { if let Some(selected_net_index) = station.known_networks_state.selected() { - if selected_net_index > station.known_networks.len() - 1 { - // Can not connect to unavailble network + let ethernet_offset = + if station.is_ethernet_connected { 1 } else { 0 }; + + if selected_net_index < ethernet_offset { + // Ethernet row selected — no-op return Ok(()); } - let (selected_net, _signal) = &station.known_networks[selected_net_index]; + let data_index = selected_net_index - ethernet_offset; + + if data_index >= station.known_networks.len() { + // Can not connect to unavailable network + return Ok(()); + } + + let (selected_net, _signal) = &station.known_networks[data_index]; if selected_net.name == connected_net.name { station.disconnect(sender.clone()).await?; @@ -96,11 +106,21 @@ pub async fn toggle_connect(app: &mut App, sender: UnboundedSender) -> Re } None => { if let Some(selected_net_index) = station.known_networks_state.selected() { - if selected_net_index > station.known_networks.len() - 1 { - // Can not connect to unavailble network + let ethernet_offset = + if station.is_ethernet_connected { 1 } else { 0 }; + + if selected_net_index < ethernet_offset { + // Ethernet row selected — no-op return Ok(()); } - let (selected_net, _signal) = &station.known_networks[selected_net_index]; + + let data_index = selected_net_index - ethernet_offset; + + if data_index >= station.known_networks.len() { + // Can not connect to unavailable network + return Ok(()); + } + let (selected_net, _signal) = &station.known_networks[data_index]; let net_index = station .known_networks .iter() @@ -564,10 +584,22 @@ pub async fn handle_key_events( if let Some(net_index) = station.known_networks_state.selected() { - if net_index > station.known_networks.len() - 1 { - let index = net_index.saturating_sub( - station.known_networks.len(), - ); + let ethernet_offset = + if station.is_ethernet_connected { + 1 + } else { + 0 + }; + + if net_index < ethernet_offset { + // Ethernet row — no-op + } else if net_index - ethernet_offset + >= station.known_networks.len() + { + let index = (net_index - ethernet_offset) + .saturating_sub( + station.known_networks.len(), + ); let network = &station.unavailable_known_networks[index]; // Check if it's a PSK network (WPA/WPA2/WPA3) @@ -588,8 +620,10 @@ pub async fn handle_key_events( FocusedBlock::ShareNetwork; } } else { + let data_index = + net_index - ethernet_offset; let (network, _) = - &station.known_networks[net_index]; + &station.known_networks[data_index]; // Check if it's a PSK network (WPA/WPA2/WPA3) if matches!( network.network_type, @@ -618,16 +652,30 @@ pub async fn handle_key_events( if let Some(net_index) = station.known_networks_state.selected() { - if net_index > station.known_networks.len() - 1 { - let index = net_index.saturating_sub( - station.known_networks.len(), - ); + let ethernet_offset = + if station.is_ethernet_connected { + 1 + } else { + 0 + }; + + if net_index < ethernet_offset { + // Ethernet row — no-op + } else if net_index - ethernet_offset + >= station.known_networks.len() + { + let index = (net_index - ethernet_offset) + .saturating_sub( + station.known_networks.len(), + ); let network = &station.unavailable_known_networks[index]; network.forget(sender.clone()).await?; } else { + let data_index = + net_index - ethernet_offset; let (net, _signal) = - &station.known_networks[net_index]; + &station.known_networks[data_index]; if let Some(known_net) = &net.known_network { known_net.forget(sender.clone()).await?; @@ -643,12 +691,23 @@ pub async fn handle_key_events( .known_network .toggle_autoconnect => { + let ethernet_offset = + if station.is_ethernet_connected { + 1 + } else { + 0 + }; + if let Some(net_index) = station.known_networks_state.selected() - && net_index < station.known_networks.len() + && net_index >= ethernet_offset + && net_index - ethernet_offset + < station.known_networks.len() { + let data_index = + net_index - ethernet_offset; let (net, _) = - &mut station.known_networks[net_index]; + &mut station.known_networks[data_index]; if let Some(known_net) = &mut net.known_network { known_net @@ -702,22 +761,25 @@ pub async fn handle_key_events( // Scroll down KeyCode::Char('j') | KeyCode::Down => { - if !station.known_networks.is_empty() { + let ethernet_offset = + if station.is_ethernet_connected { + 1 + } else { + 0 + }; + let total_rows = ethernet_offset + + station.known_networks.len() + + if station.show_unavailable_known_networks { + station.unavailable_known_networks.len() + } else { + 0 + }; + + if total_rows > 0 { let i = match station.known_networks_state.selected() { Some(i) => { - let limit = if station - .show_unavailable_known_networks - { - station.known_networks.len() - + station - .unavailable_known_networks - .len() - - 1 - } else { - station.known_networks.len() - 1 - }; - + let limit = total_rows - 1; if i < limit { i + 1 } else { i } } None => 0, @@ -727,7 +789,21 @@ pub async fn handle_key_events( } } KeyCode::Char('k') | KeyCode::Up => { - if !station.known_networks.is_empty() { + let ethernet_offset = + if station.is_ethernet_connected { + 1 + } else { + 0 + }; + let total_rows = ethernet_offset + + station.known_networks.len() + + if station.show_unavailable_known_networks { + station.unavailable_known_networks.len() + } else { + 0 + }; + + if total_rows > 0 { let i = match station.known_networks_state.selected() { Some(i) => i.saturating_sub(1), From 43da63d63584da5ea685368af88e912d78a71565 Mon Sep 17 00:00:00 2001 From: Aashish Thapa Date: Sun, 15 Feb 2026 01:53:47 -0600 Subject: [PATCH 2/5] feat: resolve the current selected known network including ethernet --- src/mode/station.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/mode/station.rs b/src/mode/station.rs index c585ced..fda9fb1 100644 --- a/src/mode/station.rs +++ b/src/mode/station.rs @@ -28,6 +28,17 @@ use crate::{ use network::Network; +/// Result of resolving the selected known networks table index, +/// accounting for the ethernet row offset. +pub enum KnownNetworkSelection { + /// The ethernet row is selected (no-op for most actions) + Ethernet, + /// A known (visible) network at the given data index + Network(usize), + /// An unavailable (saved but not visible) network at the given index + Unavailable(usize), +} + /// Hidden network representation for NetworkManager #[derive(Debug, Clone)] pub struct HiddenNetwork { @@ -366,6 +377,40 @@ impl Station { Ok(()) } + /// Resolve the currently selected known networks table index to a typed selection, + /// accounting for the ethernet row offset and unavailable networks. + pub fn resolve_known_selection(&self) -> Option { + let selected = self.known_networks_state.selected()?; + let ethernet_offset = usize::from(self.is_ethernet_connected); + + if selected < ethernet_offset { + return Some(KnownNetworkSelection::Ethernet); + } + + let data_index = selected - ethernet_offset; + if data_index < self.known_networks.len() { + Some(KnownNetworkSelection::Network(data_index)) + } else { + let unavail_index = data_index - self.known_networks.len(); + if unavail_index < self.unavailable_known_networks.len() { + Some(KnownNetworkSelection::Unavailable(unavail_index)) + } else { + None + } + } + } + + /// Total number of rows in the known networks table (ethernet + known + unavailable). + pub fn known_networks_total_rows(&self) -> usize { + let ethernet_offset = usize::from(self.is_ethernet_connected); + let unavail = if self.show_unavailable_known_networks { + self.unavailable_known_networks.len() + } else { + 0 + }; + ethernet_offset + self.known_networks.len() + unavail + } + pub fn render( &mut self, frame: &mut Frame, From 468de7dafaa2349357ad70da58556b04d51eefbb Mon Sep 17 00:00:00 2001 From: Aashish Thapa Date: Sun, 15 Feb 2026 01:54:21 -0600 Subject: [PATCH 3/5] fix: remove redundancy and use knownnetworkselection --- src/handler.rs | 208 +++++++++++-------------------------------------- 1 file changed, 44 insertions(+), 164 deletions(-) diff --git a/src/handler.rs b/src/handler.rs index 9a94414..2a76c6e 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -8,6 +8,7 @@ use crate::event::Event; use crate::mode::ap::APFocusedSection; use crate::mode::station::share::Share; use crate::mode::station::speed_test::SpeedTest; +use crate::mode::station::KnownNetworkSelection; use crate::nm::{Mode, SecurityType}; use crate::notification::{self, Notification}; @@ -65,77 +66,30 @@ pub async fn toggle_connect(app: &mut App, sender: UnboundedSender) -> Re } } } - FocusedBlock::KnownNetworks => match &station.connected_network { - Some(connected_net) => { - if let Some(selected_net_index) = station.known_networks_state.selected() { - let ethernet_offset = - if station.is_ethernet_connected { 1 } else { 0 }; - - if selected_net_index < ethernet_offset { - // Ethernet row selected — no-op - return Ok(()); - } - - let data_index = selected_net_index - ethernet_offset; - - if data_index >= station.known_networks.len() { - // Can not connect to unavailable network - return Ok(()); - } - - let (selected_net, _signal) = &station.known_networks[data_index]; - - if selected_net.name == connected_net.name { + FocusedBlock::KnownNetworks => { + if let Some(KnownNetworkSelection::Network(data_index)) = + station.resolve_known_selection() + { + let (selected_net, _) = &station.known_networks[data_index]; + + let is_connected = station + .connected_network + .as_ref() + .is_some_and(|c| c.name == selected_net.name); + + if is_connected { + station.disconnect(sender.clone()).await?; + } else { + let (net, _) = station.known_networks[data_index].clone(); + if station.connected_network.is_some() { station.disconnect(sender.clone()).await?; - } else { - let net_index = station - .known_networks - .iter() - .position(|(n, _s)| n.name == selected_net.name); - - if let Some(index) = net_index { - let (net, _) = station.known_networks[index].clone(); - station.disconnect(sender.clone()).await?; - tokio::spawn(async move { - // Known networks already have saved credentials - let _ = net.connect(sender.clone(), None).await; - }); - } - } - } - } - None => { - if let Some(selected_net_index) = station.known_networks_state.selected() { - let ethernet_offset = - if station.is_ethernet_connected { 1 } else { 0 }; - - if selected_net_index < ethernet_offset { - // Ethernet row selected — no-op - return Ok(()); - } - - let data_index = selected_net_index - ethernet_offset; - - if data_index >= station.known_networks.len() { - // Can not connect to unavailable network - return Ok(()); - } - let (selected_net, _signal) = &station.known_networks[data_index]; - let net_index = station - .known_networks - .iter() - .position(|(n, _s)| n.name == selected_net.name); - - if let Some(index) = net_index { - let (net, _) = station.known_networks[index].clone(); - tokio::spawn(async move { - // Known networks already have saved credentials - let _ = net.connect(sender.clone(), None).await; - }); } + tokio::spawn(async move { + let _ = net.connect(sender.clone(), None).await; + }); } } - }, + } _ => {} } } @@ -581,28 +535,10 @@ pub async fn handle_key_events( KeyCode::Char(c) if c == config.station.known_network.share => { - if let Some(net_index) = - station.known_networks_state.selected() - { - let ethernet_offset = - if station.is_ethernet_connected { - 1 - } else { - 0 - }; - - if net_index < ethernet_offset { - // Ethernet row — no-op - } else if net_index - ethernet_offset - >= station.known_networks.len() - { - let index = (net_index - ethernet_offset) - .saturating_sub( - station.known_networks.len(), - ); + match station.resolve_known_selection() { + Some(KnownNetworkSelection::Unavailable(index)) => { let network = &station.unavailable_known_networks[index]; - // Check if it's a PSK network (WPA/WPA2/WPA3) if matches!( network.network_type, SecurityType::WPA @@ -619,12 +555,12 @@ pub async fn handle_key_events( app.focused_block = FocusedBlock::ShareNetwork; } - } else { - let data_index = - net_index - ethernet_offset; + } + Some(KnownNetworkSelection::Network( + data_index, + )) => { let (network, _) = &station.known_networks[data_index]; - // Check if it's a PSK network (WPA/WPA2/WPA3) if matches!( network.network_type, SecurityType::WPA @@ -643,44 +579,29 @@ pub async fn handle_key_events( FocusedBlock::ShareNetwork; } } + _ => {} } } // Remove a known network KeyCode::Char(c) if c == config.station.known_network.remove => { - if let Some(net_index) = - station.known_networks_state.selected() - { - let ethernet_offset = - if station.is_ethernet_connected { - 1 - } else { - 0 - }; - - if net_index < ethernet_offset { - // Ethernet row — no-op - } else if net_index - ethernet_offset - >= station.known_networks.len() - { - let index = (net_index - ethernet_offset) - .saturating_sub( - station.known_networks.len(), - ); + match station.resolve_known_selection() { + Some(KnownNetworkSelection::Unavailable(index)) => { let network = &station.unavailable_known_networks[index]; network.forget(sender.clone()).await?; - } else { - let data_index = - net_index - ethernet_offset; - let (net, _signal) = + } + Some(KnownNetworkSelection::Network( + data_index, + )) => { + let (net, _) = &station.known_networks[data_index]; - if let Some(known_net) = &net.known_network { known_net.forget(sender.clone()).await?; } } + _ => {} } } @@ -691,24 +612,12 @@ pub async fn handle_key_events( .known_network .toggle_autoconnect => { - let ethernet_offset = - if station.is_ethernet_connected { - 1 - } else { - 0 - }; - - if let Some(net_index) = - station.known_networks_state.selected() - && net_index >= ethernet_offset - && net_index - ethernet_offset - < station.known_networks.len() + if let Some(KnownNetworkSelection::Network( + data_index, + )) = station.resolve_known_selection() { - let data_index = - net_index - ethernet_offset; let (net, _) = &mut station.known_networks[data_index]; - if let Some(known_net) = &mut net.known_network { known_net .toggle_autoconnect(sender.clone()) @@ -761,55 +670,26 @@ pub async fn handle_key_events( // Scroll down KeyCode::Char('j') | KeyCode::Down => { - let ethernet_offset = - if station.is_ethernet_connected { - 1 - } else { - 0 - }; - let total_rows = ethernet_offset - + station.known_networks.len() - + if station.show_unavailable_known_networks { - station.unavailable_known_networks.len() - } else { - 0 - }; - - if total_rows > 0 { + let total = station.known_networks_total_rows(); + if total > 0 { let i = match station.known_networks_state.selected() { Some(i) => { - let limit = total_rows - 1; - if i < limit { i + 1 } else { i } + if i < total - 1 { i + 1 } else { i } } None => 0, }; - station.known_networks_state.select(Some(i)); } } KeyCode::Char('k') | KeyCode::Up => { - let ethernet_offset = - if station.is_ethernet_connected { - 1 - } else { - 0 - }; - let total_rows = ethernet_offset - + station.known_networks.len() - + if station.show_unavailable_known_networks { - station.unavailable_known_networks.len() - } else { - 0 - }; - - if total_rows > 0 { + let total = station.known_networks_total_rows(); + if total > 0 { let i = match station.known_networks_state.selected() { Some(i) => i.saturating_sub(1), None => 0, }; - station.known_networks_state.select(Some(i)); } } From f73ba813fca093977b421257cf21a28fdb90b034 Mon Sep 17 00:00:00 2001 From: Aashish Thapa Date: Sun, 15 Feb 2026 01:54:42 -0600 Subject: [PATCH 4/5] style: cargo format --- src/handler.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/handler.rs b/src/handler.rs index 2a76c6e..7e9ea9e 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -6,9 +6,9 @@ use crate::config::Config; use crate::device::Device; use crate::event::Event; use crate::mode::ap::APFocusedSection; +use crate::mode::station::KnownNetworkSelection; use crate::mode::station::share::Share; use crate::mode::station::speed_test::SpeedTest; -use crate::mode::station::KnownNetworkSelection; use crate::nm::{Mode, SecurityType}; use crate::notification::{self, Notification}; @@ -675,7 +675,11 @@ pub async fn handle_key_events( let i = match station.known_networks_state.selected() { Some(i) => { - if i < total - 1 { i + 1 } else { i } + if i < total - 1 { + i + 1 + } else { + i + } } None => 0, }; From e04640dfadd04260a574a4601232b40c22888f95 Mon Sep 17 00:00:00 2001 From: Aashish Thapa Date: Sun, 15 Feb 2026 17:27:51 -0600 Subject: [PATCH 5/5] style: simplify scroll-down index clamping --- src/handler.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/handler.rs b/src/handler.rs index 7e9ea9e..e71fe21 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -674,13 +674,7 @@ pub async fn handle_key_events( if total > 0 { let i = match station.known_networks_state.selected() { - Some(i) => { - if i < total - 1 { - i + 1 - } else { - i - } - } + Some(i) => (i + 1).min(total - 1), None => 0, }; station.known_networks_state.select(Some(i));