83 lines
3.0 KiB
Rust
83 lines
3.0 KiB
Rust
#![allow(non_snake_case)]
|
|
|
|
use console_log::init_with_level;
|
|
use dioxus::prelude::*;
|
|
use log::Level;
|
|
use niom_webrtc::components::VoiceChannelLayout;
|
|
use niom_webrtc::models::Participant;
|
|
use niom_webrtc::services::signaling::SignalingProvider;
|
|
// config functions used via fully-qualified paths below
|
|
|
|
const FAVICON: Asset = asset!("/assets/favicon.ico");
|
|
const MAIN_CSS: Asset = asset!("/assets/main.css");
|
|
|
|
fn main() {
|
|
init_with_level(Level::Info).expect("console_log initialization failed");
|
|
console_error_panic_hook::set_once();
|
|
dioxus::launch(App);
|
|
}
|
|
|
|
#[component]
|
|
fn App() -> Element {
|
|
rsx! {
|
|
document::Link { rel: "icon", href: FAVICON }
|
|
document::Link { rel: "stylesheet", href: MAIN_CSS }
|
|
ConfigProvider {}
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
fn ConfigProvider() -> Element {
|
|
// Start with a synchronous default so the UI has a sensible config immediately.
|
|
let default_cfg = niom_webrtc::config::load_config_sync_or_default();
|
|
|
|
// A signal holding the active config; children will consume a Signal<Config> via use_context.
|
|
let mut cfg_signal = use_signal(|| default_cfg.clone());
|
|
|
|
// Spawn an async resource to load the config at runtime (WASM fetch / native file). When it
|
|
// finishes, overwrite the signal so the rest of the app sees the updated config.
|
|
let resource = use_resource(|| async move {
|
|
// load_config_or_default is async and returns a Config
|
|
niom_webrtc::config::load_config_or_default().await
|
|
});
|
|
|
|
// When the resource value becomes available, update the cfg_signal. This effect will run
|
|
// reactively whenever the resource's value changes.
|
|
// If the async resource has produced a value, apply it to the signal immediately so
|
|
// downstream consumers see the updated configuration.
|
|
if let Some(cfg) = resource.value().read_unchecked().as_ref() {
|
|
cfg_signal.set(cfg.clone());
|
|
}
|
|
|
|
// Provide the Signal<Config> to downstream components.
|
|
use_context_provider(|| cfg_signal.clone());
|
|
|
|
rsx! { Content {} }
|
|
}
|
|
|
|
#[component]
|
|
pub fn Content() -> Element {
|
|
// Config is provided by ConfigProvider via provide_context; components can use use_context to read it.
|
|
|
|
let participants = use_signal(|| {
|
|
vec![
|
|
Participant::new("self", "Ghost", "#5865F2", true, false, true),
|
|
Participant::new("mod-1", "Nia Moderator", "#43B581", false, false, true),
|
|
Participant::new("listener-1", "Amber", "#FAA61A", false, true, false),
|
|
Participant::new("listener-2", "Basil", "#EB459E", false, false, false),
|
|
Participant::new("listener-3", "Colt", "#5865F2", false, true, false),
|
|
Participant::new("listener-4", "Delta", "#99AAB5", false, false, false),
|
|
]
|
|
});
|
|
|
|
rsx! {
|
|
SignalingProvider {
|
|
VoiceChannelLayout {
|
|
channel_name: "Project Alpha / Voice Lounge".to_string(),
|
|
channel_topic: "Team sync & architecture deep dive".to_string(),
|
|
participants,
|
|
}
|
|
}
|
|
}
|
|
}
|