migrate to leptos 0.7
This commit is contained in:
parent
f22f1a00a9
commit
0de020ac39
19 changed files with 695 additions and 396 deletions
731
Cargo.lock
generated
731
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -7,18 +7,19 @@ authors = ["Adam Doyle <adam@doordesk.net>"]
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
leptos = { version = "0.6", features = ["csr", "nightly"] }
|
||||
leptos_meta = { version = "0.6", features = ["csr", "nightly"] }
|
||||
leptos_router = { version = "0.6", features = ["csr", "nightly"] }
|
||||
leptos = { version = "0.7.0-beta", features = ["csr", "nightly"] }
|
||||
leptos_meta = { version = "0.7.0-beta" }
|
||||
leptos_router = { version = "0.7.0-beta", features = ["nightly"] }
|
||||
console_error_panic_hook = "0.1"
|
||||
console_log = "1"
|
||||
log = "0.4"
|
||||
|
||||
leptos-use = "0.13"
|
||||
leptos-use = "0.14.0-beta"
|
||||
codee = "0.2"
|
||||
|
||||
lib = { workspace = true }
|
||||
serde_json = "1.0"
|
||||
thaw = { version = "0.4.0-beta2", features = ["csr", "nightly"] }
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen = "0.2"
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!-- Add a plain CSS file: see https://trunkrs.dev/assets/#css -->
|
||||
<!-- If using Tailwind with Leptos CSR, see https://trunkrs.dev/assets/#tailwind instead-->
|
||||
<link data-trunk rel="tailwind-css" href="public/styles.css" />
|
||||
|
||||
<!-- Include favicon in dist output: see https://trunkrs.dev/assets/#icon -->
|
||||
<link data-trunk rel="icon" href="public/favicon.ico" />
|
||||
|
||||
<!-- include support for `wasm-bindgen --weak-refs` - see: https://rustwasm.github.io/docs/wasm-bindgen/reference/weak-references.html -->
|
||||
<meta charset="utf-8" />
|
||||
<link data-trunk rel="rust" data-target-path="client" data-wasm-opt="z" data-weak-refs />
|
||||
<link data-trunk rel="icon" href="public/favicon.ico" />
|
||||
<link data-trunk rel="tailwind-css" href="public/styles.css" />
|
||||
<title>Cards for Humanity</title>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
html,
|
||||
body {
|
||||
@apply text-neutral-200;
|
||||
@apply text-neutral-200 bg-neutral-900;
|
||||
font-family: "Inter", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 400;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::components::websocket::WebSocketContext;
|
||||
use html::Input;
|
||||
use leptos::*;
|
||||
use leptos::{html::Input, prelude::*};
|
||||
use leptos_use::core::ConnectionReadyState;
|
||||
use lib::*;
|
||||
use serde_json::to_string;
|
||||
|
@ -8,11 +7,11 @@ use serde_json::to_string;
|
|||
#[component]
|
||||
pub fn Auth() -> impl IntoView {
|
||||
let websocket = expect_context::<WebSocketContext>();
|
||||
let (username, set_username) = create_signal("".to_string());
|
||||
let (username, set_username) = signal("".to_string());
|
||||
let user_context = expect_context::<ReadSignal<Option<UserUpdate>>>();
|
||||
let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open;
|
||||
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
user_context.with(|new_user| {
|
||||
if let Some(user) = new_user {
|
||||
set_username(user.username.to_string());
|
||||
|
@ -20,7 +19,7 @@ pub fn Auth() -> impl IntoView {
|
|||
})
|
||||
});
|
||||
|
||||
let username_input_ref = create_node_ref::<Input>();
|
||||
let username_input_ref = NodeRef::<Input>::new();
|
||||
let send_login = move |_| {
|
||||
if let Some(input) = username_input_ref.get() {
|
||||
if input.value() != String::from("") {
|
||||
|
@ -37,7 +36,7 @@ pub fn Auth() -> impl IntoView {
|
|||
};
|
||||
|
||||
// Clear user name on disconnect
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
if !connected() {
|
||||
set_username(String::from(""));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::components::websocket::WebSocketContext;
|
||||
use leptos::*;
|
||||
use leptos::prelude::*;
|
||||
use leptos_use::core::ConnectionReadyState;
|
||||
use lib::*;
|
||||
use serde_json::to_string;
|
||||
|
@ -11,9 +11,9 @@ pub fn Browser() -> impl IntoView {
|
|||
let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open;
|
||||
|
||||
let tx = websocket.clone();
|
||||
let (websocket_send, set_websocket_send) = create_signal("".to_string());
|
||||
let (websocket_send, set_websocket_send) = signal("".to_string());
|
||||
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
if websocket_send() != "".to_string() {
|
||||
tx.send(&websocket_send());
|
||||
}
|
||||
|
@ -21,14 +21,14 @@ pub fn Browser() -> impl IntoView {
|
|||
|
||||
// Browser stuff
|
||||
let game_browser_context = expect_context::<ReadSignal<Vec<GameBrowserMeta>>>();
|
||||
let (join_id, set_join_id) = create_signal("".to_string());
|
||||
let (delete_id, set_delete_id) = create_signal("".to_string());
|
||||
let (join_id, set_join_id) = signal("".to_string());
|
||||
let (delete_id, set_delete_id) = signal("".to_string());
|
||||
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
set_websocket_send(to_string(&GameJoinRequest { id: join_id() }).unwrap());
|
||||
});
|
||||
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
set_websocket_send(
|
||||
to_string(&GameDeleteRequest {
|
||||
delete_game_id: delete_id(),
|
||||
|
@ -74,7 +74,7 @@ pub fn Browser() -> impl IntoView {
|
|||
<td class="text-center border-b">
|
||||
<button
|
||||
type="button"
|
||||
value=&game.uuid
|
||||
value=game.uuid.clone()
|
||||
on:click=move |e| {
|
||||
set_join_id(event_target_value(&e));
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ pub fn Browser() -> impl IntoView {
|
|||
</button>
|
||||
<button
|
||||
type="button"
|
||||
value=&game.uuid
|
||||
value=game.uuid.clone()
|
||||
on:click=move |e| {
|
||||
set_delete_id(event_target_value(&e));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use crate::components::websocket::WebSocketContext;
|
||||
use html::{Input, Textarea};
|
||||
use leptos::*;
|
||||
use leptos::{
|
||||
html::{Input, Textarea},
|
||||
prelude::*,
|
||||
};
|
||||
use leptos_use::core::ConnectionReadyState;
|
||||
use lib::*;
|
||||
use serde_json::to_string;
|
||||
|
@ -13,18 +15,18 @@ pub fn Chat() -> impl IntoView {
|
|||
let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open;
|
||||
|
||||
// Chat stuff
|
||||
let (chat_history, set_chat_history) = create_signal::<Vec<String>>(vec![]);
|
||||
let (users, set_users) = create_signal::<Vec<String>>(vec![]);
|
||||
let (chat_name, set_chat_name) = create_signal::<String>("".to_string());
|
||||
let chat_history_ref = create_node_ref::<Textarea>();
|
||||
let chat_input_ref = create_node_ref::<Input>();
|
||||
let (chat_history, set_chat_history) = signal::<Vec<String>>(vec![]);
|
||||
let (users, set_users) = signal::<Vec<String>>(vec![]);
|
||||
let (chat_name, set_chat_name) = signal::<String>("".to_string());
|
||||
let chat_history_ref = NodeRef::<Textarea>::new();
|
||||
let chat_input_ref = NodeRef::<Input>::new();
|
||||
|
||||
fn update_chat_history(&history: &WriteSignal<Vec<String>>, message: String) {
|
||||
let _ = &history.update(|history: &mut Vec<_>| history.push(message));
|
||||
}
|
||||
|
||||
// Connection status updates in chat window
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
websocket.ready_state.with(move |state| match *state {
|
||||
ConnectionReadyState::Connecting => {
|
||||
update_chat_history(
|
||||
|
@ -45,7 +47,7 @@ pub fn Chat() -> impl IntoView {
|
|||
});
|
||||
|
||||
// Handle incoming chat messages
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
chat_context.with(move |chat_message| {
|
||||
if let Some(message) = chat_message {
|
||||
update_chat_history(&set_chat_history, format!("{}\n", message.text));
|
||||
|
@ -54,7 +56,7 @@ pub fn Chat() -> impl IntoView {
|
|||
});
|
||||
|
||||
// Handle users
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
chat_update_context.with(move |chat_update| {
|
||||
if let Some(update) = chat_update {
|
||||
set_users(update.users.clone());
|
||||
|
@ -64,7 +66,7 @@ pub fn Chat() -> impl IntoView {
|
|||
});
|
||||
|
||||
// Clear user list on disconnect
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
websocket.ready_state.with(move |status| {
|
||||
if *status == ConnectionReadyState::Closed {
|
||||
set_users(vec![]);
|
||||
|
@ -88,7 +90,7 @@ pub fn Chat() -> impl IntoView {
|
|||
};
|
||||
|
||||
// Keep chat scrolled to the bottom
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
chat_history.with(move |_| {
|
||||
// Scroll chat textarea to bottom
|
||||
if let Some(hist) = chat_history_ref.get() {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::components::websocket::WebSocketContext;
|
||||
use leptos::html::Input;
|
||||
use leptos::*;
|
||||
use leptos::{html::Input, prelude::*};
|
||||
use leptos_use::core::ConnectionReadyState;
|
||||
use lib::*;
|
||||
use serde_json::to_string;
|
||||
|
@ -10,12 +9,12 @@ use std::collections::BTreeSet;
|
|||
pub fn CreateGame() -> impl IntoView {
|
||||
// Websocket stuff
|
||||
let websocket = expect_context::<WebSocketContext>();
|
||||
let (websocket_send, set_websocket_send) = create_signal("".to_string());
|
||||
let (websocket_send, set_websocket_send) = signal("".to_string());
|
||||
|
||||
let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open;
|
||||
|
||||
let tx = websocket.clone();
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
if websocket_send() != "".to_string() {
|
||||
tx.send(&websocket_send());
|
||||
}
|
||||
|
@ -24,29 +23,29 @@ pub fn CreateGame() -> impl IntoView {
|
|||
// New game stuff
|
||||
let card_packs = expect_context::<ReadSignal<CardPacksMeta>>();
|
||||
|
||||
let (show_packs, set_show_packs) = create_signal(false);
|
||||
let (selected_packs, set_selected_packs) = create_signal::<BTreeSet<u8>>(BTreeSet::new());
|
||||
let (show_packs, set_show_packs) = signal(false);
|
||||
let (selected_packs, set_selected_packs) = signal::<BTreeSet<u8>>(BTreeSet::new());
|
||||
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
set_selected_packs
|
||||
.update(|set| set.extend(card_packs().official_meta.iter().map(|pack| pack.pack)));
|
||||
});
|
||||
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
set_selected_packs
|
||||
.update(|set| set.extend(card_packs().unofficial_meta.iter().map(|pack| pack.pack)));
|
||||
});
|
||||
|
||||
let new_game_name_ref = create_node_ref::<Input>();
|
||||
let new_game_name_ref = NodeRef::<Input>::new();
|
||||
|
||||
let toggle_show_packs = move |_| set_show_packs(!show_packs());
|
||||
|
||||
let request_new_game = move |_| {
|
||||
if let Some(input) = new_game_name_ref.get() {
|
||||
if input.value() == *"" {
|
||||
logging::error!("New game name is empty!");
|
||||
println!("New game name is empty!");
|
||||
} else if selected_packs().is_empty() {
|
||||
logging::error!("New game selected packs is empty!");
|
||||
println!("New game selected packs is empty!");
|
||||
} else {
|
||||
set_websocket_send(
|
||||
to_string(&NewGameRequest {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::components::websocket::WebSocketContext;
|
||||
use leptos::*;
|
||||
use leptos::prelude::*;
|
||||
use leptos_use::core::ConnectionReadyState;
|
||||
use lib::*;
|
||||
|
||||
|
@ -9,8 +9,8 @@ pub fn Debug() -> impl IntoView {
|
|||
let state_summary = expect_context::<ReadSignal<Option<ServerStateSummary>>>();
|
||||
|
||||
// Signals
|
||||
let (online_users, set_online_users) = create_signal(0);
|
||||
let (active_games, set_active_games) = create_signal(0);
|
||||
let (online_users, set_online_users) = signal(0);
|
||||
let (active_games, set_active_games) = signal(0);
|
||||
|
||||
// Websocket stuff
|
||||
let status = move || websocket.ready_state.get().to_string();
|
||||
|
@ -26,7 +26,7 @@ pub fn Debug() -> impl IntoView {
|
|||
};
|
||||
|
||||
// Update server info -> move this to a new component
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
state_summary.with(move |state_summary| {
|
||||
if let Some(state_summary) = state_summary {
|
||||
set_online_users(state_summary.online_users);
|
||||
|
|
|
@ -2,7 +2,7 @@ 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::prelude::*;
|
||||
use leptos_use::core::ConnectionReadyState;
|
||||
use lib::*;
|
||||
pub mod cards;
|
||||
|
@ -20,10 +20,10 @@ pub fn Game() -> impl IntoView {
|
|||
let user_update = expect_context::<ReadSignal<Option<UserUpdate>>>();
|
||||
|
||||
// Signals //
|
||||
let (judging, set_judging) = create_signal(false);
|
||||
let (judging, set_judging) = signal(false);
|
||||
|
||||
// Determine judging
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
user_update.with(move |user_meta| {
|
||||
if let Some(user_meta) = user_meta {
|
||||
if let Some(game_meta) = game_meta() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use leptos::*;
|
||||
use leptos::prelude::*;
|
||||
use lib::*;
|
||||
|
||||
#[component]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use leptos::*;
|
||||
use leptos::prelude::*;
|
||||
use lib::*;
|
||||
|
||||
#[component]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::components::game::cards::*;
|
||||
use crate::components::websocket::WebSocketContext;
|
||||
use leptos::*;
|
||||
use leptos::prelude::*;
|
||||
use lib::*;
|
||||
use serde_json::to_string;
|
||||
|
||||
|
@ -13,14 +13,14 @@ pub fn JudgingView() -> impl IntoView {
|
|||
let set_judge_round = expect_context::<WriteSignal<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());
|
||||
let (selected_cards, set_selected_cards) = signal::<Vec<WhiteCardMeta>>(vec![]);
|
||||
let (card_clicked, set_card_clicked) = signal::<String>(String::new());
|
||||
|
||||
// Outoging
|
||||
provide_context::<WriteSignal<String>>(set_card_clicked);
|
||||
|
||||
// On Incoming Judge
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
// Clear selected cards
|
||||
if judge_round().is_some() {
|
||||
set_selected_cards.update(|list| {
|
||||
|
@ -31,7 +31,7 @@ pub fn JudgingView() -> impl IntoView {
|
|||
|
||||
// Card selection //
|
||||
// Toggle selected status of cards
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
if card_clicked() != "".to_string() {
|
||||
let identical_cards = selected_cards
|
||||
.get_untracked()
|
||||
|
@ -86,15 +86,15 @@ pub fn JudgingView() -> impl IntoView {
|
|||
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 /> }
|
||||
}
|
||||
/>
|
||||
{move || {
|
||||
selected_cards()
|
||||
.into_iter()
|
||||
.map(|card| {
|
||||
view! { <WhiteCard card_data=card /> }
|
||||
})
|
||||
.collect_view()
|
||||
}}
|
||||
</div>
|
||||
|
||||
// Submit button
|
||||
|
@ -114,18 +114,17 @@ pub fn JudgingView() -> impl IntoView {
|
|||
}
|
||||
}
|
||||
>
|
||||
<For
|
||||
each=move || judge_round().unwrap().cards_to_judge
|
||||
key=move |_| 69
|
||||
children=move |group| {
|
||||
{judge_round()
|
||||
.unwrap()
|
||||
.cards_to_judge
|
||||
.into_iter()
|
||||
.map(|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| {
|
||||
{group
|
||||
.into_iter()
|
||||
.map(|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) }
|
||||
|
@ -133,12 +132,12 @@ pub fn JudgingView() -> impl IntoView {
|
|||
<WhiteCard card_data=card.clone() />
|
||||
</Show>
|
||||
}
|
||||
}
|
||||
/>
|
||||
})
|
||||
.collect_view()}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
/>
|
||||
})
|
||||
.collect_view()}
|
||||
</Show>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::components::game::cards::*;
|
||||
use crate::components::websocket::WebSocketContext;
|
||||
use leptos::*;
|
||||
use leptos::prelude::*;
|
||||
use lib::*;
|
||||
use serde_json::to_string;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
@ -13,13 +13,11 @@ pub fn PlayingView() -> impl IntoView {
|
|||
let game_state = expect_context::<ReadSignal<Option<GameStateMeta>>>();
|
||||
|
||||
// Signals
|
||||
let (selected_cards, set_selected_cards) = create_signal::<Vec<WhiteCardMeta>>(vec![]);
|
||||
let (submitted_cards, set_submitted_cards) =
|
||||
create_signal::<HashSet<WhiteCardMeta>>(HashSet::new());
|
||||
let (card_clicked, set_card_clicked) = create_signal::<String>(String::new());
|
||||
let (submitted, set_submitted) = create_signal(false);
|
||||
let (player_hand, set_player_hand) =
|
||||
create_signal::<HashMap<String, WhiteCardMeta>>(HashMap::new());
|
||||
let (selected_cards, set_selected_cards) = signal::<Vec<WhiteCardMeta>>(vec![]);
|
||||
let (submitted_cards, set_submitted_cards) = signal::<HashSet<WhiteCardMeta>>(HashSet::new());
|
||||
let (card_clicked, set_card_clicked) = signal::<String>(String::new());
|
||||
let (submitted, set_submitted) = signal(false);
|
||||
let (player_hand, set_player_hand) = signal::<HashMap<String, WhiteCardMeta>>(HashMap::new());
|
||||
|
||||
// Outoging
|
||||
provide_context::<WriteSignal<String>>(set_card_clicked);
|
||||
|
@ -27,7 +25,7 @@ pub fn PlayingView() -> impl IntoView {
|
|||
// On Incoming Meta //
|
||||
// Put cards in a map for easier lookup
|
||||
// The server sends a vec to preserve ordering
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
if game_state().is_some() {
|
||||
for card in game_state().unwrap().white {
|
||||
set_player_hand.update(|map| {
|
||||
|
@ -46,7 +44,7 @@ pub fn PlayingView() -> impl IntoView {
|
|||
|
||||
// Card selection
|
||||
// Toggle selected status of cards
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
if card_clicked() != "".to_string()
|
||||
&& !submitted()
|
||||
&& submitted_cards().len() < game_state().unwrap().black.1.into()
|
||||
|
@ -102,15 +100,12 @@ pub fn PlayingView() -> impl IntoView {
|
|||
<div class="w-full inline-flex flex-wrap">
|
||||
<BlackCard />
|
||||
|
||||
// Selected cards
|
||||
<For
|
||||
each=move || selected_cards()
|
||||
key=move |card| card.uuid.clone()
|
||||
children=move |card| {
|
||||
{move || selected_cards()
|
||||
.into_iter()
|
||||
.map(|card| {
|
||||
view! { <WhiteCard card_data=card /> }
|
||||
}
|
||||
/>
|
||||
|
||||
})
|
||||
.collect_view()}
|
||||
</div>
|
||||
|
||||
// Submit button
|
||||
|
@ -130,13 +125,15 @@ pub fn PlayingView() -> impl IntoView {
|
|||
|
||||
// Player hand
|
||||
<div class="inline-flex flex-wrap justify-center">
|
||||
<Show when=move || game_state().is_some()>
|
||||
<For
|
||||
each=move || game_state().unwrap().white
|
||||
key=move |card| card.uuid.clone()
|
||||
children=move |card| {
|
||||
<Show when=move || {
|
||||
game_state().is_some()
|
||||
}>
|
||||
{game_state()
|
||||
.unwrap()
|
||||
.white
|
||||
.into_iter()
|
||||
.map(|card| {
|
||||
view! {
|
||||
// Hide cards from hand view when they exist as selected or submitted
|
||||
<Show when={
|
||||
let id = card.uuid.clone();
|
||||
move || {
|
||||
|
@ -151,10 +148,9 @@ pub fn PlayingView() -> impl IntoView {
|
|||
<WhiteCard card_data=card.clone() />
|
||||
</Show>
|
||||
}
|
||||
}
|
||||
/>
|
||||
})
|
||||
.collect_view()}
|
||||
</Show>
|
||||
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
use codee::string::FromToStringCodec;
|
||||
use leptos::*;
|
||||
use leptos::prelude::*;
|
||||
use leptos_use::{core::ConnectionReadyState, use_websocket, UseWebSocketReturn};
|
||||
use lib::*;
|
||||
use serde_json::from_str;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WebSocketContext {
|
||||
pub ready_state: Signal<ConnectionReadyState>,
|
||||
// pub message: Signal<Option<String>>,
|
||||
send: Rc<dyn Fn(&String)>,
|
||||
pub open: Rc<dyn Fn()>,
|
||||
pub close: Rc<dyn Fn()>,
|
||||
send: Arc<dyn Fn(&String) + Send + Sync + 'static>,
|
||||
pub open: Arc<dyn Fn() + Send + Sync + 'static>,
|
||||
pub close: Arc<dyn Fn() + Send + Sync + 'static>,
|
||||
}
|
||||
|
||||
impl WebSocketContext {
|
||||
pub fn new(
|
||||
ready_state: Signal<ConnectionReadyState>,
|
||||
// message: Signal<Option<String>>,
|
||||
send: Rc<dyn Fn(&String)>,
|
||||
open: Rc<dyn Fn()>,
|
||||
close: Rc<dyn Fn()>,
|
||||
send: Arc<dyn Fn(&String) + Send + Sync + 'static>,
|
||||
open: Arc<dyn Fn() + Send + Sync + 'static>,
|
||||
close: Arc<dyn Fn() + Send + Sync + 'static>,
|
||||
) -> Self {
|
||||
Self {
|
||||
ready_state,
|
||||
|
@ -59,38 +59,37 @@ pub fn Websocket() -> impl IntoView {
|
|||
provide_context(WebSocketContext::new(
|
||||
ready_state,
|
||||
// message,
|
||||
Rc::new(send.clone()),
|
||||
Rc::new(open.clone()),
|
||||
Rc::new(close.clone()),
|
||||
Arc::new(send.clone()),
|
||||
Arc::new(open.clone()),
|
||||
Arc::new(close.clone()),
|
||||
));
|
||||
|
||||
let connected = move || ready_state.get() == ConnectionReadyState::Open;
|
||||
|
||||
// Contexts for message handler
|
||||
// TODO: This context stuff can probably be done better
|
||||
let (state_summary, set_state_summary) =
|
||||
create_signal::<Option<ServerStateSummary>>(Option::None);
|
||||
let (active_games, set_active_games) = create_signal::<Vec<GameBrowserMeta>>(vec![]);
|
||||
let (user_update, set_user_update) = create_signal::<Option<UserUpdate>>(Option::None);
|
||||
let (chat_update, set_chat_update) = create_signal::<Option<ChatUpdate>>(Option::None);
|
||||
let (judge_round, set_judge_round) = create_signal::<Option<JudgeRound>>(Option::None);
|
||||
let (chat_message, set_chat_message) = create_signal::<Option<ChatMessage>>(Option::None);
|
||||
let (game_meta, set_game_meta) = create_signal::<Option<GameMeta>>(Option::None);
|
||||
let (game_state, set_game_state) = create_signal::<Option<GameStateMeta>>(Option::None);
|
||||
let (card_packs_meta, set_card_packs_meta) = create_signal::<CardPacksMeta>(CardPacksMeta {
|
||||
let (state_summary, set_state_summary) = signal::<Option<ServerStateSummary>>(Option::None);
|
||||
let (active_games, set_active_games) = signal::<Vec<GameBrowserMeta>>(vec![]);
|
||||
let (user_update, set_user_update) = signal::<Option<UserUpdate>>(Option::None);
|
||||
let (chat_update, set_chat_update) = signal::<Option<ChatUpdate>>(Option::None);
|
||||
let (judge_round, set_judge_round) = signal::<Option<JudgeRound>>(Option::None);
|
||||
let (chat_message, set_chat_message) = signal::<Option<ChatMessage>>(Option::None);
|
||||
let (game_meta, set_game_meta) = signal::<Option<GameMeta>>(Option::None);
|
||||
let (game_state, set_game_state) = signal::<Option<GameStateMeta>>(Option::None);
|
||||
let (card_packs_meta, set_card_packs_meta) = signal::<CardPacksMeta>(CardPacksMeta {
|
||||
official_meta: vec![],
|
||||
unofficial_meta: vec![],
|
||||
});
|
||||
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
if !connected() {
|
||||
set_active_games.set_untracked(vec![]);
|
||||
set_user_update.set_untracked(None);
|
||||
set_chat_update.set_untracked(None);
|
||||
set_judge_round.set_untracked(None);
|
||||
set_chat_message.set_untracked(None);
|
||||
set_game_meta.set_untracked(None);
|
||||
set_game_state.set_untracked(None);
|
||||
set_active_games(vec![]);
|
||||
set_user_update(None);
|
||||
set_chat_update(None);
|
||||
set_judge_round(None);
|
||||
set_chat_message(None);
|
||||
set_game_meta(None);
|
||||
set_game_state(None);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -106,7 +105,7 @@ pub fn Websocket() -> impl IntoView {
|
|||
provide_context::<ReadSignal<Option<ServerStateSummary>>>(state_summary);
|
||||
|
||||
// Message handler
|
||||
create_effect(move |_| {
|
||||
Effect::new(move |_| {
|
||||
message.with(move |message_raw| {
|
||||
if let Some(message) = message_raw {
|
||||
if let Ok(state_summary) = from_str::<ServerStateSummary>(message) {
|
||||
|
@ -128,7 +127,7 @@ pub fn Websocket() -> impl IntoView {
|
|||
} else if let Ok(judge_update) = from_str::<JudgeRound>(message) {
|
||||
set_judge_round(Some(judge_update));
|
||||
} else {
|
||||
logging::error!("Unhandled message: {:#?}", message);
|
||||
println!("Unhandled message: {:#?}", message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use leptos::*;
|
||||
use leptos_meta::*;
|
||||
use leptos_router::*;
|
||||
use leptos::prelude::*;
|
||||
use leptos_router::{
|
||||
components::{Route, Router, Routes},
|
||||
StaticSegment,
|
||||
};
|
||||
|
||||
// Modules
|
||||
mod components;
|
||||
|
@ -8,28 +10,14 @@ mod pages;
|
|||
|
||||
// Top-Level pages
|
||||
use crate::pages::home::Home;
|
||||
use crate::pages::not_found::NotFound;
|
||||
|
||||
/// An app router which renders the homepage and handles 404's
|
||||
#[component]
|
||||
pub fn App() -> impl IntoView {
|
||||
// Provides context that manages stylesheets, titles, meta tags, etc.
|
||||
provide_meta_context();
|
||||
|
||||
view! {
|
||||
<Html class="bg-neutral-900" lang="en" dir="ltr" attr:data-theme="dark" />
|
||||
|
||||
// sets the document title
|
||||
<Title text="Cards for Humanity" />
|
||||
|
||||
// injects metadata in the <head> of the page
|
||||
<Meta charset="UTF-8" />
|
||||
<Meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<Router>
|
||||
<Routes>
|
||||
<Route path="/" view=Home />
|
||||
<Route path="/*" view=NotFound />
|
||||
<Routes fallback=|| "Not found.".into_view()>
|
||||
<Route path=StaticSegment("") view=Home />
|
||||
</Routes>
|
||||
</Router>
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
use leptos::*;
|
||||
use client::App;
|
||||
|
||||
fn main() {
|
||||
// set up logging
|
||||
_ = console_log::init_with_level(log::Level::Debug);
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
mount_to_body(|| {
|
||||
view! { <App /> }
|
||||
})
|
||||
leptos::mount::mount_to_body(App)
|
||||
}
|
||||
|
|
|
@ -5,11 +5,15 @@ use crate::components::create_game::*;
|
|||
use crate::components::debug::*;
|
||||
use crate::components::game::*;
|
||||
use crate::components::websocket::*;
|
||||
use leptos::*;
|
||||
use leptos::prelude::*;
|
||||
use thaw::*;
|
||||
|
||||
/// Default Home Page
|
||||
#[component]
|
||||
pub fn Home() -> impl IntoView {
|
||||
let open = RwSignal::new(true);
|
||||
let theme = RwSignal::new(Theme::dark());
|
||||
|
||||
view! {
|
||||
<ErrorBoundary fallback=|errors| {
|
||||
view! {
|
||||
|
@ -33,18 +37,35 @@ pub fn Home() -> impl IntoView {
|
|||
<div class="container m-auto">
|
||||
<h1 class="mx-4 text-6xl inter-med text-neutral-200">"Cards For Humanity"</h1>
|
||||
<div class="p-5 bg-neutral-950 rounded-3xl shadow-black shadow-xl">
|
||||
<h1 class="text-4xl">Hey!</h1>
|
||||
<br />
|
||||
<p>
|
||||
{"Welcome! Thank you for helping me test this. Please let me know about any issues you may come across. Chances are you already know how to contact me but in case you don't you can email me at "}
|
||||
<a href="mailto:adam@doordesk.net">adam@doordesk.net</a>
|
||||
{". The server may go down from time to time as bugs are found and as I add updates. If you manage to crash the server or notice it down for a long time please tell me about it."}
|
||||
</p>
|
||||
<br />
|
||||
<p>Have fun!</p>
|
||||
<br />
|
||||
|
||||
<ConfigProvider theme>
|
||||
<Dialog open>
|
||||
<DialogSurface>
|
||||
<DialogBody>
|
||||
<DialogTitle>"Hey!"</DialogTitle>
|
||||
<DialogContent>
|
||||
<p>
|
||||
{"Welcome! Thank you for helping me test this. Please let me know about any issues you may come across. Chances are you already know how to contact me but in case you don't you can email me at "}
|
||||
<a href="mailto:adam@doordesk.net">adam@doordesk.net</a>
|
||||
{". The server may go down from time to time as bugs are found and as I add updates. If you manage to crash the server or notice it down for a long time please tell me about it."}
|
||||
</p>
|
||||
<br />
|
||||
<p>Have fun!</p>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button
|
||||
on_click=move |_| open.set(!open())
|
||||
appearance=ButtonAppearance::Primary
|
||||
>
|
||||
"Got it"
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</DialogBody>
|
||||
</DialogSurface>
|
||||
</Dialog>
|
||||
</ConfigProvider>
|
||||
|
||||
<Websocket />
|
||||
<hr />
|
||||
<Auth />
|
||||
<hr />
|
||||
<Browser />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use leptos::*;
|
||||
use leptos::prelude::*;
|
||||
|
||||
/// 404 Not Found Page
|
||||
#[component]
|
||||
|
|
Loading…
Add table
Reference in a new issue