v0.1.0-pre.045

This commit is contained in:
2026-07-25 18:35:51 +02:00
parent c2dbd207d3
commit 01764a485a
9 changed files with 329 additions and 132 deletions

View File

@@ -1,5 +1,5 @@
// file: kb-app-demo-desktop/src/lib.rs
// version: 1
// version: 2
//! Tauri desktop demo application for `khadhroony-bot3`.
@@ -9,85 +9,23 @@
mod constants;
mod splash;
use tauri::Manager; // rust-rules: trait-import
mod tauri;
/// Runs the desktop demo application.
pub async fn run() -> kb_core::Result<()> {
let builder = tauri::Builder::default().setup(|app| {
let splash_window = match app.get_webview_window("splash") {
std::option::Option::Some(window) => window,
std::option::Option::None => {
return std::result::Result::Err(std::boxed::Box::new(std::io::Error::new(
std::io::ErrorKind::NotFound,
"splash window is missing",
)));
},
};
let main_window = match app.get_webview_window("main") {
std::option::Option::Some(window) => window,
std::option::Option::None => {
return std::result::Result::Err(std::boxed::Box::new(std::io::Error::new(
std::io::ErrorKind::NotFound,
"main window is missing",
)));
},
};
tauri::async_runtime::spawn(async move {
let started_at = tokio::time::Instant::now();
crate::emit_splash_order(
&splash_window,
"fadein",
std::option::Option::None,
std::option::Option::None,
std::option::Option::Some(crate::SPLASH_FADE_MS),
);
crate::emit_splash_order(
&splash_window,
"add_msg",
std::option::Option::Some("Initialisation de Khadhroony Bot3..."),
std::option::Option::Some("info"),
std::option::Option::None,
);
crate::wait_until_minimum(started_at, crate::SPLASH_MINIMUM_MS).await;
crate::emit_splash_order(
&splash_window,
"fadeout",
std::option::Option::None,
std::option::Option::None,
std::option::Option::Some(crate::SPLASH_FADE_MS),
);
tokio::time::sleep(std::time::Duration::from_millis(crate::SPLASH_CLOSE_WAIT_MS)).await;
if let std::result::Result::Err(error) = splash_window.destroy() {
tracing::error!(target: crate::TRACING_TARGET, "cannot destroy splash window: {error:?}");
}
if let std::result::Result::Err(error) = main_window.show() {
tracing::error!(target: crate::TRACING_TARGET, "cannot show main window: {error:?}");
}
if let std::result::Result::Err(error) = main_window.set_focus() {
tracing::error!(target: crate::TRACING_TARGET, "cannot focus main window: {error:?}");
}
});
return std::result::Result::Ok(());
});
let run_result = builder.run(tauri::generate_context!());
return match run_result {
std::result::Result::Ok(()) => std::result::Result::Ok(()),
std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::tauri(format!(
"cannot run desktop demo application: {error:?}"
))),
};
}
pub use self::tauri::run;
/// Minimum startup splash duration before fade-out begins.
pub(crate) use self::splash::SPLASH_MINIMUM_MS;
/// Splash fade duration.
pub(crate) use self::splash::SPLASH_FADE_MS;
/// Delay after fade-out before destroying the splash window.
pub(crate) use self::splash::SPLASH_CLOSE_WAIT_MS;
/// Splash fade duration.
pub(crate) use self::splash::SPLASH_FADE_MS;
/// Minimum startup splash duration before fade-out begins.
pub(crate) use self::splash::SPLASH_MINIMUM_MS;
/// Command sent from Rust to the splash frontend.
pub(crate) use self::splash::SplashOrder;
/// Emits one order to the splash frontend.
pub(crate) use self::splash::emit_splash_order;
/// Waits for the minimum splash duration.
pub(crate) use self::splash::wait_until_minimum;
// Keep the canonical tracing target as the final facade export.
/// Canonical tracing target for the desktop demo application.
pub(crate) use self::constants::TRACING_TARGET;

View File

@@ -31,7 +31,7 @@ async fn main() -> std::process::ExitCode {
return std::process::ExitCode::FAILURE;
}
let _lock_file = lock_file;
let run_result = kb_app_demo_desktop::run().await;
let run_result = kb_app_demo_desktop_lib::run();
return match run_result {
std::result::Result::Ok(()) => std::process::ExitCode::SUCCESS,
std::result::Result::Err(error) => {

View File

@@ -7,11 +7,11 @@ 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;
pub(crate) const SPLASH_MINIMUM_MS: u64 = 3100;
/// Splash fade duration.
pub(crate) const SPLASH_FADE_MS: u32 = 500;
pub(crate) const SPLASH_FADE_MS: u32 = 3000;
/// Delay after fade-out before destroying the splash window.
pub(crate) const SPLASH_CLOSE_WAIT_MS: u64 = 550;
pub(crate) const SPLASH_CLOSE_WAIT_MS: u64 = 3100;
/// Command sent from Rust to the splash frontend.
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, TS)]
@@ -35,7 +35,7 @@ pub(crate) fn emit_splash_order(
status: std::option::Option<&str>,
duration_ms: std::option::Option<u32>,
) {
let payload = SplashOrder {
let payload = crate::SplashOrder {
order: order.to_string(),
msg: msg.map(std::string::ToString::to_string),
status: status.map(std::string::ToString::to_string),
@@ -61,7 +61,7 @@ pub(crate) async fn wait_until_minimum(start: tokio::time::Instant, minimum_ms:
mod tests {
#[test]
fn splash_order_serializes_duration_ms() {
let order = super::SplashOrder {
let order = crate::SplashOrder {
order: "fadein".to_string(),
msg: std::option::Option::None,
status: std::option::Option::None,

View File

@@ -0,0 +1,73 @@
// file: kb-app-demo-desktop/src/tauri.rs
// version: 1
//! Tauri runtime assembly and private command wrappers.
use tauri::Manager; // rust-rules: trait-import
/// Runs the desktop demo application.
pub fn run() -> kb_core::Result<()> {
let builder = tauri::Builder::default().setup(|app| {
let splash_window = match app.get_webview_window("splash") {
std::option::Option::Some(window) => window,
std::option::Option::None => {
return std::result::Result::Err(std::boxed::Box::new(std::io::Error::new(
std::io::ErrorKind::NotFound,
"splash window is missing",
)));
},
};
let main_window = match app.get_webview_window("main") {
std::option::Option::Some(window) => window,
std::option::Option::None => {
return std::result::Result::Err(std::boxed::Box::new(std::io::Error::new(
std::io::ErrorKind::NotFound,
"main window is missing",
)));
},
};
tauri::async_runtime::spawn(async move {
let started_at = tokio::time::Instant::now();
crate::emit_splash_order(
&splash_window,
"fadein",
std::option::Option::None,
std::option::Option::None,
std::option::Option::Some(crate::SPLASH_FADE_MS),
);
crate::emit_splash_order(
&splash_window,
"add_msg",
std::option::Option::Some("Initialisation de Khadhroony Bot3..."),
std::option::Option::Some("info"),
std::option::Option::None,
);
crate::wait_until_minimum(started_at, crate::SPLASH_MINIMUM_MS).await;
crate::emit_splash_order(
&splash_window,
"fadeout",
std::option::Option::None,
std::option::Option::None,
std::option::Option::Some(crate::SPLASH_FADE_MS),
);
tokio::time::sleep(std::time::Duration::from_millis(crate::SPLASH_CLOSE_WAIT_MS)).await;
if let std::result::Result::Err(error) = splash_window.destroy() {
tracing::error!(target: crate::TRACING_TARGET, "cannot destroy splash window: {error:?}");
}
if let std::result::Result::Err(error) = main_window.show() {
tracing::error!(target: crate::TRACING_TARGET, "cannot show main window: {error:?}");
}
if let std::result::Result::Err(error) = main_window.set_focus() {
tracing::error!(target: crate::TRACING_TARGET, "cannot focus main window: {error:?}");
}
});
return std::result::Result::Ok(());
});
let run_result = builder.run(tauri::generate_context!());
return match run_result {
std::result::Result::Ok(()) => std::result::Result::Ok(()),
std::result::Result::Err(error) => std::result::Result::Err(kb_core::Error::tauri(format!(
"cannot run desktop demo application: {error:?}"
))),
};
}