diff --git a/client/src/components/game.rs b/client/src/components/game.rs index 612f4f2..ab28161 100644 --- a/client/src/components/game.rs +++ b/client/src/components/game.rs @@ -1,64 +1,32 @@ -use crate::components::game::cards::*; use crate::components::game::header::*; +use crate::components::game::views::judging::*; +use crate::components::game::views::playing::*; use crate::components::websocket::WebSocketContext; use leptos::*; use leptos_use::core::ConnectionReadyState; use lib::*; -use serde_json::to_string; -use std::collections::HashMap; pub mod cards; pub mod header; -pub mod meta; -pub mod scoreboard; +pub mod views; #[component] pub fn Game() -> impl IntoView { // Websocket stuff let websocket = expect_context::(); - let tx = websocket.clone(); - let (websocket_send, set_websocket_send) = create_signal("".to_string()); - create_effect(move |_| { - tx.send(&websocket_send()); - }); + let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open; // Incoming - let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open; let game_meta = expect_context::>>(); - let judge_round = expect_context::>>(); let user_update = expect_context::>>(); // Signals // - let (selected_cards, set_selected_cards) = create_signal::>(vec![]); - let (card_clicked, set_card_clicked) = create_signal::(String::new()); - let (player_hand, set_player_hand) = - create_signal::>(HashMap::new()); let (judging, set_judging) = create_signal(false); - // Outoging - provide_context::>(set_card_clicked); - - // On Incoming Meta // - // Put cards in a map for easier lookup - // The server sends a vec to preserve ordering - create_effect(move |_| { - if game_meta().is_some() { - for card in game_meta().unwrap().white { - set_player_hand.update(|map| { - map.insert(card.uuid.clone(), card.clone()); - }); - } - } - set_selected_cards.update(|list| { - list.clear(); - }); - }); - // Determine judging create_effect(move |_| { user_update.with(move |user_meta| { if let Some(user_meta) = user_meta { if let Some(game_meta) = game_meta() { - logging::log!("{} {}", user_meta.username, game_meta.czar); if user_meta.username == game_meta.czar { set_judging(true); } else { @@ -69,114 +37,6 @@ pub fn Game() -> impl IntoView { }) }); - // On Incoming Judge // - create_effect(move |_| { - // Clear selected cards - if judge_round().is_some() { - set_selected_cards.update(|list| { - list.clear(); - }); - } - }); - - // Player Submit Handler // - let submit_move = move |_| { - let msg = to_string(&PlayerMoveRequest { - game_id: game_meta().unwrap().uuid.clone(), - card_ids: selected_cards() - .iter() - .map(|card| card.uuid.clone()) - .collect(), - }) - .unwrap(); - - set_websocket_send(msg); - set_selected_cards.update(|list| { - list.clear(); - }); - }; - - // Judging Submit Handler // - let submit_judge = move |_| { - let msg = to_string(&JudgeDecisionRequest { - game_id: game_meta().unwrap().uuid.clone(), - winning_cards: selected_cards() - .iter() - .map(|card| card.uuid.clone()) - .collect(), - }) - .unwrap(); - - set_websocket_send(msg); - set_selected_cards.update(|list| { - list.clear(); - }); - }; - - // Card selection // - // Toggle selected status of cards - create_effect(move |_| { - if card_clicked() != "".to_string() { - if judging.get_untracked() { - let identical_cards = selected_cards - .get_untracked() - .into_iter() - .filter(|card| card.uuid == card_clicked.get_untracked()) - .collect::>(); - - if identical_cards.len() > 0 { - set_selected_cards.update(|list| { - list.clear(); - }); - } else { - // Clear selected cards - set_selected_cards.update(|list| { - list.clear(); - }); - - // Select card group - for group in judge_round.get_untracked().unwrap().cards_to_judge { - for card in &group { - if card.uuid == card_clicked() { - set_selected_cards.update(|cards| cards.extend(group)); - break; - } - } - } - } - // Clear the signal otherwise it selects the last selected card again - set_card_clicked.update_untracked(|value| value.clear()); - } else { - if !selected_cards.get_untracked().contains( - player_hand - .get_untracked() - .get(&card_clicked.get_untracked()) - .unwrap(), - ) { - set_selected_cards.update(|cards| { - cards.push(player_hand().get(&card_clicked()).unwrap().clone()) - }) - } else if selected_cards - .get_untracked() - .contains(player_hand.get_untracked().get(&card_clicked()).unwrap()) - { - set_selected_cards.update(|cards| { - cards.remove( - cards - .iter() - .position(|card| { - card == player_hand().get(&card_clicked()).unwrap() - }) - .unwrap(), - ); - }) - } - // Clear the signal otherwise it selects the last selected card again - set_card_clicked.update_untracked(|value| value.clear()); - } - } - }); - view! {

Game

@@ -185,122 +45,19 @@ pub fn Game() -> impl IntoView { when=move || game_meta.get().is_some() && connected() fallback=|| view! { "You are not in a game" } > -
+
// Judging view // - -
- - - // Selected cards - } - } - /> -
- - // Submit button -
- -
- - - "You are the czar this round. Cards will appear here once all players have submitted their cards." -

- } - } - > - - - -
- } - } - /> -
- } - } - /> - + // Playing view // - - - // Play cards -
- - - // Selected cards - } - } - /> -
- - // Submit button -
- -
- - // Player hand -
- - - - } - } - /> -
+
- } } diff --git a/client/src/components/game/cards.rs b/client/src/components/game/cards.rs index 266dd6d..3813bc1 100644 --- a/client/src/components/game/cards.rs +++ b/client/src/components/game/cards.rs @@ -1,13 +1,16 @@ use leptos::*; -use lib::WhiteCardMeta; +use lib::*; #[component] -pub fn BlackCard(card_data: (String, u8)) -> impl IntoView { +pub fn BlackCard() -> impl IntoView { + let game_meta = expect_context::>>(); view! { -
-

{card_data.0}

-

Pick: {card_data.1}

-
+ +
+

{game_meta().unwrap().black.0}

+

Pick: {game_meta().unwrap().black.1}

+
+
} } diff --git a/client/src/components/game/header.rs b/client/src/components/game/header.rs index 8788752..bf4f1cd 100644 --- a/client/src/components/game/header.rs +++ b/client/src/components/game/header.rs @@ -1,14 +1,64 @@ -use crate::components::game::meta::*; -use crate::components::game::scoreboard::*; use leptos::*; use lib::*; #[component] -pub fn Header(game_meta: GameStateMeta) -> impl IntoView { +fn Meta() -> impl IntoView { + let game_meta = expect_context::>>(); + + view! { + +

Name: {move || game_meta().unwrap().name}

+

Host: {move || game_meta().unwrap().host}

+

Czar: {move || game_meta().unwrap().czar}

+

White Deck: {move || game_meta().unwrap().white_count}

+

White Discard: {move || game_meta().unwrap().white_discard_count}

+

Black Deck: {move || game_meta().unwrap().black_count}

+
+ } +} + +#[component] +fn Scoreboard() -> impl IntoView { + let game_meta = expect_context::>>(); + + view! { + + +

Players:

+ + + + + + + + {game_meta() + .unwrap() + .players + .iter() + .map(|player| { + view! { + + + + + } + }) + .collect_view()} +
NameScore
{&player.name} + {player.score} +
+
+
+ } +} + +#[component] +pub fn Header() -> impl IntoView { view! {
- - + +
} } diff --git a/client/src/components/game/meta.rs b/client/src/components/game/meta.rs deleted file mode 100644 index 4781c57..0000000 --- a/client/src/components/game/meta.rs +++ /dev/null @@ -1,17 +0,0 @@ -use leptos::*; -use lib::*; - -#[component] -pub fn Meta(game_meta: GameStateMeta) -> impl IntoView { - view! { - -

Name: {game_meta.name}

-

Host: {game_meta.host}

-

Czar: {game_meta.czar}

-

White Deck: {game_meta.white_count.to_string()}

-

White Discard: {move || game_meta.white_discard_count.to_string()}

-

Black Deck: {move || game_meta.black_count.to_string()}

-
- } -} - diff --git a/client/src/components/game/scoreboard.rs b/client/src/components/game/scoreboard.rs deleted file mode 100644 index 6c48632..0000000 --- a/client/src/components/game/scoreboard.rs +++ /dev/null @@ -1,31 +0,0 @@ -use leptos::*; -use lib::*; - -#[component] -pub fn Scoreboard(game_meta: GameStateMeta) -> impl IntoView { - view! { - -

Players:

- - - - - - - - {game_meta - .players - .iter() - .map(|player| { - view! { - - - - - } - }) - .collect_view()} -
NameScore
{&player.name}{&player.score.to_string()}
-
- } -} diff --git a/client/src/components/game/views/judging.rs b/client/src/components/game/views/judging.rs new file mode 100644 index 0000000..5701f56 --- /dev/null +++ b/client/src/components/game/views/judging.rs @@ -0,0 +1,141 @@ +use crate::components::game::cards::*; +use crate::components::websocket::WebSocketContext; +use leptos::*; +use lib::*; +use serde_json::to_string; + +#[component] +pub fn JudgingView() -> impl IntoView { + // Incoming + let websocket = expect_context::(); + let game_meta = expect_context::>>(); + let judge_round = expect_context::>>(); + + // Signals + let (selected_cards, set_selected_cards) = create_signal::>(vec![]); + let (card_clicked, set_card_clicked) = create_signal::(String::new()); + + // Outoging + provide_context::>(set_card_clicked); + + // On Incoming Judge + create_effect(move |_| { + // Clear selected cards + if judge_round().is_some() { + set_selected_cards.update(|list| { + list.clear(); + }); + } + }); + + // Card selection // + // Toggle selected status of cards + create_effect(move |_| { + if card_clicked() != "".to_string() { + let identical_cards = selected_cards + .get_untracked() + .into_iter() + .filter(|card| card.uuid == card_clicked.get_untracked()) + .collect::>(); + + if identical_cards.len() > 0 { + set_selected_cards.update(|list| { + list.clear(); + }); + } else { + // Clear selected cards + set_selected_cards.update(|list| { + list.clear(); + }); + + // Select card group + for group in judge_round.get_untracked().unwrap().cards_to_judge { + for card in &group { + if card.uuid == card_clicked() { + set_selected_cards.update(|cards| cards.extend(group)); + break; + } + } + } + } + // Clear the signal otherwise it selects the last selected card again + set_card_clicked.update_untracked(|value| value.clear()); + } + }); + + // Judging Submit Handler + let submit_judge = move |_| { + let msg = to_string(&JudgeDecisionRequest { + game_id: game_meta().unwrap().uuid.clone(), + winning_cards: selected_cards() + .iter() + .map(|card| card.uuid.clone()) + .collect(), + }) + .unwrap(); + + websocket.send(&msg); + set_selected_cards.update(|list| { + list.clear(); + }); + }; + + view! { +
+ + + // Selected cards + } + } + /> +
+ + // Submit button +
+ +
+ + + "You are the czar this round. Cards will appear here once all players have submitted their cards." +

+ } + } + > + + + +
+ } + } + /> + + } + } + /> + + } +} diff --git a/client/src/components/game/views/mod.rs b/client/src/components/game/views/mod.rs new file mode 100644 index 0000000..8049162 --- /dev/null +++ b/client/src/components/game/views/mod.rs @@ -0,0 +1,2 @@ +pub mod judging; +pub mod playing; diff --git a/client/src/components/game/views/playing.rs b/client/src/components/game/views/playing.rs new file mode 100644 index 0000000..29f94b3 --- /dev/null +++ b/client/src/components/game/views/playing.rs @@ -0,0 +1,132 @@ +use crate::components::game::cards::*; +use crate::components::websocket::WebSocketContext; +use leptos::*; +use lib::*; +use serde_json::to_string; +use std::collections::HashMap; + +#[component] +pub fn PlayingView() -> impl IntoView { + // Incoming + let websocket = expect_context::(); + let game_meta = expect_context::>>(); + + // Signals + let (selected_cards, set_selected_cards) = create_signal::>(vec![]); + let (card_clicked, set_card_clicked) = create_signal::(String::new()); + let (player_hand, set_player_hand) = + create_signal::>(HashMap::new()); + + // Outoging + provide_context::>(set_card_clicked); + + // On Incoming Meta // + // Put cards in a map for easier lookup + // The server sends a vec to preserve ordering + create_effect(move |_| { + if game_meta().is_some() { + for card in game_meta().unwrap().white { + set_player_hand.update(|map| { + map.insert(card.uuid.clone(), card.clone()); + }); + } + } + set_selected_cards.update(|list| { + list.clear(); + }); + }); + + // Card selection // + // Toggle selected status of cards + create_effect(move |_| { + if card_clicked() != "".to_string() { + if !selected_cards.get_untracked().contains( + player_hand + .get_untracked() + .get(&card_clicked.get_untracked()) + .unwrap(), + ) { + set_selected_cards + .update(|cards| cards.push(player_hand().get(&card_clicked()).unwrap().clone())) + } else if selected_cards + .get_untracked() + .contains(player_hand.get_untracked().get(&card_clicked()).unwrap()) + { + set_selected_cards.update(|cards| { + cards.remove( + cards + .iter() + .position(|card| card == player_hand().get(&card_clicked()).unwrap()) + .unwrap(), + ); + }) + } + // Clear the signal otherwise it selects the last selected card again + set_card_clicked.update_untracked(|value| value.clear()); + } + }); + + // Player Submit Handler // + let submit_move = move |_| { + let msg = to_string(&PlayerMoveRequest { + game_id: game_meta().unwrap().uuid.clone(), + card_ids: selected_cards() + .iter() + .map(|card| card.uuid.clone()) + .collect(), + }) + .unwrap(); + + websocket.send(&msg); + set_selected_cards.update(|list| { + list.clear(); + }); + }; + + view! { +
+ + + // Selected cards + } + } + /> +
+ + // Submit button +
+ +
+ + // Player hand +
+ + + + } + } + /> +
+ } +}