diff --git a/client/src/components/cards.rs b/client/src/components/cards.rs new file mode 100644 index 0000000..ad9e946 --- /dev/null +++ b/client/src/components/cards.rs @@ -0,0 +1,31 @@ +use leptos::*; +use lib::WhiteCardMeta; +use std::collections::BTreeSet; + +#[component] +pub fn BlackCard(card_data: ReadSignal<(String, u8)>) -> impl IntoView { + view! { +
+

{move || card_data().0}

+

Pick: {move || card_data().1}

+
+ } +} +#[component] +pub fn WhiteCard(card_data: WhiteCardMeta) -> impl IntoView { + let set_card_clicked = expect_context::>(); + + view! { +
+

{card_data.text}

+ +
+ } +} diff --git a/client/src/components/game.rs b/client/src/components/game.rs index 63d81d8..9b7a489 100644 --- a/client/src/components/game.rs +++ b/client/src/components/game.rs @@ -1,7 +1,9 @@ +use crate::components::cards::*; use crate::components::websocket::WebSocketContext; use leptos::*; use lib::*; use serde_json::to_string; +use std::collections::{BTreeSet, HashMap}; #[component] pub fn Game() -> impl IntoView { @@ -15,7 +17,13 @@ pub fn Game() -> impl IntoView { let (game_czar, set_game_czar) = create_signal("".to_string()); let (game_black, set_game_black) = create_signal(("".to_string(), 0u8)); let (game_white, set_game_white) = create_signal(vec![]); - let (selected_card, set_selected_card) = create_signal("".to_string()); + let (selected_cards, set_selected_cards) = + create_signal::>(HashMap::new()); + let (selected_cards_ordered, set_selected_cards_ordered) = create_signal::>(vec![]); + let (player_hand, set_player_hand) = + create_signal::>(HashMap::new()); + let (card_clicked, set_card_clicked) = create_signal::(String::new()); + provide_context::>(set_card_clicked); create_effect(move |_| { if let Some(game) = game_meta() { @@ -26,20 +34,66 @@ pub fn Game() -> impl IntoView { set_game_czar(game.czar.clone()); set_game_black(game.black.clone()); set_game_white(game.white.clone()); + for card in game.white { + set_player_hand.update(|hand| { + hand.insert(card.uuid.clone(), card.clone()); + }) + } } }); + // Move cards back and forth from hand to selected when clicked create_effect(move |_| { - logging::log!("{:#?}", selected_card()); - websocket.send( - &to_string(&PlayerMoveRequest { - game_id: game_id(), - card_id: selected_card(), - }) - .unwrap(), - ) + // Move the card + if player_hand().contains_key(&card_clicked()) { + set_selected_cards.update(|cards| { + cards.insert( + card_clicked(), + set_player_hand + .try_update(|cards| cards.remove(&card_clicked())) + .unwrap() + .unwrap(), + ); + }); + + // Track ordering + set_selected_cards_ordered.update(|list| { + list.push(card_clicked()); + }); + } else if selected_cards().contains_key(&card_clicked()) { + // Update tracking before moving the card or else the view tries to display a card that + // doesn't exist + set_selected_cards_ordered.update(|list| { + list.remove( + list.iter() + .position(|card| *card == card_clicked()) + .expect("AASSSSSSSSSSSSSS"), + ); + }); + + set_player_hand.update(|cards| { + cards.insert( + card_clicked(), + set_selected_cards + .try_update(|cards| cards.remove(&card_clicked())) + .unwrap() + .unwrap(), + ); + }); + } }); + // create_effect(move |_| { + // logging::log!("{:#?}", selected_cards()); + // websocket.send( + // &to_string(&PlayerMoveRequest { + // game_id: game_id(), + // card_ids: selected_cards(), + // }) + // .unwrap(), + // ) + // }); + view! {
@@ -62,31 +116,28 @@ pub fn Game() -> impl IntoView {
-
-

{move || game_black().0}

-

Pick: {move || game_black().1}

-
+ + + + // Card selection + + } + } + /> +
- {move || { - game_white() - .iter() - .map(|card| { - view! { -
-

{&card.text}

- -
- } - }) - .collect_view() - }} + } + } + />
diff --git a/client/src/components/mod.rs b/client/src/components/mod.rs index 03bec5c..a994774 100644 --- a/client/src/components/mod.rs +++ b/client/src/components/mod.rs @@ -1,4 +1,5 @@ pub mod auth; +pub mod cards; pub mod browser; pub mod chat; pub mod debug; diff --git a/lib/src/lib.rs b/lib/src/lib.rs index b476e15..2405652 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -1,3 +1,5 @@ +use std::collections::BTreeSet; + use serde::{Deserialize, Serialize}; /// Game join request @@ -10,7 +12,7 @@ pub struct GameJoinRequest { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct PlayerMoveRequest { pub game_id: String, - pub card_id: String, + pub card_ids: BTreeSet, } /// White Card Meta diff --git a/server/src/game_handler.rs b/server/src/game_handler.rs index 8fe62cb..acf33a7 100644 --- a/server/src/game_handler.rs +++ b/server/src/game_handler.rs @@ -25,11 +25,7 @@ pub enum GameHandlerMessage { addr: SocketAddr, id: String, }, - MoveRequest { - card_id: String, - game_id: String, - addr: SocketAddr, - }, + MoveRequest(PlayerMoveRequest, SocketAddr), } /// Handles game stuff @@ -49,16 +45,12 @@ impl GameHandler { match message { NewGame { addr, new_game } => self.create_new_game(addr, new_game).await, JoinGame { addr, id } => self.join_game(addr, id).await, - MoveRequest { - card_id, - game_id, - addr, - } => self.handle_player_move(card_id, game_id, addr).await, + MoveRequest(request, addr) => self.handle_player_move(request, addr).await, } } /// Process player move request - async fn handle_player_move(&self, card_id: String, game_id: String, addr: SocketAddr) { + async fn handle_player_move(&self, request: PlayerMoveRequest, addr: SocketAddr) { let this_player_id = self .state .online_users @@ -76,7 +68,7 @@ impl GameHandler { .games .read() .unwrap() - .get(&game_id) + .get(&request.game_id) .unwrap() .clone(); @@ -96,9 +88,9 @@ impl GameHandler { } tracing::debug!( - "Player move received:\nCard: {}\nGame: {}\nPlayer: {}", - card_id, - game_id, + "Player move received:\nCards: {:#?}\nGame: {}\nPlayer: {}", + request.card_ids, + request.game_id, this_player_id, ); } diff --git a/server/src/message_handler.rs b/server/src/message_handler.rs index c9e6b9e..32aea9a 100644 --- a/server/src/message_handler.rs +++ b/server/src/message_handler.rs @@ -68,8 +68,8 @@ impl MessageHandler { _player_move_request if let Ok(move_request) = from_str::(&text) => { - if move_request.card_id == "".to_string() { - tracing::error!("Move request card_id is empty! Ignoring..."); + if move_request.card_ids.is_empty() { + tracing::error!("Move request card_ids is empty! Ignoring..."); return; } if move_request.game_id == "".to_string() { @@ -78,11 +78,7 @@ impl MessageHandler { } else { self.state .games_tx - .send(MoveRequest { - card_id: move_request.card_id, - game_id: move_request.game_id, - addr, - }) + .send(MoveRequest(move_request, addr)) .await .unwrap(); }