Files
khadhroony-bot3/kb-app-demo-desktop/src/splash.rs
2026-07-25 18:07:51 +02:00

85 lines
3.0 KiB
Rust

// file: kb-app-demo-desktop/src/splash.rs
// version: 1
//! Splash-window payloads and startup sequencing helpers.
use tauri::Emitter; // rust-rules: trait-import
use ts_rs::TS; // rust-rules: derive-import
/// Minimum splash duration before the main window is shown.
pub(crate) const SPLASH_MINIMUM_MS: u64 = 900;
/// Splash fade duration.
pub(crate) const SPLASH_FADE_MS: u32 = 500;
/// Delay after fade-out before destroying the splash window.
pub(crate) const SPLASH_CLOSE_WAIT_MS: u64 = 550;
/// Command sent from Rust to the splash frontend.
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, TS)]
#[ts(export, export_to = "../frontend/ts/bindings/kb_app_demo_desktop/splash/SplashOrder.ts")]
pub(crate) struct SplashOrder {
/// Command name.
pub(crate) order: std::string::String,
/// Optional message.
pub(crate) msg: std::option::Option<std::string::String>,
/// Optional status.
pub(crate) status: std::option::Option<std::string::String>,
/// Optional animation duration in milliseconds.
pub(crate) duration_ms: std::option::Option<u32>,
}
/// Emits one splash command.
pub(crate) fn emit_splash_order(
splash_window: &tauri::WebviewWindow,
order: &str,
msg: std::option::Option<&str>,
status: std::option::Option<&str>,
duration_ms: std::option::Option<u32>,
) {
let payload = SplashOrder {
order: order.to_string(),
msg: msg.map(std::string::ToString::to_string),
status: status.map(std::string::ToString::to_string),
duration_ms,
};
let emit_result = splash_window.emit("splash", payload);
if let std::result::Result::Err(error) = emit_result {
tracing::error!(target: crate::TRACING_TARGET, "cannot emit splash order '{order}': {error:?}");
}
}
/// Waits until the configured minimum splash duration has elapsed.
pub(crate) async fn wait_until_minimum(start: tokio::time::Instant, minimum_ms: u64) {
let minimum = std::time::Duration::from_millis(minimum_ms);
let elapsed = start.elapsed();
if elapsed >= minimum {
return;
}
tokio::time::sleep(minimum - elapsed).await;
}
#[cfg(test)]
mod tests {
#[test]
fn splash_order_serializes_duration_ms() {
let order = super::SplashOrder {
order: "fadein".to_string(),
msg: std::option::Option::None,
status: std::option::Option::None,
duration_ms: std::option::Option::Some(500),
};
let value_result = serde_json::to_value(order);
let value = match value_result {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => panic!("cannot serialize splash order: {error}"),
};
assert_eq!(value["duration_ms"], serde_json::json!(500));
}
#[test]
fn splash_timing_is_ordered() {
assert!(super::SPLASH_MINIMUM_MS > 0);
assert!(super::SPLASH_FADE_MS > 0);
assert!(super::SPLASH_CLOSE_WAIT_MS >= u64::from(super::SPLASH_FADE_MS));
}
}