fix: dupe connection names; incorrect ipv6 labeling

Fixes a bug where we showed `Activated` networks after the current active
one.

Also ipv4/6 addresses were merged so this seperates them and only shows ipv4
for now until we decide the best way to show both, UI/UX wise.
This commit is contained in:
Akrm Al-Hakimi 2026-07-01 19:32:48 -04:00 • committed by Jacob Kauffmann
parent e318f0d412
commit a3be51560f

View file

@ -167,18 +167,21 @@ pub enum ActiveConnectionInfo {
name: String, name: String,
hw_address: String, hw_address: String,
speed: u32, speed: u32,
ip_addresses: Vec<String>, ip4_address: Option<String>,
ip6_address: Option<String>,
}, },
WiFi { WiFi {
name: String, name: String,
ip_addresses: Vec<String>, ip4_address: Option<String>,
ip6_address: Option<String>,
state: ActiveConnectionState, state: ActiveConnectionState,
strength: u8, strength: u8,
hw_address: String, hw_address: String,
}, },
Vpn { Vpn {
name: String, name: String,
ip_addresses: Vec<String>, ip4_address: Option<String>,
ip6_address: Option<String>,
}, },
} }
@ -447,8 +450,15 @@ fn vpn_section<'a>(
vpn_col vpn_col
} }
fn ip_addresses(ip4_address: Option<String>, ip6_address: Option<String>) -> Vec<String> { fn ip_address_elements<'a>(
ip4_address.into_iter().chain(ip6_address).collect() ip4_address: &Option<String>,
_ip6_address: &Option<String>,
) -> Vec<Element<'a, Message>> {
let mut elements = Vec::with_capacity(1);
if let Some(addr) = ip4_address {
elements.push(text(format!("{}: {}", fl!("ipv4"), addr)).size(12).into());
}
elements
} }
fn network_type(security: nmrs::SecurityFeatures) -> NetworkType { fn network_type(security: nmrs::SecurityFeatures) -> NetworkType {
@ -599,18 +609,21 @@ fn snapshot_to_applet(snapshot: NetworkSnapshot) -> AppletSnapshot {
name: wired.id.clone(), name: wired.id.clone(),
hw_address: wired.hw_address.clone().unwrap_or_default(), hw_address: wired.hw_address.clone().unwrap_or_default(),
speed: wired.speed_mbps.unwrap_or_default(), speed: wired.speed_mbps.unwrap_or_default(),
ip_addresses: ip_addresses(wired.ip4_address.clone(), wired.ip6_address.clone()), ip4_address: wired.ip4_address.clone(),
ip6_address: wired.ip6_address.clone(),
}), }),
ActiveConnection::Wifi(wifi) => Some(ActiveConnectionInfo::WiFi { ActiveConnection::Wifi(wifi) => Some(ActiveConnectionInfo::WiFi {
name: wifi.ssid.clone(), name: wifi.ssid.clone(),
ip_addresses: ip_addresses(wifi.ip4_address.clone(), wifi.ip6_address.clone()), ip4_address: wifi.ip4_address.clone(),
ip6_address: wifi.ip6_address.clone(),
state: wifi.state, state: wifi.state,
strength: wifi.strength.unwrap_or_default(), strength: wifi.strength.unwrap_or_default(),
hw_address: wifi.bssid.clone().unwrap_or_default(), hw_address: wifi.bssid.clone().unwrap_or_default(),
}), }),
ActiveConnection::Vpn(vpn) => Some(ActiveConnectionInfo::Vpn { ActiveConnection::Vpn(vpn) => Some(ActiveConnectionInfo::Vpn {
name: vpn.id.clone(), name: vpn.id.clone(),
ip_addresses: ip_addresses(vpn.ip4_address.clone(), vpn.ip6_address.clone()), ip4_address: vpn.ip4_address.clone(),
ip6_address: vpn.ip6_address.clone(),
}), }),
ActiveConnection::Other(_) | _ => None, ActiveConnection::Other(_) | _ => None,
}) })
@ -1457,16 +1470,20 @@ impl cosmic::Application for CosmicNetworkApplet {
let mut known_wifi = Vec::new(); let mut known_wifi = Vec::new();
for conn in &self.nm_state.nm_state.active_conns { for conn in &self.nm_state.nm_state.active_conns {
match conn { match conn {
ActiveConnectionInfo::Vpn { name, ip_addresses } => { ActiveConnectionInfo::Vpn {
name,
ip4_address,
ip6_address,
} => {
if self.active_device.as_ref().is_some_and(|d| { if self.active_device.as_ref().is_some_and(|d| {
d.active_connection.as_ref().is_none_or(|a| a.0.id != *name) d.active_connection.as_ref().is_none_or(|a| a.0.id != *name)
}) { }) {
continue; continue;
} }
let mut ipv4 = Vec::with_capacity(ip_addresses.len() + 1); let mut info_col = Vec::with_capacity(3);
ipv4.push(text::body(name).into()); info_col.push(text::body(name).into());
for addr in ip_addresses { for elem in ip_address_elements(ip4_address, ip6_address) {
ipv4.push(text::caption(format!("{}: {}", fl!("ipv4"), addr)).into()); info_col.push(elem);
} }
vpn_ethernet_col = vpn_ethernet_col.push( vpn_ethernet_col = vpn_ethernet_col.push(
column::with_capacity::<Message, cosmic::Theme, _>(2) column::with_capacity::<Message, cosmic::Theme, _>(2)
@ -1480,7 +1497,7 @@ impl cosmic::Application for CosmicNetworkApplet {
) )
.size(40), .size(40),
), ),
column::with_children(ipv4).into(), column::with_children(info_col).into(),
text::body(fl!("connected")) text::body(fl!("connected"))
.width(Length::Fill) .width(Length::Fill)
.align_x(Alignment::End) .align_x(Alignment::End)
@ -1500,18 +1517,17 @@ impl cosmic::Application for CosmicNetworkApplet {
name, name,
hw_address: _, hw_address: _,
speed, speed,
ip_addresses, ip4_address,
ip6_address,
} => { } => {
if self.active_device.as_ref().is_some_and(|d| { if self.active_device.as_ref().is_some_and(|d| {
d.active_connection.as_ref().is_none_or(|a| a.0.id != *name) d.active_connection.as_ref().is_none_or(|a| a.0.id != *name)
}) { }) {
continue; continue;
} }
let mut ipv4 = Vec::with_capacity(ip_addresses.len() + 1); let mut info_col = Vec::with_capacity(3);
ipv4.push(text::body(name).into()); info_col.push(text::body(name).into());
for addr in ip_addresses { info_col.extend(ip_address_elements(ip4_address, ip6_address));
ipv4.push(text(format!("{}: {}", fl!("ipv4"), addr)).size(12).into());
}
let mut right_column = vec![text::body(fl!("connected")).into()]; let mut right_column = vec![text::body(fl!("connected")).into()];
@ -1549,7 +1565,7 @@ impl cosmic::Application for CosmicNetworkApplet {
) )
.size(40), .size(40),
), ),
column::with_children(ipv4).into(), column::with_children(info_col).into(),
column::with_children(right_column) column::with_children(right_column)
.width(Length::Fill) .width(Length::Fill)
.align_x(Alignment::End) .align_x(Alignment::End)
@ -1567,7 +1583,8 @@ impl cosmic::Application for CosmicNetworkApplet {
} }
ActiveConnectionInfo::WiFi { ActiveConnectionInfo::WiFi {
name, name,
ip_addresses, ip4_address,
ip6_address,
state, state,
strength, strength,
hw_address, hw_address,
@ -1577,10 +1594,7 @@ impl cosmic::Application for CosmicNetworkApplet {
}) { }) {
continue; continue;
} }
let mut ipv4 = Vec::with_capacity(ip_addresses.len()); let ip_elements = ip_address_elements(ip4_address, ip6_address);
for addr in ip_addresses {
ipv4.push(text(format!("{}: {}", fl!("ipv4"), addr)).size(12).into());
}
let mut btn_content = vec![ let mut btn_content = vec![
icon::from_name(wifi_icon(*strength)) icon::from_name(wifi_icon(*strength))
.size(24) .size(24)
@ -1588,7 +1602,7 @@ impl cosmic::Application for CosmicNetworkApplet {
.into(), .into(),
column::with_children([ column::with_children([
text::body(name).into(), text::body(name).into(),
column::with_children(ipv4).into(), column::with_children(ip_elements).into(),
]) ])
.width(Length::Fill) .width(Length::Fill)
.into(), .into(),
@ -1785,6 +1799,9 @@ impl cosmic::Application for CosmicNetworkApplet {
} }
for known in &self.nm_state.nm_state.known_access_points { for known in &self.nm_state.nm_state.known_access_points {
if matches!(known.state, DeviceState::Activated) {
continue;
}
if let Some(active_device) = self.active_device.as_ref() if let Some(active_device) = self.active_device.as_ref()
&& active_device && active_device
.known_connections .known_connections