mirror of
https://github.com/house-of-vanity/khm.git
synced 2025-08-22 06:27:15 +00:00
Fixed build workflow
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
use crate::gui::common::{perform_sync, KhmSettings};
|
||||
use log::{error, info};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tray_icon::{
|
||||
menu::{Menu, MenuItem, MenuId},
|
||||
menu::{Menu, MenuId, MenuItem},
|
||||
TrayIcon, TrayIconBuilder,
|
||||
};
|
||||
use crate::gui::common::{KhmSettings, perform_sync};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SyncStatus {
|
||||
@@ -30,21 +30,26 @@ pub struct TrayMenuIds {
|
||||
}
|
||||
|
||||
/// Create tray icon with menu
|
||||
pub fn create_tray_icon(settings: &KhmSettings, sync_status: &SyncStatus) -> (TrayIcon, TrayMenuIds) {
|
||||
pub fn create_tray_icon(
|
||||
settings: &KhmSettings,
|
||||
sync_status: &SyncStatus,
|
||||
) -> (TrayIcon, TrayMenuIds) {
|
||||
// Create simple blue icon
|
||||
let icon_data: Vec<u8> = (0..32*32).flat_map(|i| {
|
||||
let y = i / 32;
|
||||
let x = i % 32;
|
||||
if x < 2 || x >= 30 || y < 2 || y >= 30 {
|
||||
[255, 255, 255, 255] // White border
|
||||
} else {
|
||||
[64, 128, 255, 255] // Blue center
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let icon_data: Vec<u8> = (0..32 * 32)
|
||||
.flat_map(|i| {
|
||||
let y = i / 32;
|
||||
let x = i % 32;
|
||||
if x < 2 || x >= 30 || y < 2 || y >= 30 {
|
||||
[255, 255, 255, 255] // White border
|
||||
} else {
|
||||
[64, 128, 255, 255] // Blue center
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let icon = tray_icon::Icon::from_rgba(icon_data, 32, 32).unwrap();
|
||||
let menu = Menu::new();
|
||||
|
||||
|
||||
// Show current configuration status (static)
|
||||
let host_text = if settings.host.is_empty() {
|
||||
"Host: Not configured"
|
||||
@@ -52,64 +57,75 @@ pub fn create_tray_icon(settings: &KhmSettings, sync_status: &SyncStatus) -> (Tr
|
||||
&format!("Host: {}", settings.host)
|
||||
};
|
||||
menu.append(&MenuItem::new(host_text, false, None)).unwrap();
|
||||
|
||||
|
||||
let flow_text = if settings.flow.is_empty() {
|
||||
"Flow: Not configured"
|
||||
} else {
|
||||
&format!("Flow: {}", settings.flow)
|
||||
};
|
||||
menu.append(&MenuItem::new(flow_text, false, None)).unwrap();
|
||||
|
||||
let is_auto_sync_enabled = !settings.host.is_empty() && !settings.flow.is_empty() && settings.in_place;
|
||||
let sync_text = format!("Auto sync: {} ({}min)",
|
||||
if is_auto_sync_enabled { "On" } else { "Off" },
|
||||
settings.auto_sync_interval_minutes);
|
||||
menu.append(&MenuItem::new(&sync_text, false, None)).unwrap();
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator()).unwrap();
|
||||
|
||||
|
||||
let is_auto_sync_enabled =
|
||||
!settings.host.is_empty() && !settings.flow.is_empty() && settings.in_place;
|
||||
let sync_text = format!(
|
||||
"Auto sync: {} ({}min)",
|
||||
if is_auto_sync_enabled { "On" } else { "Off" },
|
||||
settings.auto_sync_interval_minutes
|
||||
);
|
||||
menu.append(&MenuItem::new(&sync_text, false, None))
|
||||
.unwrap();
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator())
|
||||
.unwrap();
|
||||
|
||||
// Sync Now menu item
|
||||
let sync_item = MenuItem::new("Sync Now", !settings.host.is_empty() && !settings.flow.is_empty(), None);
|
||||
let sync_item = MenuItem::new(
|
||||
"Sync Now",
|
||||
!settings.host.is_empty() && !settings.flow.is_empty(),
|
||||
None,
|
||||
);
|
||||
let sync_id = sync_item.id().clone();
|
||||
menu.append(&sync_item).unwrap();
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator()).unwrap();
|
||||
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator())
|
||||
.unwrap();
|
||||
|
||||
// Settings menu item
|
||||
let settings_item = MenuItem::new("Settings", true, None);
|
||||
let settings_id = settings_item.id().clone();
|
||||
menu.append(&settings_item).unwrap();
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator()).unwrap();
|
||||
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator())
|
||||
.unwrap();
|
||||
|
||||
// Quit menu item
|
||||
let quit_item = MenuItem::new("Quit", true, None);
|
||||
let quit_id = quit_item.id().clone();
|
||||
menu.append(&quit_item).unwrap();
|
||||
|
||||
|
||||
// Create initial tooltip
|
||||
let tooltip = create_tooltip(settings, sync_status);
|
||||
|
||||
|
||||
let tray_icon = TrayIconBuilder::new()
|
||||
.with_tooltip(&tooltip)
|
||||
.with_icon(icon)
|
||||
.with_menu(Box::new(menu))
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
|
||||
let menu_ids = TrayMenuIds {
|
||||
settings_id,
|
||||
quit_id,
|
||||
sync_id,
|
||||
};
|
||||
|
||||
|
||||
(tray_icon, menu_ids)
|
||||
}
|
||||
|
||||
/// Update tray menu with new settings
|
||||
pub fn update_tray_menu(tray_icon: &TrayIcon, settings: &KhmSettings) -> TrayMenuIds {
|
||||
let menu = Menu::new();
|
||||
|
||||
|
||||
// Show current configuration status (static)
|
||||
let host_text = if settings.host.is_empty() {
|
||||
"Host: Not configured"
|
||||
@@ -117,43 +133,54 @@ pub fn update_tray_menu(tray_icon: &TrayIcon, settings: &KhmSettings) -> TrayMen
|
||||
&format!("Host: {}", settings.host)
|
||||
};
|
||||
menu.append(&MenuItem::new(host_text, false, None)).unwrap();
|
||||
|
||||
|
||||
let flow_text = if settings.flow.is_empty() {
|
||||
"Flow: Not configured"
|
||||
} else {
|
||||
&format!("Flow: {}", settings.flow)
|
||||
};
|
||||
menu.append(&MenuItem::new(flow_text, false, None)).unwrap();
|
||||
|
||||
let is_auto_sync_enabled = !settings.host.is_empty() && !settings.flow.is_empty() && settings.in_place;
|
||||
let sync_text = format!("Auto sync: {} ({}min)",
|
||||
if is_auto_sync_enabled { "On" } else { "Off" },
|
||||
settings.auto_sync_interval_minutes);
|
||||
menu.append(&MenuItem::new(&sync_text, false, None)).unwrap();
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator()).unwrap();
|
||||
|
||||
|
||||
let is_auto_sync_enabled =
|
||||
!settings.host.is_empty() && !settings.flow.is_empty() && settings.in_place;
|
||||
let sync_text = format!(
|
||||
"Auto sync: {} ({}min)",
|
||||
if is_auto_sync_enabled { "On" } else { "Off" },
|
||||
settings.auto_sync_interval_minutes
|
||||
);
|
||||
menu.append(&MenuItem::new(&sync_text, false, None))
|
||||
.unwrap();
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator())
|
||||
.unwrap();
|
||||
|
||||
// Sync Now menu item
|
||||
let sync_item = MenuItem::new("Sync Now", !settings.host.is_empty() && !settings.flow.is_empty(), None);
|
||||
let sync_item = MenuItem::new(
|
||||
"Sync Now",
|
||||
!settings.host.is_empty() && !settings.flow.is_empty(),
|
||||
None,
|
||||
);
|
||||
let sync_id = sync_item.id().clone();
|
||||
menu.append(&sync_item).unwrap();
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator()).unwrap();
|
||||
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator())
|
||||
.unwrap();
|
||||
|
||||
// Settings menu item
|
||||
let settings_item = MenuItem::new("Settings", true, None);
|
||||
let settings_id = settings_item.id().clone();
|
||||
menu.append(&settings_item).unwrap();
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator()).unwrap();
|
||||
|
||||
|
||||
menu.append(&tray_icon::menu::PredefinedMenuItem::separator())
|
||||
.unwrap();
|
||||
|
||||
// Quit menu item
|
||||
let quit_item = MenuItem::new("Quit", true, None);
|
||||
let quit_id = quit_item.id().clone();
|
||||
menu.append(&quit_item).unwrap();
|
||||
|
||||
|
||||
tray_icon.set_menu(Some(Box::new(menu)));
|
||||
|
||||
|
||||
TrayMenuIds {
|
||||
settings_id,
|
||||
quit_id,
|
||||
@@ -163,14 +190,17 @@ pub fn update_tray_menu(tray_icon: &TrayIcon, settings: &KhmSettings) -> TrayMen
|
||||
|
||||
/// Create tooltip text for tray icon
|
||||
pub fn create_tooltip(settings: &KhmSettings, sync_status: &SyncStatus) -> String {
|
||||
let mut tooltip = format!("KHM - SSH Key Manager\nHost: {}\nFlow: {}", settings.host, settings.flow);
|
||||
|
||||
let mut tooltip = format!(
|
||||
"KHM - SSH Key Manager\nHost: {}\nFlow: {}",
|
||||
settings.host, settings.flow
|
||||
);
|
||||
|
||||
if let Some(keys_count) = sync_status.last_sync_keys {
|
||||
tooltip.push_str(&format!("\nLast sync: {} keys", keys_count));
|
||||
} else {
|
||||
tooltip.push_str("\nLast sync: Never");
|
||||
}
|
||||
|
||||
|
||||
if let Some(seconds) = sync_status.next_sync_in_seconds {
|
||||
if seconds > 60 {
|
||||
tooltip.push_str(&format!("\nNext sync: {}m {}s", seconds / 60, seconds % 60));
|
||||
@@ -178,7 +208,7 @@ pub fn create_tooltip(settings: &KhmSettings, sync_status: &SyncStatus) -> Strin
|
||||
tooltip.push_str(&format!("\nNext sync: {}s", seconds));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tooltip
|
||||
}
|
||||
|
||||
@@ -186,18 +216,24 @@ pub fn create_tooltip(settings: &KhmSettings, sync_status: &SyncStatus) -> Strin
|
||||
pub fn start_auto_sync_task(
|
||||
settings: Arc<Mutex<KhmSettings>>,
|
||||
sync_status: Arc<Mutex<SyncStatus>>,
|
||||
event_sender: winit::event_loop::EventLoopProxy<crate::gui::UserEvent>
|
||||
event_sender: winit::event_loop::EventLoopProxy<crate::gui::UserEvent>,
|
||||
) -> Option<std::thread::JoinHandle<()>> {
|
||||
let initial_settings = settings.lock().unwrap().clone();
|
||||
|
||||
|
||||
// Only start auto sync if settings are valid and in_place is enabled
|
||||
if initial_settings.host.is_empty() || initial_settings.flow.is_empty() || !initial_settings.in_place {
|
||||
if initial_settings.host.is_empty()
|
||||
|| initial_settings.flow.is_empty()
|
||||
|| !initial_settings.in_place
|
||||
{
|
||||
info!("Auto sync disabled or settings invalid");
|
||||
return None;
|
||||
}
|
||||
|
||||
info!("Starting auto sync with interval {} minutes", initial_settings.auto_sync_interval_minutes);
|
||||
|
||||
|
||||
info!(
|
||||
"Starting auto sync with interval {} minutes",
|
||||
initial_settings.auto_sync_interval_minutes
|
||||
);
|
||||
|
||||
let handle = std::thread::spawn(move || {
|
||||
// Initial sync on startup
|
||||
info!("Performing initial sync on startup");
|
||||
@@ -207,7 +243,10 @@ pub fn start_auto_sync_task(
|
||||
rt.block_on(async {
|
||||
match perform_sync(¤t_settings).await {
|
||||
Ok(keys_count) => {
|
||||
info!("Initial sync completed successfully with {} keys", keys_count);
|
||||
info!(
|
||||
"Initial sync completed successfully with {} keys",
|
||||
keys_count
|
||||
);
|
||||
let mut status = sync_status.lock().unwrap();
|
||||
status.last_sync_time = Some(std::time::Instant::now());
|
||||
status.last_sync_keys = Some(keys_count);
|
||||
@@ -219,27 +258,28 @@ pub fn start_auto_sync_task(
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Start menu update timer
|
||||
let timer_sender = event_sender.clone();
|
||||
std::thread::spawn(move || {
|
||||
loop {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
let _ = timer_sender.send_event(crate::gui::UserEvent::UpdateMenu);
|
||||
}
|
||||
std::thread::spawn(move || loop {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
let _ = timer_sender.send_event(crate::gui::UserEvent::UpdateMenu);
|
||||
});
|
||||
|
||||
|
||||
// Periodic sync
|
||||
loop {
|
||||
let interval_minutes = current_settings.auto_sync_interval_minutes;
|
||||
std::thread::sleep(std::time::Duration::from_secs(interval_minutes as u64 * 60));
|
||||
|
||||
|
||||
let current_settings = settings.lock().unwrap().clone();
|
||||
if current_settings.host.is_empty() || current_settings.flow.is_empty() || !current_settings.in_place {
|
||||
if current_settings.host.is_empty()
|
||||
|| current_settings.flow.is_empty()
|
||||
|| !current_settings.in_place
|
||||
{
|
||||
info!("Auto sync stopped due to invalid settings or disabled in_place");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
info!("Performing scheduled auto sync");
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
@@ -258,7 +298,7 @@ pub fn start_auto_sync_task(
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Some(handle)
|
||||
}
|
||||
|
||||
@@ -268,7 +308,7 @@ pub fn update_sync_status(settings: &KhmSettings, sync_status: &mut SyncStatus)
|
||||
if let Some(last_sync) = sync_status.last_sync_time {
|
||||
let elapsed = last_sync.elapsed().as_secs();
|
||||
let interval_seconds = settings.auto_sync_interval_minutes as u64 * 60;
|
||||
|
||||
|
||||
if elapsed < interval_seconds {
|
||||
sync_status.next_sync_in_seconds = Some(interval_seconds - elapsed);
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user