diff --git a/src/battery_tray.rs b/src/battery_tray.rs index a8afac3..907f762 100644 --- a/src/battery_tray.rs +++ b/src/battery_tray.rs @@ -1,10 +1,30 @@ -use ksni::{Tray, MenuItem, menu::{StandardItem}, ToolTip}; +use hyper_x_cloud_ii_wireless::Device; +use ksni::{Tray, MenuItem, menu::{StandardItem}, ToolTip, TrayService, Handle}; + +pub struct TrayHandler { + handle: Handle, +} + +impl TrayHandler { + pub fn new() -> Self { + let tray_service = TrayService::new(BatteryTray::new()); + let handle = tray_service.handle(); + tray_service.spawn(); + TrayHandler { + handle, + } + } + + pub fn update(&self, device: &Device) { + self.handle.update(|tray: &mut BatteryTray| { tray.update(device); }) + } +} #[derive(Debug)] pub struct BatteryTray { battery_level: u8, charging: bool, - device_found: bool, + status_message: Option, } impl BatteryTray { @@ -12,18 +32,21 @@ impl BatteryTray { BatteryTray { battery_level: 0, charging: false, - device_found: false, + status_message: Some("No device found".to_string()), } } - pub fn update(&mut self, battery_level: u8, charging: bool) { - self.device_found = true; - self.battery_level = battery_level; - self.charging = charging; + pub fn update(&mut self, device: &Device) { + self.battery_level = device.battery_level; + self.charging = device.charging; } - pub fn no_device_found(&mut self) { - self.device_found = false; + pub fn set_status_message(&mut self, message: &str) { + self.status_message = Some(message.to_string()); + } + + pub fn clear_status_message(&mut self) { + self.status_message = None; } } @@ -43,17 +66,20 @@ impl Tray for BatteryTray { ] } fn tool_tip(&self) -> ToolTip { - let description = - if !self.device_found { - "No device found".to_string() - } else if self.charging { + let status = + match &self.status_message { + Some(m) => m, + None => "", + }; + let state = + if self.charging { format!("Battery level: {}%\nCharging", self.battery_level) } else { format!("Battery level: {}%\nNot charging", self.battery_level) }; ToolTip { title: "HyperX Cloud II".to_string(), - description: description, + description: format!("{}\n{}", status, state), icon_name: "".into(), icon_pixmap: Vec::new(), } diff --git a/src/bin/cli_app.rs b/src/bin/cli_app.rs index 8d15ea8..423d131 100644 --- a/src/bin/cli_app.rs +++ b/src/bin/cli_app.rs @@ -1,14 +1,14 @@ use hyper_x_cloud_ii_wireless::Device; fn main() { - let device = match Device::new() { + let mut device = match Device::new() { Ok(device) => device, Err(error) => { eprintln!("{error}"); std::process::exit(1); } }; - let (battery_level, charging) = match device.get_battery_level() { + let (battery_level, _) = match device.update_battery_level() { Ok(t) => t, Err(error) => { eprintln!("{error}"); @@ -16,9 +16,4 @@ fn main() { } }; println!("Battery level: {}%", battery_level); - if charging { - println!("Charging"); - } else { - println!("Not charging"); - } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 64c55d3..33a18da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ +use std::time::Duration; + use hyper_x_cloud_ii_wireless::{Device, DeviceError}; -use ksni::TrayService; mod battery_tray; -use battery_tray::BatteryTray; +use battery_tray::TrayHandler; fn pair_device() -> Device { loop { @@ -15,41 +16,58 @@ fn pair_device() -> Device { } } -fn main() { - let service = TrayService::new(BatteryTray::new()); - let handle = service.handle(); - service.spawn(); +//TODO: status messages +//TODO: use mute state +//TODO: make trayHandler dynamic +fn handle_error(error: DeviceError, device: &mut Device, tray_handler: &TrayHandler) { + match error { + DeviceError::HidError(hidapi::HidError::HidApiError { message }) => { + if message == "No such device" { + eprintln!("No device found."); + // handle.update(|tray: &mut BatteryTray| { tray.set_status_message("No device found"); }); + *device = pair_device(); + } else { + eprintln!("{message}"); + } + } + DeviceError::NoDeviceFound() => { + eprintln!("{}", DeviceError::NoDeviceFound()); + // handle.update(|tray: &mut BatteryTray| { tray.set_status_message("No device found"); }); + } + DeviceError::HeadSetOff() => { + eprintln!("{}", DeviceError::HeadSetOff()); + // handle.update(|tray: &mut BatteryTray| { tray.set_status_message(&DeviceError::HeadSetOff().to_string()); }); + } + error => { + eprintln!("{error}"); + } + } +} + +fn main() { + let tray_handler = TrayHandler::new(); let mut device = pair_device(); + tray_handler.update(&device); // Run loop loop { std::thread::sleep(std::time::Duration::from_secs(1)); - let (battery_level, charging) = match device.get_battery_level() { - Ok(t) => t, - Err(DeviceError::HidError(hidapi::HidError::HidApiError { message })) => { - eprintln!("Error: {message}"); - if message == "No such device" { - handle.update(|tray: &mut BatteryTray| { tray.no_device_found(); }); - device = pair_device(); - } - continue; - } - Err(DeviceError::NoDeviceFound()) => { - eprintln!("{}", DeviceError::NoDeviceFound()); - handle.update(|tray: &mut BatteryTray| { tray.no_device_found(); }); - continue; - } - Err(DeviceError::HeadSetOff()) => { - eprintln!("{}", DeviceError::HeadSetOff()); - handle.update(|tray: &mut BatteryTray| { tray.no_device_found(); }); - continue; - } + match device.update_battery_level() { + Ok(_) => { + tray_handler.update(&device); + }, Err(error) => { - eprintln!("{error}"); + handle_error(error, &mut device, &tray_handler); + continue; + }, + }; + match device.wait_for_updates(Duration::from_secs(30)) { + Ok(_) => tray_handler.update(&device), + Err(error) => { + handle_error(error, &mut device, &tray_handler); continue; } - }; - handle.update(|tray: &mut BatteryTray| { tray.update(battery_level, charging); }); + } } }