cards/client/src/components/browser/create_game.rs

163 lines
7.2 KiB
Rust

use crate::components::websocket::WebSocketContext;
use leptos::{ev, prelude::*};
use leptos_use::core::ConnectionReadyState;
use lib::*;
use serde_json::to_string;
use std::collections::HashSet;
use thaw::*;
#[component]
pub fn CreateGame() -> impl IntoView {
// Websocket stuff
let websocket = expect_context::<WebSocketContext>();
let (websocket_send, set_websocket_send) = signal("".to_string());
let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open;
let tx = websocket.clone();
Effect::new(move |_| {
if websocket_send() != "".to_string() {
tx.send(&websocket_send());
}
});
// New game stuff
let card_packs = expect_context::<ReadSignal<CardPacksMeta>>();
let show_packs = RwSignal::new(false);
let selected_packs = RwSignal::<HashSet<String>>::new(HashSet::new());
Effect::new(move |_| {
selected_packs.update(|packs| {
for pack in card_packs().official_meta {
packs.insert(pack.pack);
}
for pack in card_packs().unofficial_meta {
packs.insert(pack.pack);
}
})
});
let input_game_name = RwSignal::new(String::new());
let toggle_show_packs = move |_| show_packs.set(!show_packs());
let nav_context = expect_context::<RwSignal<String>>();
let request_new_game = move |_| {
set_websocket_send(
to_string(&NewGameRequest {
name: input_game_name(),
packs: selected_packs(),
})
.unwrap(),
);
input_game_name.set(String::new());
nav_context.set("game".to_string());
};
view! {
<div class="my-2">
<h2 class="text-2xl">"Create Game"</h2>
<Show when=move || connected() fallback=|| view! { <p>"Disconnected."</p> }>
<div class="flex">
<form onsubmit="return false" on:submit=request_new_game autocomplete="off">
<FieldContextProvider>
<Field label="Game Name" name="name">
<Input
value=input_game_name
disabled=!connected()
rules=vec![InputRule::required(true.into())]
/>
</Field>
<Popover
trigger_type=PopoverTriggerType::Click
position=PopoverPosition::BottomStart
>
<PopoverTrigger slot>
<h2 class="text-2xl">
"Packs"
<Button
icon=icondata::TbHelp
button_type=ButtonType::Button
appearance=ButtonAppearance::Transparent
size=ButtonSize::Small
/>
</h2>
</PopoverTrigger>
<p>"All 205 card packs are enabled by default"</p>
</Popover>
<div class="p-2">
<Button button_type=ButtonType::Button on_click=toggle_show_packs>
"Customize"
</Button>
</div>
<Show when=move || show_packs()>
<span class="flex">
<div>
<h2 class="text-xl">Official</h2>
<CheckboxGroup value=selected_packs>
{move || {
card_packs()
.official_meta
.into_iter()
.map(|n| {
view! {
<Checkbox
label=n.name
checked=selected_packs().contains(&n.pack)
value=n.pack
/>
<br />
}
})
.collect_view()
}}
</CheckboxGroup>
</div>
<div>
<h2 class="text-xl">Unofficial</h2>
<CheckboxGroup value=selected_packs>
{move || {
card_packs()
.unofficial_meta
.into_iter()
.map(|n| {
view! {
<Checkbox
label=n.name
checked=selected_packs().contains(&n.pack)
value=n.pack
/>
<br />
}
})
.collect_view()
}}
</CheckboxGroup>
</div>
</span>
</Show>
<Button
button_type=ButtonType::Submit
on_click={
let field_context = FieldContextInjection::expect_context();
move |e: ev::MouseEvent| {
if !field_context.validate() {
e.prevent_default();
}
}
}
>
"Create Game"
</Button>
</FieldContextProvider>
</form>
</div>
</Show>
</div>
}
}