163 lines
7.2 KiB
Rust
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>
|
|
}
|
|
}
|