use crate::app::BoardView; use crate::types::SelectedTile; use board_network::protocol::{ClientMessage, ServerMessage}; use board_shared::game::Game; use futures::stream::{SplitSink, SplitStream}; use futures::{SinkExt, StreamExt}; use gloo_dialogs::alert; use gloo_net::websocket::futures::WebSocket; use gloo_net::websocket::Message; use std::cell::RefCell; use std::rc::Rc; use yew::platform::spawn_local; use yew::prelude::*; #[derive(Properties)] pub struct RemoteGameViewProps { pub write: Rc>>, pub read: Rc>>, pub player_name: String, pub room_name: Option, } impl PartialEq for RemoteGameViewProps { fn eq(&self, other: &Self) -> bool { Rc::ptr_eq(&self.write, &other.write) && Rc::ptr_eq(&self.read, &other.read) && self.player_name == other.player_name && self.room_name == other.room_name } } #[function_component(RemoteGameView)] pub fn remote_game_view( RemoteGameViewProps { write, read, player_name, room_name, }: &RemoteGameViewProps, ) -> Html { macro_rules! send_client_message { ($write:expr, $message:expr) => {{ let write = $write.clone(); spawn_local(async move { write .borrow_mut() .send(Message::Text( serde_json::to_string(&$message).expect("Cannot serialize"), )) .await .unwrap(); }); }}; } let selected_tile = use_state(|| SelectedTile::None); let is_started = use_state(|| false); let current_player_turn = use_state(|| 0); let game = use_state(Game::default); { let player_name = player_name.clone(); let room_name = room_name.clone(); let write = write.clone(); use_effect_with_deps( move |_| { send_client_message!( write, if let Some(room_name) = room_name { ClientMessage::JoinRoom(room_name, player_name) } else { ClientMessage::CreateRoom(player_name) } ); }, (), ); let is_started = is_started.clone(); let current_player_turn = current_player_turn.clone(); let read = read.clone(); use_effect_with_deps( move |_| { spawn_local(async move { while let Some(event) = read.borrow_mut().next().await { if let Message::Text(msg) = event.unwrap() { match serde_json::from_str::(&msg) { Ok(ServerMessage::JoinedRoom { room_name, has_started, .. }) => { alert(&format!("Joined room {}", room_name)); is_started.set(has_started); } Ok(ServerMessage::PlayerTurn(player_id)) => { current_player_turn.set(player_id); is_started.set(true); } r => { alert(&format!("{:?}", r)); } }; } } }); || {} }, (), ); } let on_validate_click = { let write = write.clone(); Callback::from(move |_| { send_client_message!(write, ClientMessage::Validate); }) }; let on_start_game_click = { let write = write.clone(); Callback::from(move |_| { send_client_message!(write, ClientMessage::StartGame); }) }; let on_equals_select = { Callback::from(move |_| { selected_tile.set(SelectedTile::Equals); }) }; html! {

{"Remote Game"}

if *is_started { } else { }
if *is_started {

{format!("Player {}'s turn", *current_player_turn)}

}
} }