clean up/organize game
This commit is contained in:
parent
2ae4b60ed4
commit
364d293a4b
8 changed files with 346 additions and 309 deletions
|
@ -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::<WebSocketContext>();
|
||||
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::<ReadSignal<Option<GameStateMeta>>>();
|
||||
let judge_round = expect_context::<ReadSignal<Option<JudgeRound>>>();
|
||||
let user_update = expect_context::<ReadSignal<Option<UserUpdate>>>();
|
||||
|
||||
// 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());
|
||||
let (judging, set_judging) = create_signal(false);
|
||||
|
||||
// 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();
|
||||
});
|
||||
});
|
||||
|
||||
// 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::<Vec<WhiteCardMeta>>();
|
||||
|
||||
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! {
|
||||
<div class="my-2">
|
||||
<h2 class="text-2xl">Game</h2>
|
||||
|
@ -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" }
|
||||
>
|
||||
<Header game_meta=game_meta().unwrap() />
|
||||
<Header />
|
||||
</Show>
|
||||
|
||||
// Judging view //
|
||||
|
||||
<Show when=move || { judging() && connected() && game_meta().is_some() }>
|
||||
<div class="w-full ms-16 inline-flex flex-wrap">
|
||||
<BlackCard card_data=game_meta().unwrap().black />
|
||||
|
||||
// Selected cards
|
||||
<For
|
||||
each=move || selected_cards()
|
||||
key=move |card| card.uuid.clone()
|
||||
children=move |card| {
|
||||
view! { <WhiteCard card_data=card.clone() /> }
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
// Submit button
|
||||
<div class="w-full inline-flex flex-wrap justify-center">
|
||||
<button type="button" on:click=submit_judge>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Show
|
||||
when=move || { judge_round().is_some() }
|
||||
fallback=move || {
|
||||
view! {
|
||||
<p>
|
||||
"You are the czar this round. Cards will appear here once all players have submitted their cards."
|
||||
</p>
|
||||
}
|
||||
}
|
||||
>
|
||||
<For
|
||||
each=move || judge_round().unwrap().cards_to_judge
|
||||
key=move |_| 69
|
||||
children=move |group| {
|
||||
view! {
|
||||
<div class="m-2 inline-flex flex-wrap justify-center">
|
||||
<For
|
||||
each=move || group.clone()
|
||||
key=move |card| card.uuid.clone()
|
||||
children=move |card| {
|
||||
view! {
|
||||
// Hide cards from hand view when they exist as selected
|
||||
<Show when={
|
||||
let waste_of_memory = card.clone();
|
||||
move || { !selected_cards().contains(&waste_of_memory) }
|
||||
}>
|
||||
<WhiteCard card_data=card.clone() />
|
||||
</Show>
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
/>
|
||||
</Show>
|
||||
<JudgingView />
|
||||
</Show>
|
||||
|
||||
// Playing view //
|
||||
|
||||
<Show when=move || game_meta.get().is_some() && connected() && !judging()>
|
||||
|
||||
// Play cards
|
||||
<div class="w-full ms-16 inline-flex flex-wrap">
|
||||
<BlackCard card_data=game_meta().unwrap().black />
|
||||
|
||||
// Selected cards
|
||||
<For
|
||||
each=move || selected_cards()
|
||||
key=move |card| card.uuid.clone()
|
||||
children=move |card| {
|
||||
view! { <WhiteCard card_data=card.clone() /> }
|
||||
}
|
||||
/>
|
||||
</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>
|
||||
<PlayingView />
|
||||
</Show>
|
||||
</Show>
|
||||
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<ReadSignal<Option<GameStateMeta>>>();
|
||||
view! {
|
||||
<div class="relative m-2 w-40 h-60 text-white bg-black rounded-lg">
|
||||
<p class="p-4">{card_data.0}</p>
|
||||
<p class="absolute right-4 bottom-4">Pick: {card_data.1}</p>
|
||||
</div>
|
||||
<Show when=move || { game_meta().is_some() }>
|
||||
<div class="relative m-2 w-40 h-60 text-white bg-black rounded-lg">
|
||||
<p class="p-4">{game_meta().unwrap().black.0}</p>
|
||||
<p class="absolute right-4 bottom-4">Pick: {game_meta().unwrap().black.1}</p>
|
||||
</div>
|
||||
</Show>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<ReadSignal<Option<GameStateMeta>>>();
|
||||
|
||||
view! {
|
||||
<span>
|
||||
<p>Name: {move || game_meta().unwrap().name}</p>
|
||||
<p>Host: {move || game_meta().unwrap().host}</p>
|
||||
<p>Czar: {move || game_meta().unwrap().czar}</p>
|
||||
<p>White Deck: {move || game_meta().unwrap().white_count}</p>
|
||||
<p>White Discard: {move || game_meta().unwrap().white_discard_count}</p>
|
||||
<p>Black Deck: {move || game_meta().unwrap().black_count}</p>
|
||||
</span>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Scoreboard() -> impl IntoView {
|
||||
let game_meta = expect_context::<ReadSignal<Option<GameStateMeta>>>();
|
||||
|
||||
view! {
|
||||
<Show when=move || { game_meta().is_some() }>
|
||||
<span class="absolute top-0 right-0">
|
||||
<p>Players:</p>
|
||||
<table class="min-w-full border border-collapse table-auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="border-b">Name</th>
|
||||
<th class="border-b">Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{game_meta()
|
||||
.unwrap()
|
||||
.players
|
||||
.iter()
|
||||
.map(|player| {
|
||||
view! {
|
||||
<tr>
|
||||
<td class="text-center border-b">{&player.name}</td>
|
||||
<td class="text-center border-b">
|
||||
{player.score}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
})
|
||||
.collect_view()}
|
||||
</table>
|
||||
</span>
|
||||
</Show>
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn Header() -> impl IntoView {
|
||||
view! {
|
||||
<div class="relative">
|
||||
<Meta game_meta=game_meta.clone() />
|
||||
<Scoreboard game_meta=game_meta.clone() />
|
||||
<Meta />
|
||||
<Scoreboard />
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
use leptos::*;
|
||||
use lib::*;
|
||||
|
||||
#[component]
|
||||
pub fn Meta(game_meta: GameStateMeta) -> impl IntoView {
|
||||
view! {
|
||||
<span>
|
||||
<p>Name: {game_meta.name}</p>
|
||||
<p>Host: {game_meta.host}</p>
|
||||
<p>Czar: {game_meta.czar}</p>
|
||||
<p>White Deck: {game_meta.white_count.to_string()}</p>
|
||||
<p>White Discard: {move || game_meta.white_discard_count.to_string()}</p>
|
||||
<p>Black Deck: {move || game_meta.black_count.to_string()}</p>
|
||||
</span>
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
use leptos::*;
|
||||
use lib::*;
|
||||
|
||||
#[component]
|
||||
pub fn Scoreboard(game_meta: GameStateMeta) -> impl IntoView {
|
||||
view! {
|
||||
<span class="absolute top-0 right-0">
|
||||
<p>Players:</p>
|
||||
<table class="min-w-full border border-collapse table-auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="border-b">Name</th>
|
||||
<th class="border-b">Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{game_meta
|
||||
.players
|
||||
.iter()
|
||||
.map(|player| {
|
||||
view! {
|
||||
<tr>
|
||||
<td class="text-center border-b">{&player.name}</td>
|
||||
<td class="text-center border-b">{&player.score.to_string()}</td>
|
||||
</tr>
|
||||
}
|
||||
})
|
||||
.collect_view()}
|
||||
</table>
|
||||
</span>
|
||||
}
|
||||
}
|
141
client/src/components/game/views/judging.rs
Normal file
141
client/src/components/game/views/judging.rs
Normal file
|
@ -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::<WebSocketContext>();
|
||||
let game_meta = expect_context::<ReadSignal<Option<GameStateMeta>>>();
|
||||
let judge_round = expect_context::<ReadSignal<Option<JudgeRound>>>();
|
||||
|
||||
// Signals
|
||||
let (selected_cards, set_selected_cards) = create_signal::<Vec<WhiteCardMeta>>(vec![]);
|
||||
let (card_clicked, set_card_clicked) = create_signal::<String>(String::new());
|
||||
|
||||
// Outoging
|
||||
provide_context::<WriteSignal<String>>(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::<Vec<WhiteCardMeta>>();
|
||||
|
||||
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! {
|
||||
<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_judge>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Show
|
||||
when=move || { judge_round().is_some() }
|
||||
fallback=move || {
|
||||
view! {
|
||||
<p>
|
||||
"You are the czar this round. Cards will appear here once all players have submitted their cards."
|
||||
</p>
|
||||
}
|
||||
}
|
||||
>
|
||||
<For
|
||||
each=move || judge_round().unwrap().cards_to_judge
|
||||
key=move |_| 69
|
||||
children=move |group| {
|
||||
view! {
|
||||
<div class="m-2 inline-flex flex-wrap justify-center">
|
||||
<For
|
||||
each=move || group.clone()
|
||||
key=move |card| card.uuid.clone()
|
||||
children=move |card| {
|
||||
view! {
|
||||
// Hide cards from hand view when they exist as selected
|
||||
<Show when={
|
||||
let waste_of_memory = card.clone();
|
||||
move || { !selected_cards().contains(&waste_of_memory) }
|
||||
}>
|
||||
<WhiteCard card_data=card.clone() />
|
||||
</Show>
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
/>
|
||||
</Show>
|
||||
}
|
||||
}
|
2
client/src/components/game/views/mod.rs
Normal file
2
client/src/components/game/views/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
|||
pub mod judging;
|
||||
pub mod playing;
|
132
client/src/components/game/views/playing.rs
Normal file
132
client/src/components/game/views/playing.rs
Normal file
|
@ -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::<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>
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue