diff --git a/src/battery_tray.rs b/src/battery_tray.rs index d74e989..5690529 100644 --- a/src/battery_tray.rs +++ b/src/battery_tray.rs @@ -1,5 +1,6 @@ -use hyper_x_cloud_ii_wireless::Device; -use ksni::{Tray, MenuItem, menu::{StandardItem}, ToolTip, TrayService, Handle}; +use hyper_x_cloud_ii_wireless::devices::{Device, DeviceState}; +use ksni::{menu::StandardItem, Handle, MenuItem, ToolTip, Tray, TrayService}; +use std::sync::{Arc, RwLock, RwLockReadGuard}; pub struct TrayHandler { handle: Handle, @@ -10,58 +11,35 @@ impl TrayHandler { let tray_service = TrayService::new(tray); let handle = tray_service.handle(); tray_service.spawn(); - TrayHandler { - handle, - } + TrayHandler { handle } } - pub fn update(&self, device: &Device) { - self.handle.update(|tray: &mut BatteryTray| { tray.update(device); }) - } - - pub fn set_status(&mut self, message: &str) { - self.handle.update(|tray: &mut BatteryTray| { tray.set_status(message); }) - } - - pub fn clear_status(&mut self) { - self.handle.update(|tray: &mut BatteryTray| { tray.clear_status(); }) + pub fn update(&self, device_state: &DeviceState) { + let message = if device_state.connected.unwrap_or(false) { + Some(device_state.to_string()) + } else { + None + }; + let name = device_state.device_name.clone(); + self.handle.update(|tray| { + tray.message = message; + tray.device_name = name; + }) } } -#[derive(Debug)] pub struct BatteryTray { - battery_level: u8, - charging: Option, - muted: Option, - mic_connected: Option, - status_message: Option, + device_name: Option, + message: Option, } impl BatteryTray { pub fn new() -> Self { BatteryTray { - battery_level: 0, - charging: None, - muted: None, - mic_connected: None, - status_message: Some("No device found".to_string()), + device_name: None, + message: None, } } - - pub fn update(&mut self, device: &Device) { - self.battery_level = device.battery_level; - self.charging = device.charging; - self.muted = device.muted; - self.mic_connected = device.mic_connected; - } - - pub fn set_status(&mut self, message: &str) { - self.status_message = Some(message.to_string()); - } - - pub fn clear_status(&mut self) { - self.status_message = None; - } } impl Tray for BatteryTray { @@ -72,71 +50,45 @@ impl Tray for BatteryTray { "audio-headset".into() } fn tool_tip(&self) -> ToolTip { - let description = match &self.status_message { - Some(m) => m.clone(), - None => { - let mut description = format!("Battery level: {}%", self.battery_level); - if let Some(charging) = self.charging { - if charging { - description += "\nCharging"; - } else { - description += "\nNot charging"; - } - } - if let Some(muted) = self.muted { - if muted { - description += "\nMuted"; - } else { - description += "\nNot muted"; - } - } - if let Some(mic_connected) = self.mic_connected { - if mic_connected { - description += "\nMicrophone connected"; - } else { - description += "\nMicrophone not connected"; - } - } - description - }, + println!("tool_tip"); + let description = if let Some(message) = self.message.clone() { + message + } else { + "Headset is not connected".to_string() }; ToolTip { - title: "HyperX Cloud II".to_string(), + title: self.device_name.clone().unwrap_or("Unknown".to_string()), description, icon_name: "audio-headset".into(), icon_pixmap: Vec::new(), } } fn menu(&self) -> Vec> { - let mut items = vec![ - StandardItem { - label: format!("Battery level: {bat}% ({crg})", bat = self.battery_level,crg = (if self.charging.is_some() { "Charging" } else {"Discharging"})), - enabled: false, - ..Default::default() - } - .into(), - StandardItem { - label: "Exit".into(), - icon_name: "application-exit".into(), - activate: Box::new(|_| std::process::exit(0)), - ..Default::default() - } - .into(), - ]; - if let Some(muted) = self.muted { - items.insert(1, StandardItem { - label: if muted { "Muted" } else { "Not muted" }.into(), - enabled: false, - ..Default::default() - }.into()); - } - if let Some(mic_connected) = self.mic_connected { - items.insert(2, StandardItem { - label: if mic_connected { "Microphone connected" } else { "Microphone not connected" }.into(), - enabled: false, - ..Default::default() - }.into()); - } - items + println!("menu"); + let message = if let Some(message) = &self.message { + message + } else { + &"Headset is not connected".to_string() + }; + + let mut state_items: Vec> = message + .lines() + .map(|line| { + StandardItem { + label: line.to_string(), + enabled: false, + ..Default::default() + } + .into() + }) + .collect(); + let exit = StandardItem { + label: "Exit".into(), + icon_name: "application-exit".into(), + activate: Box::new(|_| std::process::exit(0)), + ..Default::default() + }; + state_items.push(exit.into()); + state_items } } diff --git a/src/main.rs b/src/main.rs index 0c92be7..0e97123 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,78 +1,48 @@ +use std::sync::{Arc, RwLock}; use std::time::Duration; -use hyper_x_cloud_ii_wireless::{Device, DeviceError}; mod battery_tray; -use battery_tray::{TrayHandler, BatteryTray}; +use battery_tray::{BatteryTray, TrayHandler}; +use hyper_x_cloud_ii_wireless::devices::{connect_compatible_device, Device, DeviceError}; -fn pair_device() -> Device { - loop { - match Device::new() { - Ok(device) => break device, - Err(error) => { - eprintln!("{error}"); - } - }; - std::thread::sleep(std::time::Duration::from_secs(1)); - } -} - -fn handle_error(error: DeviceError, device: &mut Device, tray_handler: &mut TrayHandler) { +fn handle_error(error: DeviceError) -> String { match error { DeviceError::HidError(hidapi::HidError::HidApiError { message }) => { if message == "No such device" { eprintln!("No device found."); - tray_handler.set_status("No device found."); - *device = pair_device(); + "No such device".to_string() } else { eprintln!("{message}"); + message } } - DeviceError::NoDeviceFound() => { - eprintln!("{}", DeviceError::NoDeviceFound()); - device.clear_state(); - tray_handler.update(device); - tray_handler.set_status( &DeviceError::NoDeviceFound().to_string()); - } - DeviceError::HeadSetOff() => { - eprintln!("{}", DeviceError::HeadSetOff()); - device.clear_state(); - tray_handler.update(device); - tray_handler.set_status(&DeviceError::HeadSetOff().to_string()); - } error => { eprintln!("{error}"); + error.to_string() } } } fn main() { - let mut tray_handler = TrayHandler::new(BatteryTray::new()); - let mut device = pair_device(); - tray_handler.update(&device); + let mut device = loop { + match connect_compatible_device() { + Ok(d) => break d, + Err(e) => println!("Connecting failed with error: {e}"), + } + std::thread::sleep(Duration::from_secs(1)); + }; + + let tray_handler = TrayHandler::new(BatteryTray::new()); // Run loop loop { - std::thread::sleep(std::time::Duration::from_secs(1)); - match device.update_battery_level() { - Ok(_) => { - tray_handler.clear_status(); - tray_handler.update(&device); - }, + std::thread::sleep(Duration::from_secs(1)); + match device.refresh_state() { + Ok(()) => (), Err(error) => { - handle_error(error, &mut device, &mut tray_handler); - continue; - }, - }; - match device.wait_for_updates(Duration::from_secs(60)) { - Ok(_) => { - tray_handler.clear_status(); - tray_handler.update(&device) - }, - Err(DeviceError::NoResponse()) => (), - Err(error) => { - handle_error(error, &mut device, &mut tray_handler); - continue; + eprintln!("{}", error); } - } + }; + tray_handler.update(device.get_device_state()) } }