cards/client/src/components/game/views/playing.rs

133 lines
4.4 KiB
Rust
Raw Normal View History

2024-08-28 22:39:25 -04:00
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::<WebSocketContext>();
let game_meta = expect_context::<ReadSignal<Option<GameStateMeta>>>();
// Signals
let (selected_cards, set_selected_cards) = create_signal::<Vec<WhiteCardMeta>>(vec![]);
let (card_clicked, set_card_clicked) = create_signal::<String>(String::new());
let (player_hand, set_player_hand) =
create_signal::<HashMap<String, WhiteCardMeta>>(HashMap::new());
// Outoging
provide_context::<WriteSignal<String>>(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! {
<div class="w-full ms-16 inline-flex flex-wrap">
<BlackCard />
// Selected cards
<For
each=move || selected_cards()
key=move |card| card.uuid.clone()
children=move |card| {
view! { <WhiteCard card_data=card /> }
}
/>
</div>
// Submit button
<div class="w-full inline-flex flex-wrap justify-center">
<button type="button" on:click=submit_move>
Submit
</button>
</div>
// Player hand
<div class="inline-flex flex-wrap justify-center">
<For
each=move || game_meta().unwrap().white
key=move |card| card.uuid.clone()
children=move |card| {
view! {
// Hide cards from hand view when they exist as selected
<Show when={
let id = card.uuid.clone();
move || {
if let Some(card) = player_hand().get(&id) {
!selected_cards().contains(card)
} else {
true
}
}
}>
<WhiteCard card_data=card.clone() />
</Show>
}
}
/>
</div>
}
}