diff --git a/client/src/gui.rs b/client/src/gui.rs index cae524e..ac87cba 100644 --- a/client/src/gui.rs +++ b/client/src/gui.rs @@ -1,40 +1,41 @@ use leptos::{ IntoView, ev, html::{ElementChild, button}, - logging::log, prelude::{OnAttribute, Read, Show, ShowProps, ToChildren}, server::LocalResource, - task::spawn_local, }; -use wasm_bindgen_futures::JsFuture; -use web_sys::HtmlAudioElement; -use crate::media::audio; +use crate::{media::audio, webrtc::WebRTC}; pub fn app() -> impl IntoView { let audio_stream = LocalResource::new(|| audio()); - let props = ShowProps::builder() + let offer_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), + .on(ev::click, move |_| { + WebRTC::init(Some(audio_stream), None, None); + LocalResource::new(|| WebRTC::offer()); }) - .child("Happy Button") + .child("Offer") .into_view() })) - .fallback(|| button().child("Sad Button")) + .fallback(|| button().child("Sad Offer Button")) .build(); - Show(props) + + let answer_props = ShowProps::builder() + .when(move || audio_stream.read().is_some()) + .children(ToChildren::to_children(move || { + button() + .on(ev::click, move |_| { + WebRTC::init(Some(audio_stream), None, None); + LocalResource::new(|| WebRTC::answer()); + }) + .child("Answer") + .into_view() + })) + .fallback(|| button().child("Sad Answer Button")) + .build(); + + (Show(offer_props), Show(answer_props)) } diff --git a/client/src/webrtc.rs b/client/src/webrtc.rs index 8f29887..4afda2b 100644 --- a/client/src/webrtc.rs +++ b/client/src/webrtc.rs @@ -1,4 +1,4 @@ -use leptos::logging::log; +use leptos::{logging::log, prelude::Get, server::LocalResource}; use protocol::Error; use wasm_bindgen_futures::{JsFuture, spawn_local}; use web_sys::{ @@ -14,14 +14,11 @@ use crate::signal::{ }; pub struct WebRTC { - audio_stream: Option, - video_stream: Option, - screen_stream: Option, peer_connection: RtcPeerConnection, } thread_local! { - static WEBRTC:WebRTC = WebRTC::new().unwrap(); + pub static WEBRTC:WebRTC = WebRTC::new().unwrap(); } impl WebRTC { @@ -51,27 +48,17 @@ impl WebRTC { peer_connection.set_onicecandidate(Some(on_ice_candidate.as_ref().unchecked_ref())); on_ice_candidate.forget(); - let webrtc = Self { - audio_stream: None, - video_stream: None, - screen_stream: None, - peer_connection, - }; + let webrtc = Self { peer_connection }; Ok(webrtc) } - async fn init( - &mut self, - audio_stream: Option, - video_stream: Option, - screen_stream: Option, + pub fn init( + audio_stream: Option>, + video_stream: Option>, + screen_stream: Option>, ) { - self.audio_stream = audio_stream; - self.video_stream = video_stream; - self.screen_stream = screen_stream; - - self.add_streams(); + Self::add_streams(audio_stream, video_stream, screen_stream); spawn_local(async { while let Ok(received_ice_candidate) = receive_ice_candidate() { @@ -98,20 +85,32 @@ impl WebRTC { }); } - fn add_streams(&mut self) { - if let Some(audio_stream) = &self.audio_stream { - self.peer_connection.add_stream(audio_stream); - } - if let Some(video_stream) = &self.video_stream { - self.peer_connection.add_stream(video_stream); - } - if let Some(screen_stream) = &self.screen_stream { - self.peer_connection.add_stream(screen_stream); - } + fn add_streams( + audio_stream: Option>, + video_stream: Option>, + screen_stream: Option>, + ) { + WEBRTC.with(|webrtc| { + if let Some(audio_stream) = audio_stream { + if let Some(audio_stream) = audio_stream.get() { + webrtc.peer_connection.add_stream(&audio_stream); + } + } + if let Some(video_stream) = video_stream { + if let Some(video_stream) = video_stream.get() { + webrtc.peer_connection.add_stream(&video_stream); + } + } + if let Some(screen_stream) = screen_stream { + if let Some(screen_stream) = screen_stream.get() { + webrtc.peer_connection.add_stream(&screen_stream); + } + } + }); } - async fn offer(&mut self) -> Result<(), Error> { - let offer_promise = self.peer_connection.create_offer(); + pub async fn offer() -> Result<(), Error> { + let offer_promise = WEBRTC.with(|webrtc| webrtc.peer_connection.create_offer()); match JsFuture::from(offer_promise) .await .map_err(|_| Error::WebRTCOffer) @@ -127,8 +126,8 @@ impl WebRTC { Ok(offer_session_description_protocol) => { let offer = RtcSessionDescriptionInit::new(RtcSdpType::Offer); offer.set_sdp(&offer_session_description_protocol); - let set_local_description_promise = - self.peer_connection.set_local_description(&offer); + let set_local_description_promise = WEBRTC + .with(|webrtc| webrtc.peer_connection.set_local_description(&offer)); JsFuture::from(set_local_description_promise) .await @@ -140,8 +139,9 @@ impl WebRTC { let answer = RtcSessionDescriptionInit::new(RtcSdpType::Answer); answer.set_sdp(&received_answer.get_data()); - let set_remote_description_promise = - self.peer_connection.set_remote_description(&answer); + let set_remote_description_promise = WEBRTC.with(|webrtc| { + webrtc.peer_connection.set_remote_description(&answer) + }); JsFuture::from(set_remote_description_promise) .await .map_err(|_| Error::WebRTCSetRemoteDescription)?; @@ -164,18 +164,18 @@ impl WebRTC { return Err(Error::WebRTCOffer); } - async fn answer(&mut self) -> Result<(), Error> { + pub async fn answer() -> Result<(), Error> { if let Ok(received_offer) = receive_offer() { let offer = RtcSessionDescriptionInit::new(RtcSdpType::Offer); offer.set_sdp(&received_offer.get_data()); let set_remote_description_promise = - self.peer_connection.set_remote_description(&offer); + WEBRTC.with(|webrtc| webrtc.peer_connection.set_remote_description(&offer)); JsFuture::from(set_remote_description_promise) .await .map_err(|_| Error::WebRTCSetRemoteDescription)?; - let answer_promise = self.peer_connection.create_answer(); + let answer_promise = WEBRTC.with(|webrtc| webrtc.peer_connection.create_answer()); match JsFuture::from(answer_promise) .await .map_err(|_| Error::WebRTCAnswer) @@ -192,8 +192,9 @@ impl WebRTC { let answer = RtcSessionDescriptionInit::new(RtcSdpType::Answer); answer.set_sdp(&answer_session_description_protocol); - let set_local_description_promise = - self.peer_connection.set_local_description(&answer); + let set_local_description_promise = WEBRTC.with(|webrtc| { + webrtc.peer_connection.set_local_description(&answer) + }); JsFuture::from(set_local_description_promise) .await .map_err(|_| Error::WebRTCSetLocalDescription)?;