Ziya/src/task/ui.rs
2025-07-08 14:57:51 +07:00

147 lines
5.6 KiB
Rust

use i_slint_backend_winit::WinitWindowAccessor;
use slint::Weak;
use tokio::task::JoinHandle;
use tokio_util::sync::CancellationToken;
use crate::error::Result;
use crate::get_current_unix_timestamp;
use crate::handler::ui::SlintHandlerUiOperator;
use crate::slint_ui::*;
use crate::{err_with_loc, error::app::AppError};
use std::sync::Arc;
use tracing::{error, info};
pub fn spawn_ui_task(
slint_handler: Arc<SlintHandlerUiOperator>,
ui_weak: Weak<MainWindow>,
cancellation_token: CancellationToken,
shutdown_tx: tokio::sync::mpsc::Sender<()>,
) -> JoinHandle<Result<()>> {
tokio::spawn(async move {
ui_weak
.clone()
.upgrade_in_event_loop(move |ui| {
// Window dragging
ui.on_start_drag_window({
let ui_weak = ui.as_weak();
move || {
let _ = ui_weak.upgrade_in_event_loop(|ui| {
let _ = ui.window().with_winit_window(
|winit_window: &winit::window::Window| {
let _ = winit_window.drag_window();
},
);
});
}
});
// Window minimize
ui.on_minimize_window({
let ui_weak = ui_weak.clone();
move || {
let _ = ui_weak.upgrade_in_event_loop(|ui| {
let _ = ui.window().with_winit_window(
|winit_window: &winit::window::Window| {
winit_window.set_minimized(true);
},
);
});
}
});
// Window maximize/restore
ui.on_maximize_window({
let ui_weak = ui_weak.clone();
move || {
let _ = ui_weak.upgrade_in_event_loop(|ui| {
let _ = ui.window().with_winit_window(
|winit_window: &winit::window::Window| {
let is_maximized = winit_window.is_maximized();
winit_window.set_maximized(!is_maximized);
},
);
});
}
});
// Theme toggle
ui.on_theme_toggle_clicked({
let ui_weak = ui_weak.clone();
move || {
let _ = ui_weak.upgrade_in_event_loop(|ui| {
ui.invoke_toggle_theme();
info!("Theme toggled");
});
}
});
// Navigation callback
ui.on_navigation_changed({
move |page| {
info!("Navigation changed to: {}", page);
}
});
let new_tokens_handler = slint_handler.clone();
ui.on_clear_new_tokens(move || {
let handler = new_tokens_handler.clone();
handler.clear_new_tokens();
});
let cex_tokens_handler = slint_handler.clone();
ui.on_clear_cex_tokens(move || {
let handler = cex_tokens_handler.clone();
handler.clear_cex_tokens();
});
let analysis_tokens_handler = slint_handler.clone();
ui.on_clear_analysis_tokens(move || {
let handler = analysis_tokens_handler.clone();
handler.clear_analysis_tokens();
});
// Other callbacks (placeholder implementations)
ui.on_logout_clicked({
move || {
info!("Logout clicked");
}
});
// Window close - with proper task cleanup
ui.on_close_window({
let ui_weak = ui_weak.clone();
let shutdown_tx = shutdown_tx.clone();
let cancellation_token = cancellation_token.clone();
move || {
let _ = ui_weak.upgrade_in_event_loop({
let shutdown_tx = shutdown_tx.clone();
let cancellation_token = cancellation_token.clone();
move |ui| {
info!("close_window::shutting_down_all_tasks");
// Signal shutdown to all subscriber tasks
cancellation_token.cancel();
// Hide window immediately for responsive UI
let _ = ui.window().hide();
// Send shutdown signal
let _ = shutdown_tx.try_send(());
info!("close_window::all_tasks_cleaned_up");
// Quit the event loop after cleanup
let _ = slint::quit_event_loop();
}
});
}
});
})
.map_err(|e| {
error!("failed_to_setup_ui_callbacks: {}", e);
err_with_loc!(AppError::Slint(format!(
"failed_to_setup_ui_callbacks: {}",
e
)))
})
})
}