diff --git a/front_end/index.html b/front_end/index.html index 022cc84..eebcb7f 100644 --- a/front_end/index.html +++ b/front_end/index.html @@ -188,6 +188,12 @@ opacity: 1; } } + button#resetbutton { + background-color: #C55; + color: #FFF; + grid-row: 2; + grid-column: 8; + } diff --git a/front_end/src/yew_components.rs b/front_end/src/yew_components.rs index defc412..88bda03 100644 --- a/front_end/src/yew_components.rs +++ b/front_end/src/yew_components.rs @@ -52,66 +52,62 @@ impl Component for MainMenu { .link() .context::(Callback::noop()) .expect("state to be set"); - match shared.game_state.get() { - GameState::MainMenu => { - let player_type: Turn; - { - let mut rng = get_seeded_random().expect("Random should be available"); - player_type = if rng.rand_range(0..2) == 0 { - Turn::CyanPlayer - } else { - Turn::MagentaPlayer - }; - } + let player_type: Turn; + { + let mut rng = get_seeded_random().expect("Random should be available"); + player_type = if rng.rand_range(0..2) == 0 { + Turn::CyanPlayer + } else { + Turn::MagentaPlayer + }; + } - let easy_player_type = player_type; - let normal_player_type = player_type; - let hard_player_type = player_type; + let easy_player_type = player_type; + let normal_player_type = player_type; + let hard_player_type = player_type; - let onclick_singleplayer_easy = ctx.link().callback(move |_| { - MainMenuMessage::SinglePlayer(easy_player_type, AIDifficulty::Easy) - }); - let onclick_singleplayer_normal = ctx.link().callback(move |_| { - MainMenuMessage::SinglePlayer(normal_player_type, AIDifficulty::Normal) - }); - let onclick_singleplayer_hard = ctx.link().callback(move |_| { - MainMenuMessage::SinglePlayer(hard_player_type, AIDifficulty::Hard) - }); + let onclick_singleplayer_easy = ctx + .link() + .callback(move |_| MainMenuMessage::SinglePlayer(easy_player_type, AIDifficulty::Easy)); + let onclick_singleplayer_normal = ctx.link().callback(move |_| { + MainMenuMessage::SinglePlayer(normal_player_type, AIDifficulty::Normal) + }); + let onclick_singleplayer_hard = ctx + .link() + .callback(move |_| MainMenuMessage::SinglePlayer(hard_player_type, AIDifficulty::Hard)); - let onclick_local_multiplayer = - ctx.link().callback(|_| MainMenuMessage::LocalMultiplayer); + let onclick_local_multiplayer = ctx.link().callback(|_| MainMenuMessage::LocalMultiplayer); - let onclick_networked_multiplayer = ctx - .link() - .callback(|_| MainMenuMessage::NetworkedMultiplayer); + let onclick_networked_multiplayer = ctx + .link() + .callback(|_| MainMenuMessage::NetworkedMultiplayer); - html! { -
- {"Please pick a game mode."} -
- - - -
- - -
- } - } - _ => html! { -
+ let menu_class = if shared.game_state.get() == GameState::MainMenu { + "menu" + } else { + "hidden_menu" + }; + html! { +
+ {"Please pick a game mode."} +
+ + +
- }, + + +
} } @@ -129,7 +125,6 @@ impl Component for MainMenu { .get_element_by_id("mainmenu") .expect("mainmenu should exist"); mainmenu.set_class_name("hidden_menu"); - mainmenu.set_inner_html(""); match shared.game_state.get() { GameState::SinglePlayer(turn, _) => { @@ -176,7 +171,7 @@ impl Component for MainMenu { .expect("Wrapper should be a parent of MainMenu") .clone() .downcast::() - .send_message(WrapperMsg::BackendTick); + .send_message(WrapperMsg::StartBackendTick); } _ => { append_to_info_text( @@ -194,6 +189,36 @@ impl Component for MainMenu { } } +struct ResetButton {} + +impl Component for ResetButton { + type Message = (); + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self {} + } + + fn view(&self, ctx: &Context) -> Html { + let onclick_reset = ctx.link().callback(|_| ()); + html! { + + } + } + + fn update(&mut self, ctx: &Context, _msg: Self::Message) -> bool { + ctx.link() + .get_parent() + .expect("Wrapper should be parent of ResetButton") + .clone() + .downcast::() + .send_message(WrapperMsg::Reset); + true + } +} + pub struct Slot {} pub enum SlotMessage { @@ -575,6 +600,8 @@ pub enum WrapperMsg { AIPressed(u8), AIChoice, AIChoiceImpl, + StartBackendTick, + StartBackendTickImpl, BackendTick, BackendRequest { place: u8 }, BackendResponse(BREnum), @@ -607,6 +634,7 @@ impl Component for Wrapper { html! {
+ @@ -1175,8 +1203,44 @@ impl Component for Wrapper { } } } + WrapperMsg::StartBackendTick => { + self.defer_message( + ctx, + WrapperMsg::StartBackendTickImpl, + BACKEND_TICK_DURATION_MILLIS, + ); + } + WrapperMsg::StartBackendTickImpl => { + // If previous id is still stored, request disconnect so that a + // new id can be received + if let Some(id) = self.player_id.take() { + let function = Function::new_no_args(&format!( + " + let xhr = new XMLHttpRequest(); + xhr.open('POST', '{}'); + xhr.send('{{\"type\": \"disconnect\", \"id\": {}}}'); + ", + BACKEND_URL, id + )); + function.call0(&function).ok(); + } + self.do_backend_tick = true; + ctx.link().send_message(WrapperMsg::BackendTick); + } WrapperMsg::BackendTick => { - if !self.do_backend_tick { + if !self.do_backend_tick || shared.game_state.get() == GameState::default() { + // disconnect id if backend tick is to be stopped + if let Some(id) = self.player_id.take() { + let function = Function::new_no_args(&format!( + " + let xhr = new XMLHttpRequest(); + xhr.open('POST', '{}'); + xhr.send('{{\"type\": \"disconnect\", \"id\": {}}}'); + ", + BACKEND_URL, id + )); + function.call0(&function).ok(); + } return false; } @@ -1415,6 +1479,13 @@ impl Component for Wrapper { self.do_backend_tick = false; } NetworkedGameState::Disconnected => { + append_to_info_text( + &document, + "info_text0", + "The opponent disconnected", + INFO_TEXT_MAX_ITEMS, + ) + .ok(); append_to_info_text( &document, "info_text1", @@ -1593,6 +1664,22 @@ impl Component for Wrapper { function.call0(&function).ok(); } self.place_request = None; + element_remove_class(&document, "mainmenu", "hidden_menu").ok(); + element_append_class(&document, "mainmenu", "menu").ok(); + append_to_info_text( + &document, + "info_text1", + "Waiting to choose game-mode...", + 1, + ) + .ok(); + append_to_info_text( + &document, + "info_text0", + "Reset button was pressed", + INFO_TEXT_MAX_ITEMS, + ) + .ok(); self.do_backend_tick = false; } } // match (msg)