update cards display

This commit is contained in:
Adam 2024-08-18 18:48:37 -04:00
parent 2ab7a68115
commit a2a25b892f
6 changed files with 129 additions and 56 deletions

View file

@ -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! {
<div class="relative m-auto w-40 h-60 text-white bg-black rounded-lg">
<p class="p-4">{move || card_data().0}</p>
<p class="absolute right-4 bottom-4">Pick: {move || card_data().1}</p>
</div>
}
}
#[component]
pub fn WhiteCard(card_data: WhiteCardMeta) -> impl IntoView {
let set_card_clicked = expect_context::<WriteSignal<String>>();
view! {
<div class="relative m-2 w-40 h-60 text-black bg-white rounded-lg">
<p class="p-4">{card_data.text}</p>
<button
class="absolute w-full h-full opacity-10 left-0 top-0"
type="button"
value=card_data.uuid.clone()
on:click=move |e| {
set_card_clicked(event_target_value(&e));
}
></button>
</div>
}
}

View file

@ -1,7 +1,9 @@
use crate::components::cards::*;
use crate::components::websocket::WebSocketContext; use crate::components::websocket::WebSocketContext;
use leptos::*; use leptos::*;
use lib::*; use lib::*;
use serde_json::to_string; use serde_json::to_string;
use std::collections::{BTreeSet, HashMap};
#[component] #[component]
pub fn Game() -> impl IntoView { 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_czar, set_game_czar) = create_signal("".to_string());
let (game_black, set_game_black) = create_signal(("".to_string(), 0u8)); let (game_black, set_game_black) = create_signal(("".to_string(), 0u8));
let (game_white, set_game_white) = create_signal(vec![]); 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<String, WhiteCardMeta>>(HashMap::new());
let (selected_cards_ordered, set_selected_cards_ordered) = create_signal::<Vec<String>>(vec![]);
let (player_hand, set_player_hand) =
create_signal::<HashMap<String, WhiteCardMeta>>(HashMap::new());
let (card_clicked, set_card_clicked) = create_signal::<String>(String::new());
provide_context::<WriteSignal<String>>(set_card_clicked);
create_effect(move |_| { create_effect(move |_| {
if let Some(game) = game_meta() { if let Some(game) = game_meta() {
@ -26,20 +34,66 @@ pub fn Game() -> impl IntoView {
set_game_czar(game.czar.clone()); set_game_czar(game.czar.clone());
set_game_black(game.black.clone()); set_game_black(game.black.clone());
set_game_white(game.white.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 |_| { create_effect(move |_| {
logging::log!("{:#?}", selected_card()); // Move the card
websocket.send( if player_hand().contains_key(&card_clicked()) {
&to_string(&PlayerMoveRequest { set_selected_cards.update(|cards| {
game_id: game_id(), cards.insert(
card_id: selected_card(), card_clicked(),
}) set_player_hand
.unwrap(), .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! { view! {
<div class="p-1"> <div class="p-1">
<div class="relative"> <div class="relative">
@ -62,31 +116,28 @@ pub fn Game() -> impl IntoView {
</ul> </ul>
</span> </span>
</div> </div>
<div class="relative m-auto w-40 h-60 text-white bg-black rounded-lg"> <span class="flex">
<p class="p-4">{move || game_black().0}</p> <BlackCard card_data=game_black />
<p class="absolute right-4 bottom-4">Pick: {move || game_black().1}</p>
</div> // Card selection
<For
each=move || selected_cards_ordered()
key=move |card| selected_cards().get(card).unwrap().uuid.clone()
children=move |card| {
view! {
<WhiteCard card_data=selected_cards().get(&card).unwrap().clone() />
}
}
/>
</span>
<div class="inline-flex flex-wrap justify-center"> <div class="inline-flex flex-wrap justify-center">
{move || { <For
game_white() each=move || player_hand()
.iter() key=|card| card.0.clone()
.map(|card| { children=move |card| {
view! { view! { <WhiteCard card_data=card.1 /> }
<div class="relative m-2 w-40 h-60 text-black bg-white rounded-lg"> }
<p class="p-4">{&card.text}</p> />
<button
class="absolute w-full h-full opacity-10 left-0 top-0"
type="button"
value=card.uuid.clone()
on:click=move |e| {
set_selected_card(event_target_value(&e))
}
></button>
</div>
}
})
.collect_view()
}}
</div> </div>
</div> </div>

View file

@ -1,4 +1,5 @@
pub mod auth; pub mod auth;
pub mod cards;
pub mod browser; pub mod browser;
pub mod chat; pub mod chat;
pub mod debug; pub mod debug;

View file

@ -1,3 +1,5 @@
use std::collections::BTreeSet;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Game join request /// Game join request
@ -10,7 +12,7 @@ pub struct GameJoinRequest {
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PlayerMoveRequest { pub struct PlayerMoveRequest {
pub game_id: String, pub game_id: String,
pub card_id: String, pub card_ids: BTreeSet<String>,
} }
/// White Card Meta /// White Card Meta

View file

@ -25,11 +25,7 @@ pub enum GameHandlerMessage {
addr: SocketAddr, addr: SocketAddr,
id: String, id: String,
}, },
MoveRequest { MoveRequest(PlayerMoveRequest, SocketAddr),
card_id: String,
game_id: String,
addr: SocketAddr,
},
} }
/// Handles game stuff /// Handles game stuff
@ -49,16 +45,12 @@ impl GameHandler {
match message { match message {
NewGame { addr, new_game } => self.create_new_game(addr, new_game).await, NewGame { addr, new_game } => self.create_new_game(addr, new_game).await,
JoinGame { addr, id } => self.join_game(addr, id).await, JoinGame { addr, id } => self.join_game(addr, id).await,
MoveRequest { MoveRequest(request, addr) => self.handle_player_move(request, addr).await,
card_id,
game_id,
addr,
} => self.handle_player_move(card_id, game_id, addr).await,
} }
} }
/// Process player move request /// 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 let this_player_id = self
.state .state
.online_users .online_users
@ -76,7 +68,7 @@ impl GameHandler {
.games .games
.read() .read()
.unwrap() .unwrap()
.get(&game_id) .get(&request.game_id)
.unwrap() .unwrap()
.clone(); .clone();
@ -96,9 +88,9 @@ impl GameHandler {
} }
tracing::debug!( tracing::debug!(
"Player move received:\nCard: {}\nGame: {}\nPlayer: {}", "Player move received:\nCards: {:#?}\nGame: {}\nPlayer: {}",
card_id, request.card_ids,
game_id, request.game_id,
this_player_id, this_player_id,
); );
} }

View file

@ -68,8 +68,8 @@ impl MessageHandler {
_player_move_request _player_move_request
if let Ok(move_request) = from_str::<PlayerMoveRequest>(&text) => if let Ok(move_request) = from_str::<PlayerMoveRequest>(&text) =>
{ {
if move_request.card_id == "".to_string() { if move_request.card_ids.is_empty() {
tracing::error!("Move request card_id is empty! Ignoring..."); tracing::error!("Move request card_ids is empty! Ignoring...");
return; return;
} }
if move_request.game_id == "".to_string() { if move_request.game_id == "".to_string() {
@ -78,11 +78,7 @@ impl MessageHandler {
} else { } else {
self.state self.state
.games_tx .games_tx
.send(MoveRequest { .send(MoveRequest(move_request, addr))
card_id: move_request.card_id,
game_id: move_request.game_id,
addr,
})
.await .await
.unwrap(); .unwrap();
} }