v0.2.6-pre.014
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-wallet-desk/src/app_state.rs
|
||||
// version: 17
|
||||
// version: 18
|
||||
|
||||
//! Shared backend state owned by the Wallet Desk Tauri application.
|
||||
|
||||
@@ -57,7 +57,7 @@ impl AppState {
|
||||
crate::SplashSettings::fallback()
|
||||
},
|
||||
};
|
||||
ksp_logging_lib::debug!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WINDOWS, minimum_ms = splash_settings.minimum_ms(), minimum_source = splash_settings.minimum_source(), fade_ms = splash_settings.fade_ms(), fade_source = splash_settings.fade_source(), expected_backend_lifecycle_ms = splash_settings.expected_backend_lifecycle_ms(), "resolved Wallet Desk splash timings");
|
||||
ksp_logging_lib::debug!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WINDOWS, minimum_ms = splash_settings.minimum_ms(), minimum_source = splash_settings.minimum_source(), fade_in_ms = splash_settings.fade_in_ms(), fade_in_source = splash_settings.fade_in_source(), fade_out_ms = splash_settings.fade_out_ms(), fade_out_source = splash_settings.fade_out_source(), expected_backend_lifecycle_ms = splash_settings.expected_backend_lifecycle_ms(), "resolved Wallet Desk splash timings");
|
||||
return std::result::Result::Ok(Self {
|
||||
config_management,
|
||||
logging_runtime: std::sync::Mutex::new(LoggingRuntimeState {
|
||||
@@ -126,7 +126,7 @@ impl AppState {
|
||||
effective_wallets_directory_created_on_startup: self.wallet_config_startup.effective_directory_created_on_startup(),
|
||||
fallback_logging_active: runtime.fallback_active,
|
||||
root_wallets_directory_created_on_startup: self.wallet_config_startup.root_directory_created_on_startup(),
|
||||
shell_phase: "pre.013-integration-compliance".to_owned(),
|
||||
shell_phase: "pre.014-desktop-polish".to_owned(),
|
||||
startup_diagnostic: runtime.startup_diagnostic.clone(),
|
||||
transport_available_endpoint_count,
|
||||
transport_clusters: self.transport_runtime.clusters(),
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
// file: crates/ksp-app-wallet-desk/src/splash.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Common splash settings and frontend event contracts for Wallet Desk.
|
||||
|
||||
use ts_rs::TS; // rust-rules: trait-import
|
||||
|
||||
const DEFAULT_SPLASH_FADE_MS: u32 = 300;
|
||||
const DEFAULT_SPLASH_FADE_IN_MS: u32 = 300;
|
||||
const DEFAULT_SPLASH_FADE_OUT_MS: u32 = 300;
|
||||
const DEFAULT_SPLASH_MINIMUM_MS: u64 = 1200;
|
||||
const ENV_SPLASH_FADE_MS: &str = "KSP_DESK_SPLASH_FADE_MS";
|
||||
const ENV_SPLASH_FADE_IN_MS: &str = "KSP_DESK_SPLASH_FADE_IN_MS";
|
||||
const ENV_SPLASH_FADE_OUT_MS: &str = "KSP_DESK_SPLASH_FADE_OUT_MS";
|
||||
const ENV_SPLASH_MINIMUM_MS: &str = "KSP_DESK_SPLASH_MINIMUM_MS";
|
||||
const MAX_SPLASH_FADE_MS: u32 = 10_000;
|
||||
const MAX_SPLASH_MINIMUM_MS: u64 = 60_000;
|
||||
@@ -15,10 +17,12 @@ const MAX_SPLASH_MINIMUM_MS: u64 = 60_000;
|
||||
/// Runtime timings used by the common desk splash lifecycle.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(crate) struct SplashSettings {
|
||||
fade_in_ms: u32,
|
||||
minimum_ms: u64,
|
||||
fade_ms: u32,
|
||||
fade_out_ms: u32,
|
||||
fade_in_source: ksp_config_lib::ConfigEnvironmentSource,
|
||||
minimum_source: ksp_config_lib::ConfigEnvironmentSource,
|
||||
fade_source: ksp_config_lib::ConfigEnvironmentSource,
|
||||
fade_out_source: ksp_config_lib::ConfigEnvironmentSource,
|
||||
}
|
||||
|
||||
impl SplashSettings {
|
||||
@@ -29,13 +33,23 @@ impl SplashSettings {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let fade_in = environment.resolve_variable(ENV_SPLASH_FADE_IN_MS, std::option::Option::Some("300"));
|
||||
let fade_in = match fade_in {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let minimum = environment.resolve_variable(ENV_SPLASH_MINIMUM_MS, std::option::Option::Some("1200"));
|
||||
let minimum = match minimum {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let fade = environment.resolve_variable(ENV_SPLASH_FADE_MS, std::option::Option::Some("300"));
|
||||
let fade = match fade {
|
||||
let fade_out = environment.resolve_variable(ENV_SPLASH_FADE_OUT_MS, std::option::Option::Some("300"));
|
||||
let fade_out = match fade_out {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let fade_in_ms = parse_u32_setting(ENV_SPLASH_FADE_IN_MS, fade_in.value(), MAX_SPLASH_FADE_MS);
|
||||
let fade_in_ms = match fade_in_ms {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
@@ -44,35 +58,56 @@ impl SplashSettings {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let fade_ms = parse_u32_setting(ENV_SPLASH_FADE_MS, fade.value(), MAX_SPLASH_FADE_MS);
|
||||
let fade_ms = match fade_ms {
|
||||
let fade_out_ms = parse_u32_setting(ENV_SPLASH_FADE_OUT_MS, fade_out.value(), MAX_SPLASH_FADE_MS);
|
||||
let fade_out_ms = match fade_out_ms {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
return std::result::Result::Ok(Self { minimum_ms, fade_ms, minimum_source: minimum.source(), fade_source: fade.source() });
|
||||
return std::result::Result::Ok(Self {
|
||||
fade_in_ms,
|
||||
minimum_ms,
|
||||
fade_out_ms,
|
||||
fade_in_source: fade_in.source(),
|
||||
minimum_source: minimum.source(),
|
||||
fade_out_source: fade_out.source(),
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns safe in-memory timings used when the managed environment cannot be resolved.
|
||||
#[must_use]
|
||||
pub(crate) const fn fallback() -> Self {
|
||||
return Self {
|
||||
fade_in_ms: DEFAULT_SPLASH_FADE_IN_MS,
|
||||
minimum_ms: DEFAULT_SPLASH_MINIMUM_MS,
|
||||
fade_ms: DEFAULT_SPLASH_FADE_MS,
|
||||
fade_out_ms: DEFAULT_SPLASH_FADE_OUT_MS,
|
||||
fade_in_source: ksp_config_lib::ConfigEnvironmentSource::Fallback,
|
||||
minimum_source: ksp_config_lib::ConfigEnvironmentSource::Fallback,
|
||||
fade_source: ksp_config_lib::ConfigEnvironmentSource::Fallback,
|
||||
fade_out_source: ksp_config_lib::ConfigEnvironmentSource::Fallback,
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns the minimum visible duration after splash frontend readiness.
|
||||
/// Returns the configured fade-in duration.
|
||||
#[must_use]
|
||||
pub(crate) const fn fade_in_ms(self) -> u32 {
|
||||
return self.fade_in_ms;
|
||||
}
|
||||
|
||||
/// Returns the minimum fully-visible splash duration.
|
||||
#[must_use]
|
||||
pub(crate) const fn minimum_ms(self) -> u64 {
|
||||
return self.minimum_ms;
|
||||
}
|
||||
|
||||
/// Returns the fade duration used for both fade-in and fade-out.
|
||||
/// Returns the configured fade-out duration.
|
||||
#[must_use]
|
||||
pub(crate) const fn fade_ms(self) -> u32 {
|
||||
return self.fade_ms;
|
||||
pub(crate) const fn fade_out_ms(self) -> u32 {
|
||||
return self.fade_out_ms;
|
||||
}
|
||||
|
||||
/// Returns the safe provenance code for the fade-in duration.
|
||||
#[must_use]
|
||||
pub(crate) const fn fade_in_source(self) -> &'static str {
|
||||
return environment_source_code(self.fade_in_source);
|
||||
}
|
||||
|
||||
/// Returns the safe provenance code for the minimum duration.
|
||||
@@ -81,16 +116,16 @@ impl SplashSettings {
|
||||
return environment_source_code(self.minimum_source);
|
||||
}
|
||||
|
||||
/// Returns the safe provenance code for the fade duration.
|
||||
/// Returns the safe provenance code for the fade-out duration.
|
||||
#[must_use]
|
||||
pub(crate) const fn fade_source(self) -> &'static str {
|
||||
return environment_source_code(self.fade_source);
|
||||
pub(crate) const fn fade_out_source(self) -> &'static str {
|
||||
return environment_source_code(self.fade_out_source);
|
||||
}
|
||||
|
||||
/// Returns the minimum backend lifecycle duration from readiness until main activation.
|
||||
/// Returns the expected additive backend lifecycle from readiness through fade-out.
|
||||
#[must_use]
|
||||
pub(crate) fn expected_backend_lifecycle_ms(self) -> u64 {
|
||||
return self.minimum_ms + u64::from(self.fade_ms);
|
||||
return u64::from(self.fade_in_ms) + self.minimum_ms + u64::from(self.fade_out_ms);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +138,8 @@ pub(crate) struct SplashOrderDto {
|
||||
pub(crate) action: String,
|
||||
/// Optional status text.
|
||||
pub(crate) message: std::option::Option<String>,
|
||||
/// Optional message severity used by the bottom message feed.
|
||||
pub(crate) status: std::option::Option<String>,
|
||||
/// Optional animation duration in milliseconds.
|
||||
pub(crate) duration_ms: std::option::Option<u32>,
|
||||
}
|
||||
@@ -110,8 +147,13 @@ pub(crate) struct SplashOrderDto {
|
||||
impl SplashOrderDto {
|
||||
/// Creates a new `SplashOrderDto` value.
|
||||
#[must_use]
|
||||
pub(crate) fn new(action: &str, message: std::option::Option<&str>, duration_ms: std::option::Option<u32>) -> Self {
|
||||
return Self { action: action.to_owned(), message: message.map(std::string::ToString::to_string), duration_ms };
|
||||
pub(crate) fn new(action: &str, message: std::option::Option<&str>, status: std::option::Option<&str>, duration_ms: std::option::Option<u32>) -> Self {
|
||||
return Self {
|
||||
action: action.to_owned(),
|
||||
message: message.map(std::string::ToString::to_string),
|
||||
status: status.map(std::string::ToString::to_string),
|
||||
duration_ms,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-wallet-desk/src/tw_splash.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Tauri-window lifecycle for the Wallet Desk splash window.
|
||||
|
||||
@@ -41,27 +41,64 @@ pub(crate) async fn splash_frontend_ready_service(
|
||||
}
|
||||
let settings = state.splash_settings();
|
||||
let lifecycle_started = std::time::Instant::now();
|
||||
ksp_logging_lib::debug!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WINDOWS, window_label = WINDOW_LABEL_SPLASH, minimum_ms = settings.minimum_ms(), minimum_source = settings.minimum_source(), fade_ms = settings.fade_ms(), fade_source = settings.fade_source(), expected_backend_lifecycle_ms = settings.expected_backend_lifecycle_ms(), "splash frontend readiness accepted; starting splash to main lifecycle");
|
||||
let fade_in = emit_order(
|
||||
&invoking_window,
|
||||
crate::SplashOrderDto::new("fade_in", std::option::Option::Some("Initialisation de KSP Wallet Desk..."), std::option::Option::Some(settings.fade_ms())),
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
domain = crate::TRACING_DOMAIN_WINDOWS,
|
||||
window_label = WINDOW_LABEL_SPLASH,
|
||||
fade_in_ms = settings.fade_in_ms(),
|
||||
fade_in_source = settings.fade_in_source(),
|
||||
minimum_ms = settings.minimum_ms(),
|
||||
minimum_source = settings.minimum_source(),
|
||||
fade_out_ms = settings.fade_out_ms(),
|
||||
fade_out_source = settings.fade_out_source(),
|
||||
expected_backend_lifecycle_ms = settings.expected_backend_lifecycle_ms(),
|
||||
"splash frontend readiness accepted; starting splash to main lifecycle"
|
||||
);
|
||||
if let std::result::Result::Err(error) = fade_in {
|
||||
let emitted = emit_order(
|
||||
&invoking_window,
|
||||
crate::SplashOrderDto::new("fade_in", std::option::Option::None, std::option::Option::None, std::option::Option::Some(settings.fade_in_ms())),
|
||||
);
|
||||
if let std::result::Result::Err(error) = emitted {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let minimum_wait_started = std::time::Instant::now();
|
||||
tokio::time::sleep(std::time::Duration::from_millis(settings.minimum_ms())).await;
|
||||
ksp_logging_lib::debug!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WINDOWS, window_label = WINDOW_LABEL_SPLASH, configured_wait_ms = settings.minimum_ms(), actual_wait_ms = minimum_wait_started.elapsed().as_secs_f64() * 1000.0, lifecycle_elapsed_ms = lifecycle_started.elapsed().as_secs_f64() * 1000.0, "splash minimum wait completed");
|
||||
let fade_out = emit_order(
|
||||
&invoking_window,
|
||||
crate::SplashOrderDto::new("fade_out", std::option::Option::Some("Initialisation terminée."), std::option::Option::Some(settings.fade_ms())),
|
||||
);
|
||||
if let std::result::Result::Err(error) = fade_out {
|
||||
let emitted = emit_message(&invoking_window, "Initialisation de Wallet Desk...", "info");
|
||||
if let std::result::Result::Err(error) = emitted {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let fade_wait_started = std::time::Instant::now();
|
||||
tokio::time::sleep(std::time::Duration::from_millis(u64::from(settings.fade_ms()))).await;
|
||||
ksp_logging_lib::debug!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WINDOWS, window_label = WINDOW_LABEL_SPLASH, configured_wait_ms = settings.fade_ms(), actual_wait_ms = fade_wait_started.elapsed().as_secs_f64() * 1000.0, lifecycle_elapsed_ms = lifecycle_started.elapsed().as_secs_f64() * 1000.0, "splash fade-out wait completed");
|
||||
let emitted = emit_debug(&invoking_window, "Listener frontend prêt; fade-in piloté par Rust.");
|
||||
if let std::result::Result::Err(error) = emitted {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
sleep_and_log(&invoking_window, "fade-in", u64::from(settings.fade_in_ms()), lifecycle_started).await;
|
||||
let emitted = emit_message(&invoking_window, "Configuration KSP chargée.", "success");
|
||||
if let std::result::Result::Err(error) = emitted {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let emitted = emit_debug(&invoking_window, "Configuration et provenance des timings résolues via ksp-config-lib.");
|
||||
if let std::result::Result::Err(error) = emitted {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let emitted = emit_message(&invoking_window, "Runtime Logging initialisé.", "success");
|
||||
if let std::result::Result::Err(error) = emitted {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let emitted = emit_message(&invoking_window, "Wallet et Transport prêts.", "success");
|
||||
if let std::result::Result::Err(error) = emitted {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
sleep_and_log(&invoking_window, "minimum", settings.minimum_ms(), lifecycle_started).await;
|
||||
let emitted = emit_message(&invoking_window, "Initialisation terminée.", "success");
|
||||
if let std::result::Result::Err(error) = emitted {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
let emitted = emit_order(
|
||||
&invoking_window,
|
||||
crate::SplashOrderDto::new("fade_out", std::option::Option::None, std::option::Option::None, std::option::Option::Some(settings.fade_out_ms())),
|
||||
);
|
||||
if let std::result::Result::Err(error) = emitted {
|
||||
return std::result::Result::Err(error);
|
||||
}
|
||||
sleep_and_log(&invoking_window, "fade-out", u64::from(settings.fade_out_ms()), lifecycle_started).await;
|
||||
let show_main = crate::show_main_window(&app);
|
||||
if let std::result::Result::Err(error) = show_main {
|
||||
return std::result::Result::Err(error);
|
||||
@@ -74,10 +111,50 @@ pub(crate) async fn splash_frontend_ready_service(
|
||||
.with_source(error),
|
||||
);
|
||||
}
|
||||
ksp_logging_lib::debug!(target: crate::TRACING_TARGET, domain = crate::TRACING_DOMAIN_WINDOWS, window_label = WINDOW_LABEL_SPLASH, expected_backend_lifecycle_ms = settings.expected_backend_lifecycle_ms(), actual_backend_lifecycle_ms = lifecycle_started.elapsed().as_secs_f64() * 1000.0, "splash window destroyed after main activation");
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
domain = crate::TRACING_DOMAIN_WINDOWS,
|
||||
window_label = WINDOW_LABEL_SPLASH,
|
||||
expected_backend_lifecycle_ms = settings.expected_backend_lifecycle_ms(),
|
||||
actual_backend_lifecycle_ms = lifecycle_started.elapsed().as_secs_f64() * 1000.0,
|
||||
"splash window destroyed after main activation"
|
||||
);
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
|
||||
fn emit_message(window: &tauri::WebviewWindow, message: &str, status: &str) -> ksp_core_lib::Result<()> {
|
||||
return emit_order(
|
||||
window,
|
||||
crate::SplashOrderDto::new("add_message", std::option::Option::Some(message), std::option::Option::Some(status), std::option::Option::None),
|
||||
);
|
||||
}
|
||||
|
||||
fn emit_debug(window: &tauri::WebviewWindow, message: &str) -> ksp_core_lib::Result<()> {
|
||||
if !cfg!(debug_assertions) {
|
||||
return std::result::Result::Ok(());
|
||||
}
|
||||
return emit_order(
|
||||
window,
|
||||
crate::SplashOrderDto::new("add_debug", std::option::Option::Some(message), std::option::Option::None, std::option::Option::None),
|
||||
);
|
||||
}
|
||||
|
||||
async fn sleep_and_log(window: &tauri::WebviewWindow, phase: &str, duration_ms: u64, lifecycle_started: std::time::Instant) {
|
||||
let wait_started = std::time::Instant::now();
|
||||
tokio::time::sleep(std::time::Duration::from_millis(duration_ms)).await;
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
domain = crate::TRACING_DOMAIN_WINDOWS,
|
||||
window_label = window.label(),
|
||||
phase,
|
||||
configured_wait_ms = duration_ms,
|
||||
actual_wait_ms = wait_started.elapsed().as_secs_f64() * 1000.0,
|
||||
lifecycle_elapsed_ms = lifecycle_started.elapsed().as_secs_f64() * 1000.0,
|
||||
"splash lifecycle wait completed"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
fn emit_order(window: &tauri::WebviewWindow, order: crate::SplashOrderDto) -> ksp_core_lib::Result<()> {
|
||||
let action = order.action.clone();
|
||||
let emitted = window.emit(SPLASH_EVENT_NAME, order);
|
||||
|
||||
Reference in New Issue
Block a user