feat(bar): add activity to network widget

This commit is contained in:
LGUG2Z
2024-09-11 12:59:16 -07:00
parent 96a9cb320e
commit 42b7a13693
2 changed files with 172 additions and 87 deletions
+156 -81
View File
@@ -16,29 +16,53 @@ use sysinfo::Networks;
pub struct NetworkConfig { pub struct NetworkConfig {
/// Enable the Network widget /// Enable the Network widget
pub enable: bool, pub enable: bool,
/// Show network transfer data /// Show total data transmitted
pub show_data: bool, pub show_total_data_transmitted: bool,
/// Show network activity
pub show_network_activity: bool,
/// Data refresh interval (default: 10 seconds) /// Data refresh interval (default: 10 seconds)
pub data_refresh_interval: Option<u64>, pub data_refresh_interval: Option<u64>,
} }
impl From<NetworkConfig> for Network { impl From<NetworkConfig> for Network {
fn from(value: NetworkConfig) -> Self { fn from(value: NetworkConfig) -> Self {
let mut last_state = vec![]; let mut last_state_data = vec![];
let mut networks = Networks::new_with_refreshed_list(); let mut last_state_transmitted = vec![];
let mut networks_total_data_transmitted = Networks::new_with_refreshed_list();
let mut networks_network_activity = Networks::new_with_refreshed_list();
let mut default_interface = String::new();
if let Ok(interface) = netdev::get_default_interface() { if let Ok(interface) = netdev::get_default_interface() {
if let Some(friendly_name) = interface.friendly_name { if let Some(friendly_name) = interface.friendly_name {
last_state.push(friendly_name.clone()); default_interface.clone_from(&friendly_name);
if value.show_data { if value.show_total_data_transmitted {
networks.refresh(); networks_total_data_transmitted.refresh();
for (interface_name, data) in &networks { for (interface_name, data) in &networks_total_data_transmitted {
if friendly_name.eq(interface_name) { if friendly_name.eq(interface_name) {
last_state.push(format!( last_state_data.push(format!(
"{} MB (down) / {} MB (up)", "{} {:.0} MB / {} {:.0} MB",
data.total_received() / 1024 / 1024, egui_phosphor::regular::ARROW_CIRCLE_DOWN,
data.total_transmitted() / 1024 / 1024, (data.total_received() as f32) / 1024.0 / 1024.0,
egui_phosphor::regular::ARROW_CIRCLE_UP,
(data.total_transmitted() as f32) / 1024.0 / 1024.0,
))
}
}
}
if value.show_network_activity {
networks_network_activity.refresh();
for (interface_name, data) in &networks_network_activity {
if friendly_name.eq(interface_name) {
last_state_transmitted.push(format!(
"{} {:.1} KB/s / {} {:.1} KB/s",
egui_phosphor::regular::ARROW_CIRCLE_DOWN,
(data.received() as f32) / 1024.0 / 1.0,
egui_phosphor::regular::ARROW_CIRCLE_UP,
(data.transmitted() as f32) / 1024.0 / 1.0,
)) ))
} }
} }
@@ -48,44 +72,69 @@ impl From<NetworkConfig> for Network {
Self { Self {
enable: value.enable, enable: value.enable,
last_state, networks_total_data_transmitted,
networks, networks_network_activity,
default_interface,
data_refresh_interval: value.data_refresh_interval.unwrap_or(10), data_refresh_interval: value.data_refresh_interval.unwrap_or(10),
show_data: value.show_data, show_total_data_transmitted: value.show_total_data_transmitted,
last_updated: Instant::now(), show_network_activity: value.show_network_activity,
last_state_total_data_transmitted: last_state_data,
last_state_network_activity: last_state_transmitted,
last_updated_total_data_transmitted: Instant::now(),
last_updated_network_activity: Instant::now(),
} }
} }
} }
pub struct Network { pub struct Network {
pub enable: bool, pub enable: bool,
pub show_data: bool, pub show_total_data_transmitted: bool,
networks: Networks, pub show_network_activity: bool,
networks_total_data_transmitted: Networks,
networks_network_activity: Networks,
data_refresh_interval: u64, data_refresh_interval: u64,
last_state: Vec<String>, default_interface: String,
last_updated: Instant, last_state_total_data_transmitted: Vec<String>,
last_state_network_activity: Vec<String>,
last_updated_total_data_transmitted: Instant,
last_updated_network_activity: Instant,
} }
impl Network { impl Network {
fn output(&mut self) -> Vec<String> { fn default_interface(&mut self) {
let mut outputs = self.last_state.clone(); if let Ok(interface) = netdev::get_default_interface() {
if let Some(friendly_name) = &interface.friendly_name {
self.default_interface.clone_from(friendly_name);
}
}
}
fn network_activity(&mut self) -> Vec<String> {
let mut outputs = self.last_state_network_activity.clone();
let now = Instant::now(); let now = Instant::now();
if now.duration_since(self.last_updated) > Duration::from_secs(self.data_refresh_interval) {
if self.show_network_activity
&& now.duration_since(self.last_updated_network_activity)
> Duration::from_secs(self.data_refresh_interval)
{
outputs.clear(); outputs.clear();
if let Ok(interface) = netdev::get_default_interface() { if let Ok(interface) = netdev::get_default_interface() {
if let Some(friendly_name) = &interface.friendly_name { if let Some(friendly_name) = &interface.friendly_name {
outputs.push(friendly_name.clone()); if self.show_network_activity {
self.networks_network_activity.refresh();
if self.show_data { for (interface_name, data) in &self.networks_network_activity {
self.networks.refresh();
for (interface_name, data) in &self.networks {
if friendly_name.eq(interface_name) { if friendly_name.eq(interface_name) {
outputs.push(format!( outputs.push(format!(
"{} MB (down) / {} MB (up)", "{} {:.1} KB/s / {} {:.1} KB/s",
data.total_received() / 1024 / 1024, egui_phosphor::regular::ARROW_CIRCLE_DOWN,
data.total_transmitted() / 1024 / 1024, (data.received() as f32)
/ 1024.0
/ self.data_refresh_interval as f32,
egui_phosphor::regular::ARROW_CIRCLE_UP,
(data.transmitted() as f32)
/ 1024.0
/ self.data_refresh_interval as f32,
)) ))
} }
} }
@@ -93,8 +142,45 @@ impl Network {
} }
} }
self.last_state.clone_from(&outputs); self.last_state_network_activity.clone_from(&outputs);
self.last_updated = now; self.last_updated_network_activity = now;
}
outputs
}
fn total_data_transmitted(&mut self) -> Vec<String> {
let mut outputs = self.last_state_total_data_transmitted.clone();
let now = Instant::now();
if self.show_total_data_transmitted
&& now.duration_since(self.last_updated_total_data_transmitted)
> Duration::from_secs(self.data_refresh_interval)
{
outputs.clear();
if let Ok(interface) = netdev::get_default_interface() {
if let Some(friendly_name) = &interface.friendly_name {
if self.show_total_data_transmitted {
self.networks_total_data_transmitted.refresh();
for (interface_name, data) in &self.networks_total_data_transmitted {
if friendly_name.eq(interface_name) {
outputs.push(format!(
"{} {:.0} MB / {} {:.0} MB",
egui_phosphor::regular::ARROW_CIRCLE_DOWN,
(data.total_received() as f32) / 1024.0 / 1024.0,
egui_phosphor::regular::ARROW_CIRCLE_UP,
(data.total_transmitted() as f32) / 1024.0 / 1024.0,
))
}
}
}
}
}
self.last_state_total_data_transmitted.clone_from(&outputs);
self.last_updated_total_data_transmitted = now;
} }
outputs outputs
@@ -103,55 +189,44 @@ impl Network {
impl BarWidget for Network { impl BarWidget for Network {
fn render(&mut self, _ctx: &Context, ui: &mut Ui) { fn render(&mut self, _ctx: &Context, ui: &mut Ui) {
if self.enable { if self.show_total_data_transmitted {
let output = self.output(); for output in self.total_data_transmitted() {
ui.add(Label::new(output).selectable(false));
if !output.is_empty() {
match output.len() {
1 => {
if ui
.add(
Label::new(format!(
"{} {}",
egui_phosphor::regular::WIFI_HIGH,
output[0]
))
.selectable(false)
.sense(Sense::click()),
)
.clicked()
{
if let Err(error) = Command::new("cmd.exe").args(["/C", "ncpa"]).spawn()
{
eprintln!("{}", error)
}
}
}
2 => {
if ui
.add(
Label::new(format!(
"{} {} - {}",
egui_phosphor::regular::WIFI_HIGH,
output[0],
output[1]
))
.selectable(false)
.sense(Sense::click()),
)
.clicked()
{
if let Err(error) = Command::new("cmd.exe").args(["/C", "ncpa"]).spawn()
{
eprintln!("{}", error)
}
};
}
_ => {}
}
ui.add_space(WIDGET_SPACING);
} }
ui.add_space(WIDGET_SPACING);
}
if self.show_network_activity {
for output in self.network_activity() {
ui.add(Label::new(output).selectable(false));
}
ui.add_space(WIDGET_SPACING);
}
if self.enable {
self.default_interface();
if !self.default_interface.is_empty()
&& ui
.add(
Label::new(format!(
"{} {}",
egui_phosphor::regular::WIFI_HIGH,
self.default_interface
))
.selectable(false)
.sense(Sense::click()),
)
.clicked()
{
if let Err(error) = Command::new("cmd.exe").args(["/C", "ncpa"]).spawn() {
eprintln!("{}", error)
}
}
ui.add_space(WIDGET_SPACING);
} }
} }
} }
+16 -6
View File
@@ -267,7 +267,8 @@
"type": "object", "type": "object",
"required": [ "required": [
"enable", "enable",
"show_data" "show_network_activity",
"show_total_data_transmitted"
], ],
"properties": { "properties": {
"data_refresh_interval": { "data_refresh_interval": {
@@ -280,8 +281,12 @@
"description": "Enable the Network widget", "description": "Enable the Network widget",
"type": "boolean" "type": "boolean"
}, },
"show_data": { "show_network_activity": {
"description": "Show network transfer data", "description": "Show network activity",
"type": "boolean"
},
"show_total_data_transmitted": {
"description": "Show total data transmitted",
"type": "boolean" "type": "boolean"
} }
} }
@@ -646,7 +651,8 @@
"type": "object", "type": "object",
"required": [ "required": [
"enable", "enable",
"show_data" "show_network_activity",
"show_total_data_transmitted"
], ],
"properties": { "properties": {
"data_refresh_interval": { "data_refresh_interval": {
@@ -659,8 +665,12 @@
"description": "Enable the Network widget", "description": "Enable the Network widget",
"type": "boolean" "type": "boolean"
}, },
"show_data": { "show_network_activity": {
"description": "Show network transfer data", "description": "Show network activity",
"type": "boolean"
},
"show_total_data_transmitted": {
"description": "Show total data transmitted",
"type": "boolean" "type": "boolean"
} }
} }