Load runtime config in App (wasm fetch) and provide async loader; use DEFAULT_STUN_SERVER fallback

This commit is contained in:
ghost 2025-09-30 13:53:26 +02:00
parent 2250859ff9
commit 9fa1c22c5e
4 changed files with 51 additions and 6 deletions

1
Cargo.lock generated
View File

@ -2681,6 +2681,7 @@ dependencies = [
"dioxus",
"dioxus-logger",
"futures",
"gloo-net",
"js-sys",
"log",
"serde",

View File

@ -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"]

View File

@ -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<Config, Box<dyn std::error::Error>> {
// 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<Config, Box<dyn std::error::Error>> {
// 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() } }
}

View File

@ -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::<crate::config::Config>);
// 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 {}
}
}
}