use leptos::{ IntoView, attr::Value, ev, html::{ElementChild, button, form, input}, logging::log, prelude::{ BindAttribute, Get, OnAttribute, Read, ReadSignal, Show, ShowProps, ToChildren, WriteSignal, signal, }, server::LocalResource, task::spawn_local, }; use wasm_bindgen_futures::JsFuture; use web_sys::HtmlAudioElement; use crate::{ media::audio, rtc::{answer, offer}, signal::send_auth, sleep, }; pub fn app() -> impl IntoView { let audio_stream = LocalResource::new(|| audio()); let props = ShowProps::builder() .when(move || audio_stream.read().is_some()) .children(ToChildren::to_children(move || { let audio_element = HtmlAudioElement::new().unwrap(); let audio_stream = audio_stream.read(); let audio_stream = audio_stream.as_deref(); audio_element.set_src_object(audio_stream); button() .on(ev::click, move |_| match audio_element.play() { Ok(audio_element_play_promise) => { log!("{}", "Play will"); spawn_local(async move { JsFuture::from(audio_element_play_promise).await.ok(); }); log!("{}", "Play must"); } Err(err_val) => log!("{:#?}", err_val), }) .child("Happy Button") .into_view() })) .fallback(|| button().child("Sad Button")) .build(); let username = signal(String::from("")); (Show(props), signalling(username), rtc_offer(), rtc_answer()) } fn signalling(username: (ReadSignal, WriteSignal)) -> impl IntoView { let signalling_trigger = move || { spawn_local(async move { send_auth(&username.0.get()).await.unwrap() }); }; let signalling_server_input = form() .child( input() .bind(Value, username) .placeholder("Some Username") .r#type("text"), ) .on(ev::submit, move |event| { event.prevent_default(); signalling_trigger(); }); let signalling_submit_button = button() .on(ev::click, move |event| { event.prevent_default(); signalling_trigger(); }) .child("Signal"); (signalling_server_input, signalling_submit_button) } fn rtc_offer() -> impl IntoView { let offer_trigger = move || { spawn_local(async move { let peer_connection = offer(audio().await).await; let audio_stream = audio().await; peer_connection.add_stream(&audio_stream); loop { log!("{:#?}", peer_connection.ice_connection_state()); log!("{:#?}", peer_connection.get_remote_streams()); sleep(1000).await; } }); }; let offer_button = button() .on(ev::click, move |event| { event.prevent_default(); offer_trigger(); }) .child("RTC Offer"); offer_button } fn rtc_answer() -> impl IntoView { let answer_trigger = move || { spawn_local(async move { let peer_connection = answer(audio().await).await; loop { log!("{:#?}", peer_connection.ice_connection_state()); log!("{:#?}", peer_connection.get_remote_streams()); sleep(1000).await; } }); }; let answer_button = button() .on(ev::click, move |event| { event.prevent_default(); answer_trigger(); }) .child("RTC Answer"); answer_button }