Update network display format to match CLAUDE.md specification
All checks were successful
Build and Release / build-and-release (push) Successful in 1m38s
All checks were successful
Build and Release / build-and-release (push) Successful in 1m38s
Nest IP addresses under physical interface names. Show physical interfaces with status icon on header line. Virtual interfaces show inline with compressed IPs. Format: ● eno1: ├─ ip: 192.168.30.105 └─ tailscale0: 100.125.108.16 Version bump to 0.1.166
This commit is contained in:
@@ -628,60 +628,65 @@ impl SystemWidget {
|
||||
let physical: Vec<_> = self.network_interfaces.iter().filter(|i| i.is_physical).collect();
|
||||
let virtual_interfaces: Vec<_> = self.network_interfaces.iter().filter(|i| !i.is_physical).collect();
|
||||
|
||||
// Render physical interfaces first
|
||||
for (i, interface) in physical.iter().enumerate() {
|
||||
let is_last = i == physical.len() - 1 && virtual_interfaces.is_empty();
|
||||
let tree_symbol = if is_last { " └─ " } else { " ├─ " };
|
||||
// Render physical interfaces
|
||||
for (phy_idx, interface) in physical.iter().enumerate() {
|
||||
let is_last_physical = phy_idx == physical.len() - 1 && virtual_interfaces.is_empty();
|
||||
|
||||
// Show interface name with IPs
|
||||
let mut interface_text = format!("{}: ", interface.name);
|
||||
|
||||
// Add compressed IPv4 addresses
|
||||
if !interface.ipv4_addresses.is_empty() {
|
||||
interface_text.push_str(&Self::compress_ipv4_addresses(&interface.ipv4_addresses));
|
||||
}
|
||||
|
||||
// Add IPv6 addresses (no compression for now)
|
||||
if !interface.ipv6_addresses.is_empty() {
|
||||
if !interface.ipv4_addresses.is_empty() {
|
||||
interface_text.push_str(", ");
|
||||
}
|
||||
interface_text.push_str(&interface.ipv6_addresses.join(", "));
|
||||
}
|
||||
|
||||
// Physical interfaces show status icon
|
||||
let mut spans = vec![
|
||||
Span::styled(tree_symbol, Typography::tree()),
|
||||
];
|
||||
spans.extend(StatusIcons::create_status_spans(
|
||||
// Physical interface header with status icon
|
||||
let mut header_spans = vec![];
|
||||
header_spans.extend(StatusIcons::create_status_spans(
|
||||
interface.link_status.clone(),
|
||||
&interface_text
|
||||
&format!("{}:", interface.name)
|
||||
));
|
||||
lines.push(Line::from(spans));
|
||||
lines.push(Line::from(header_spans));
|
||||
|
||||
// Show IPs nested under the interface
|
||||
let ip_count = interface.ipv4_addresses.len() + interface.ipv6_addresses.len();
|
||||
let mut ip_index = 0;
|
||||
|
||||
// IPv4 addresses
|
||||
for ipv4 in &interface.ipv4_addresses {
|
||||
ip_index += 1;
|
||||
let is_last_ip = ip_index == ip_count && is_last_physical;
|
||||
let tree_symbol = if is_last_ip { " └─ " } else { " ├─ " };
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(tree_symbol, Typography::tree()),
|
||||
Span::styled(format!("ip: {}", ipv4), Typography::secondary()),
|
||||
]));
|
||||
}
|
||||
|
||||
// IPv6 addresses
|
||||
for ipv6 in &interface.ipv6_addresses {
|
||||
ip_index += 1;
|
||||
let is_last_ip = ip_index == ip_count && is_last_physical;
|
||||
let tree_symbol = if is_last_ip { " └─ " } else { " ├─ " };
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(tree_symbol, Typography::tree()),
|
||||
Span::styled(format!("ip: {}", ipv6), Typography::secondary()),
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
// Render virtual interfaces
|
||||
for (i, interface) in virtual_interfaces.iter().enumerate() {
|
||||
let is_last = i == virtual_interfaces.len() - 1;
|
||||
// Render standalone virtual interfaces (those without a parent)
|
||||
for (virt_idx, interface) in virtual_interfaces.iter().enumerate() {
|
||||
let is_last = virt_idx == virtual_interfaces.len() - 1;
|
||||
let tree_symbol = if is_last { " └─ " } else { " ├─ " };
|
||||
|
||||
// Show interface name with IPs
|
||||
let mut interface_text = format!("{}: ", interface.name);
|
||||
// Virtual interface with IPs
|
||||
let ip_text = if !interface.ipv4_addresses.is_empty() {
|
||||
Self::compress_ipv4_addresses(&interface.ipv4_addresses)
|
||||
} else if !interface.ipv6_addresses.is_empty() {
|
||||
interface.ipv6_addresses.join(", ")
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
// Add compressed IPv4 addresses
|
||||
if !interface.ipv4_addresses.is_empty() {
|
||||
interface_text.push_str(&Self::compress_ipv4_addresses(&interface.ipv4_addresses));
|
||||
}
|
||||
let interface_text = if !ip_text.is_empty() {
|
||||
format!("{}: {}", interface.name, ip_text)
|
||||
} else {
|
||||
format!("{}:", interface.name)
|
||||
};
|
||||
|
||||
// Add IPv6 addresses (no compression for now)
|
||||
if !interface.ipv6_addresses.is_empty() {
|
||||
if !interface.ipv4_addresses.is_empty() {
|
||||
interface_text.push_str(", ");
|
||||
}
|
||||
interface_text.push_str(&interface.ipv6_addresses.join(", "));
|
||||
}
|
||||
|
||||
// Virtual interfaces don't show status icon
|
||||
lines.push(Line::from(vec![
|
||||
Span::styled(tree_symbol, Typography::tree()),
|
||||
Span::styled(interface_text, Typography::secondary()),
|
||||
|
||||
Reference in New Issue
Block a user