Update app logic
This commit is contained in:
parent
a3d29d3d84
commit
3def319f58
3 changed files with 76 additions and 48 deletions
10
Cargo.toml
10
Cargo.toml
|
|
@ -13,7 +13,7 @@ categories = ["gui", "network-programming"]
|
|||
botlib = { workspace = true, features = ["http-client"] }
|
||||
|
||||
# Tauri
|
||||
tauri = { workspace = true }
|
||||
tauri = { workspace = true, features = ["tray-icon", "image"] }
|
||||
tauri-plugin-dialog = { workspace = true }
|
||||
tauri-plugin-opener = { workspace = true }
|
||||
|
||||
|
|
@ -26,22 +26,20 @@ env_logger = { workspace = true }
|
|||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
reqwest = { workspace = true, features = ["json"] }
|
||||
reqwest = { workspace = true, features = ["json", "rustls-tls"] }
|
||||
|
||||
# Unix process control
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc = { workspace = true }
|
||||
ksni = { workspace = true, optional = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
trayicon = { workspace = true, optional = true }
|
||||
image = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["desktop"]
|
||||
desktop = []
|
||||
desktop-tray = ["dep:ksni", "dep:trayicon"]
|
||||
desktop = ["desktop-tray"]
|
||||
desktop-tray = []
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -3,12 +3,27 @@ use anyhow::Result;
|
|||
use serde::Serialize;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use tauri::AppHandle;
|
||||
use tauri::tray::{TrayIcon, TrayIconBuilder};
|
||||
use tauri::menu::{Menu, MenuItem};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub struct TrayManager {
|
||||
hostname: Arc<RwLock<Option<String>>>,
|
||||
running_mode: RunningMode,
|
||||
tray_active: Arc<RwLock<bool>>,
|
||||
#[cfg(feature = "desktop-tray")]
|
||||
tray_handle: Arc<std::sync::Mutex<Option<TrayIcon>>>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for TrayManager {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("TrayManager")
|
||||
.field("hostname", &self.hostname)
|
||||
.field("running_mode", &self.running_mode)
|
||||
.field("tray_active", &self.tray_active)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
|
|
@ -33,6 +48,8 @@ impl TrayManager {
|
|||
hostname: Arc::new(RwLock::new(None)),
|
||||
running_mode: RunningMode::Desktop,
|
||||
tray_active: Arc::new(RwLock::new(false)),
|
||||
#[cfg(feature = "desktop-tray")]
|
||||
tray_handle: Arc::new(std::sync::Mutex::new(None)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,71 +59,83 @@ impl TrayManager {
|
|||
hostname: Arc::new(RwLock::new(None)),
|
||||
running_mode: mode,
|
||||
tray_active: Arc::new(RwLock::new(false)),
|
||||
#[cfg(feature = "desktop-tray")]
|
||||
tray_handle: Arc::new(std::sync::Mutex::new(None)),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn start(&self) -> Result<()> {
|
||||
pub async fn start(&self, app: &AppHandle) -> Result<()> {
|
||||
match self.running_mode {
|
||||
RunningMode::Desktop => {
|
||||
self.start_desktop_mode().await?;
|
||||
self.start_desktop_mode(app).await?;
|
||||
}
|
||||
RunningMode::Server => {
|
||||
log::info!("Running in server mode - tray icon disabled");
|
||||
}
|
||||
RunningMode::Client => {
|
||||
self.start_client_mode().await;
|
||||
self.start_client_mode(app).await;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn start_desktop_mode(&self) -> Result<()> {
|
||||
pub async fn start_desktop_mode(&self, app: &AppHandle) -> Result<()> {
|
||||
log::info!("Starting desktop mode tray icon");
|
||||
let mut active = self.tray_active.write().await;
|
||||
*active = true;
|
||||
drop(active);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
self.setup_linux_tray();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
self.setup_windows_tray();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
self.setup_macos_tray();
|
||||
|
||||
self.setup_tray(app);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn start_client_mode(&self) {
|
||||
fn setup_tray(&self, app: &AppHandle) {
|
||||
#[cfg(feature = "desktop-tray")]
|
||||
{
|
||||
log::info!(
|
||||
"Initializing unified system tray via tauri::tray for mode: {:?}",
|
||||
self.running_mode
|
||||
);
|
||||
|
||||
let tray_menu = Menu::new(app).unwrap();
|
||||
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>).unwrap();
|
||||
let _ = tray_menu.append(&quit_i);
|
||||
|
||||
// Create a simple red icon
|
||||
let w = 32;
|
||||
let h = 32;
|
||||
let mut rgba = Vec::with_capacity((w * h * 4) as usize);
|
||||
for _ in 0..(w * h) {
|
||||
rgba.extend_from_slice(&[255, 0, 0, 255]); // Red
|
||||
}
|
||||
|
||||
let icon = tauri::image::Image::new_owned(rgba, w, h);
|
||||
|
||||
let tray_builder = TrayIconBuilder::with_id("main")
|
||||
.menu(&tray_menu)
|
||||
.tooltip("General Bots")
|
||||
.icon(icon);
|
||||
|
||||
match tray_builder.build(app) {
|
||||
Ok(tray) => {
|
||||
if let Ok(mut handle) = self.tray_handle.lock() {
|
||||
*handle = Some(tray);
|
||||
log::info!("Tray icon created successfully");
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to build tray icon: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn start_client_mode(&self, app: &AppHandle) {
|
||||
log::info!("Starting client mode with minimal tray");
|
||||
let mut active = self.tray_active.write().await;
|
||||
*active = true;
|
||||
drop(active);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn setup_linux_tray(&self) {
|
||||
log::info!(
|
||||
"Initializing Linux system tray via DBus/StatusNotifierItem for mode: {:?}",
|
||||
self.running_mode
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn setup_windows_tray(&self) {
|
||||
log::info!(
|
||||
"Initializing Windows system tray via Shell_NotifyIcon for mode: {:?}",
|
||||
self.running_mode
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn setup_macos_tray(&self) {
|
||||
log::info!(
|
||||
"Initializing macOS menu bar via NSStatusItem for mode: {:?}",
|
||||
self.running_mode
|
||||
);
|
||||
self.setup_tray(app);
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ async fn get_tray_status(tray: tauri::State<'_, TrayManager>) -> Result<bool, St
|
|||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn start_tray(tray: tauri::State<'_, TrayManager>) -> Result<(), String> {
|
||||
tray.start().await.map_err(|e| e.to_string())
|
||||
async fn start_tray(tray: tauri::State<'_, TrayManager>, app: tauri::AppHandle) -> Result<(), String> {
|
||||
tray.start(&app).await.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
|
@ -208,6 +208,7 @@ fn main() {
|
|||
info!("BotApp setup complete in {mode} mode");
|
||||
|
||||
let tray_clone = tray.inner().clone();
|
||||
let app_handle = app.handle().clone();
|
||||
std::thread::spawn(move || {
|
||||
let rt = match tokio::runtime::Runtime::new() {
|
||||
Ok(rt) => rt,
|
||||
|
|
@ -217,7 +218,7 @@ fn main() {
|
|||
}
|
||||
};
|
||||
rt.block_on(async {
|
||||
if let Err(e) = tray_clone.start().await {
|
||||
if let Err(e) = tray_clone.start(&app_handle).await {
|
||||
log::error!("Failed to start tray: {e}");
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue