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;
|
2024-08-30 01:20:54 -04:00
|
|
|
use std::collections::{HashMap, HashSet};
|
2024-08-28 22:39:25 -04:00
|
|
|
|
|
|
|
#[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![]);
|
2024-08-30 01:20:54 -04:00
|
|
|
let (submitted_cards, set_submitted_cards) =
|
|
|
|
create_signal::<HashSet<WhiteCardMeta>>(HashSet::new());
|
2024-08-28 22:39:25 -04:00
|
|
|
let (card_clicked, set_card_clicked) = create_signal::<String>(String::new());
|
2024-08-29 01:11:49 -04:00
|
|
|
let (submitted, set_submitted) = create_signal(false);
|
2024-08-28 22:39:25 -04:00
|
|
|
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();
|
|
|
|
});
|
2024-08-29 01:11:49 -04:00
|
|
|
set_submitted_cards.update(|list| {
|
|
|
|
list.clear();
|
|
|
|
});
|
|
|
|
set_submitted(false);
|
2024-08-28 22:39:25 -04:00
|
|
|
});
|
|
|
|
|
2024-08-29 01:11:49 -04:00
|
|
|
// Card selection
|
2024-08-28 22:39:25 -04:00
|
|
|
// Toggle selected status of cards
|
|
|
|
create_effect(move |_| {
|
2024-08-29 01:11:49 -04:00
|
|
|
if card_clicked() != "".to_string()
|
2024-09-02 15:04:32 -04:00
|
|
|
&& !submitted()
|
2024-08-29 01:11:49 -04:00
|
|
|
&& submitted_cards().len() < game_meta().unwrap().black.1.into()
|
|
|
|
{
|
|
|
|
if let Some(clicked_card) = player_hand
|
2024-08-28 22:39:25 -04:00
|
|
|
.get_untracked()
|
2024-08-29 01:11:49 -04:00
|
|
|
.get(&card_clicked.get_untracked())
|
2024-08-28 22:39:25 -04:00
|
|
|
{
|
2024-08-29 01:11:49 -04:00
|
|
|
if !selected_cards.get_untracked().contains(clicked_card) {
|
|
|
|
set_selected_cards.update(|cards| cards.push(clicked_card.to_owned()))
|
|
|
|
} else if selected_cards.get_untracked().contains(clicked_card)
|
|
|
|
&& !submitted_cards.get_untracked().contains(clicked_card)
|
|
|
|
{
|
|
|
|
set_selected_cards.update(|cards| {
|
|
|
|
cards.remove(cards.iter().position(|card| card == clicked_card).unwrap());
|
|
|
|
})
|
|
|
|
}
|
2024-08-28 22:39:25 -04:00
|
|
|
}
|
|
|
|
// 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();
|
|
|
|
|
2024-08-29 01:11:49 -04:00
|
|
|
set_submitted_cards.update_untracked(|cards| {
|
2024-08-30 01:20:54 -04:00
|
|
|
for card in selected_cards.get_untracked() {
|
|
|
|
cards.insert(card);
|
|
|
|
}
|
2024-08-29 01:11:49 -04:00
|
|
|
});
|
|
|
|
|
2024-08-30 01:20:54 -04:00
|
|
|
if submitted_cards().len() < game_meta().unwrap().black.1.into() {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-08-28 22:39:25 -04:00
|
|
|
websocket.send(&msg);
|
2024-08-29 01:11:49 -04:00
|
|
|
set_selected_cards.update_untracked(|list| {
|
2024-08-28 22:39:25 -04:00
|
|
|
list.clear();
|
|
|
|
});
|
2024-08-29 01:11:49 -04:00
|
|
|
set_submitted(true);
|
2024-08-28 22:39:25 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
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 /> }
|
|
|
|
}
|
|
|
|
/>
|
2024-09-02 15:04:32 -04:00
|
|
|
|
2024-08-28 22:39:25 -04:00
|
|
|
</div>
|
|
|
|
|
|
|
|
// Submit button
|
|
|
|
<div class="w-full inline-flex flex-wrap justify-center">
|
2024-08-30 00:16:55 -04:00
|
|
|
<Show
|
|
|
|
when=move || !submitted()
|
|
|
|
fallback=move || {
|
|
|
|
view! { <p>"Card(s) submitted. Waiting for other players..."</p> }
|
|
|
|
}
|
|
|
|
>
|
2024-09-02 15:04:32 -04:00
|
|
|
|
2024-08-30 00:16:55 -04:00
|
|
|
<button type="button" on:click=submit_move.clone()>
|
|
|
|
Submit
|
|
|
|
</button>
|
|
|
|
</Show>
|
2024-08-28 22:39:25 -04:00
|
|
|
</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! {
|
2024-08-29 01:11:49 -04:00
|
|
|
// Hide cards from hand view when they exist as selected or submitted
|
2024-08-28 22:39:25 -04:00
|
|
|
<Show when={
|
|
|
|
let id = card.uuid.clone();
|
|
|
|
move || {
|
|
|
|
if let Some(card) = player_hand().get(&id) {
|
|
|
|
!selected_cards().contains(card)
|
2024-08-29 01:11:49 -04:00
|
|
|
&& !submitted_cards().contains(card)
|
2024-08-28 22:39:25 -04:00
|
|
|
} else {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}>
|
|
|
|
<WhiteCard card_data=card.clone() />
|
|
|
|
</Show>
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/>
|
2024-09-02 15:04:32 -04:00
|
|
|
|
2024-08-28 22:39:25 -04:00
|
|
|
</div>
|
|
|
|
}
|
|
|
|
}
|