niom-webrtc/src/main.rs

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,
}
}
}
}