diff --git a/Cargo.lock b/Cargo.lock index cbe3f3f..3562cc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2681,6 +2681,7 @@ dependencies = [ "dioxus", "dioxus-logger", "futures", + "gloo-net", "js-sys", "log", "serde", diff --git a/Cargo.toml b/Cargo.toml index e58763b..9634a70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ console_log = "1.0.0" serde = { version = "1.0.142", features = ["derive"] } serde_json = "1.0.100" futures = "0.3.31" +gloo-net = "0.6" [features] default = ["web"] diff --git a/src/config.rs b/src/config.rs index 6c7db5f..ea9114f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -22,3 +22,31 @@ impl Config { Self::from_file("appsettings.json") } } + +// WASM runtime loader: fetch `appsettings.json` from the hosting origin +#[cfg(target_arch = "wasm32")] +pub async fn load_config_from_server() -> Result> { + // lazy import gloo-net to avoid non-wasm compile errors + let resp = gloo_net::http::Request::get("appsettings.json").send().await?; + let text = resp.text().await?; + let cfg: Config = serde_json::from_str(&text)?; + Ok(cfg) +} + +// Native loader convenience wrapper (blocking-friendly) +#[cfg(not(target_arch = "wasm32"))] +pub async fn load_config_from_server() -> Result> { + // On native we can just read the file synchronously and return + Ok(Config::from_file("appsettings.json")?) +} + +/// High-level loader with fallbacks: try wasm fetch (or native read), otherwise fallback to defaults. +pub async fn load_config_or_default() -> Config { + // Try to load via the async loader + if let Ok(cfg) = load_config_from_server().await { + return cfg; + } + + // Fallback default + Config { server: ServerOptions { stun_server: crate::constants::DEFAULT_STUN_SERVER.to_string() } } +} diff --git a/src/main.rs b/src/main.rs index 872fe51..456d237 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,8 +3,8 @@ mod components; mod models; mod utils; -mod constants; mod config; +mod constants; use dioxus::prelude::*; use log::Level; @@ -22,11 +22,26 @@ fn main() { } #[component] -fn App() -> Element { - rsx! { - document::Link { rel: "icon", href: FAVICON } - document::Link { rel: "stylesheet", href: MAIN_CSS } - Content {} +fn App(cx: Scope) -> Element { + // Component state for loaded config + let cfg_state = use_state(cx, || None::); + + // Kick off async config load once + use_future(cx, (), |_| { + let cfg_state = cfg_state.clone(); + async move { + let cfg = crate::config::load_config_or_default().await; + cfg_state.set(Some(cfg)); + } + }); + + match cfg_state.get().as_ref() { + None => rsx!( div { "Lade Konfiguration…" } ), + Some(_cfg) => rsx! { + document::Link { rel: "icon", href: FAVICON } + document::Link { rel: "stylesheet", href: MAIN_CSS } + Content {} + } } }