-
Notifications
You must be signed in to change notification settings - Fork 167
feat(wifi): add search functionality for filtering WiFi networks #1592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -73,6 +73,8 @@ pub enum Message { | |||||||||||||||||
| ViewMore(Option<network_manager::SSID>), | ||||||||||||||||||
| /// Toggle WiFi access | ||||||||||||||||||
| WiFiEnable(bool), | ||||||||||||||||||
| /// Update search query for filtering networks | ||||||||||||||||||
| SearchQuery(String), | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| impl From<Message> for crate::app::Message { | ||||||||||||||||||
|
|
@@ -126,6 +128,8 @@ pub struct Page { | |||||||||||||||||
| qr_code_data: Option<widget::qr_code::Data>, | ||||||||||||||||||
| /// QR code context drawer state | ||||||||||||||||||
| qr_drawer: Option<QRCodeDrawer>, | ||||||||||||||||||
| /// Search query for filtering WiFi networks | ||||||||||||||||||
| search_query: String, | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| #[derive(Debug)] | ||||||||||||||||||
|
|
@@ -633,6 +637,10 @@ impl Page { | |||||||||||||||||
| self.active_device = Some(device); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| Message::SearchQuery(query) => { | ||||||||||||||||||
| self.search_query = query; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| Message::NetworkManagerConnect(conn) => { | ||||||||||||||||||
| return cosmic::task::batch(vec![ | ||||||||||||||||||
| self.connect(conn.clone()), | ||||||||||||||||||
|
|
@@ -767,6 +775,15 @@ fn devices_view() -> Section<crate::pages::Message> { | |||||||||||||||||
| .center_x(Length::Fill) | ||||||||||||||||||
| })); | ||||||||||||||||||
|
|
||||||||||||||||||
| if !state.airplane_mode { | ||||||||||||||||||
| let search_input = widget::search_input(fl!("type-to-search"), &page.search_query) | ||||||||||||||||||
| .on_input(Message::SearchQuery) | ||||||||||||||||||
| .on_clear(Message::SearchQuery(String::new())) | ||||||||||||||||||
| .apply(Element::from); | ||||||||||||||||||
|
|
||||||||||||||||||
| view = view.push(search_input); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| if !state.airplane_mode | ||||||||||||||||||
| && state.known_access_points.is_empty() | ||||||||||||||||||
| && state.wireless_access_points.is_empty() | ||||||||||||||||||
|
|
@@ -780,8 +797,53 @@ fn devices_view() -> Section<crate::pages::Message> { | |||||||||||||||||
| let mut has_known = false; | ||||||||||||||||||
| let mut has_visible = false; | ||||||||||||||||||
|
|
||||||||||||||||||
| // Filter networks based on search query | ||||||||||||||||||
| // Include both visible networks and known networks (even if not currently visible) | ||||||||||||||||||
| let search_query_lower = page.search_query.trim().to_lowercase(); | ||||||||||||||||||
| let filtered_networks: Vec<_> = if search_query_lower.is_empty() { | ||||||||||||||||||
| // When no search query, show all visible networks | ||||||||||||||||||
| state.wireless_access_points.iter().collect() | ||||||||||||||||||
| } else { | ||||||||||||||||||
| // When searching, include both visible and known networks that match | ||||||||||||||||||
| use std::collections::BTreeSet; | ||||||||||||||||||
| let mut seen_ssids = BTreeSet::new(); | ||||||||||||||||||
| let mut filtered = Vec::new(); | ||||||||||||||||||
|
|
||||||||||||||||||
| // First, add visible networks that match | ||||||||||||||||||
| for network in &state.wireless_access_points { | ||||||||||||||||||
| if network.ssid.as_ref().to_lowercase().contains(&search_query_lower) { | ||||||||||||||||||
| seen_ssids.insert(network.ssid.as_ref()); | ||||||||||||||||||
| filtered.push(network); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| // Then, add known networks that match and aren't already included | ||||||||||||||||||
| for network in &state.known_access_points { | ||||||||||||||||||
| if !seen_ssids.contains(network.ssid.as_ref()) | ||||||||||||||||||
| && network.ssid.as_ref().to_lowercase().contains(&search_query_lower) | ||||||||||||||||||
| { | ||||||||||||||||||
| filtered.push(network); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+820
to
+827
|
||||||||||||||||||
| // Then, add known networks that match and aren't already included | |
| for network in &state.known_access_points { | |
| if !seen_ssids.contains(network.ssid.as_ref()) | |
| && network.ssid.as_ref().to_lowercase().contains(&search_query_lower) | |
| { | |
| filtered.push(network); | |
| } | |
| } |
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The BTreeSet for tracking seen_ssids (lines 809, 815, 822) is unnecessary since you're only iterating through wireless_access_points, which shouldn't contain duplicate SSIDs. The second loop that checks seen_ssids (lines 821-827) is also redundant as explained in the previous comment.
The entire search logic can be simplified to just:
let filtered_networks: Vec<_> = state.wireless_access_points
.iter()
.filter(|network| network.ssid.as_ref().to_lowercase().contains(&search_query_lower))
.collect();
Copilot
AI
Dec 4, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "no networks found" message when search returns no results uses the same localization key (no-networks) as when there are genuinely no networks available. This could be confusing to users - they might think there are no networks at all rather than understanding their search didn't match any networks.
Consider adding a new localization key like no-matching-networks with text such as "No matching networks found" to make it clearer that this is a search result issue, not a lack of available networks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment states "Include both visible networks and known networks (even if not currently visible)" but this is inaccurate. Based on the NetworkManagerState implementation (subscriptions/network-manager/src/lib.rs:787-794),
known_access_pointsonly contains networks that are both known AND currently visible inwireless_access_points.The comment should be updated to reflect the actual behavior, such as:
// Filter visible networks based on search query