even more responsive

This commit is contained in:
Adam 2024-09-10 01:59:35 -04:00
parent 31cd79c543
commit fb586bb362
11 changed files with 243 additions and 167 deletions

View file

@ -14,7 +14,7 @@ console_error_panic_hook = "0.1"
console_log = "1"
log = "0.4"
leptos-use = "0.14.0-beta"
leptos-use = { version = "0.14.0-beta", features = ["use_media_query"] }
# leptos-use = { path = "../../leptos-use" }
# leptos-use = { git = "https://github.com/adoyle0/leptos-use.git", branch = "leptos-0.7" }
codee = "0.2"

View file

@ -1,6 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<style>
@media (prefers-color-scheme: dark) {
body, html {
background-color: #292929;
}
}
</style>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link data-trunk rel="rust" data-target-path="client" data-wasm-opt="z" data-weak-refs />

View file

@ -12,7 +12,6 @@ pub fn Auth() -> impl IntoView {
let user_context = expect_context::<ReadSignal<Option<UserUpdate>>>();
let connected = move || websocket.ready_state.get() == ConnectionReadyState::Open;
let new_username = RwSignal::new(String::new());
let show_auth = RwSignal::new(false);
Effect::new(move |_| {
user_context.with(|new_user| {
@ -40,19 +39,13 @@ pub fn Auth() -> impl IntoView {
});
view! {
<div class="flex flex-wrap justify-between">
<p class="my-2">"Welcome " {move || username()}"!"</p>
<Button
appearance=ButtonAppearance::Transparent
size=ButtonSize::Small
on_click=move |_| { show_auth.set(!show_auth()) }
>
<Avatar name=username />
<Popover trigger_type=PopoverTriggerType::Click position=PopoverPosition::BottomEnd>
<PopoverTrigger slot>
<Button appearance=ButtonAppearance::Transparent size=ButtonSize::Small>
// on_click=move |_| { show_auth.set(!show_auth()) }
<Avatar class="drop-shadow-md" name=username />
</Button>
</div>
<div class="overflow-hidden">
<InlineDrawer open=show_auth position=DrawerPosition::Top size=DrawerSize::Small>
<DrawerBody>
</PopoverTrigger>
<Show when=move || { connected() } fallback=|| view! { <p>"Disconnected."</p> }>
<Popover
trigger_type=PopoverTriggerType::Click
@ -111,8 +104,6 @@ pub fn Auth() -> impl IntoView {
</FieldContextProvider>
</form>
</Show>
</DrawerBody>
</InlineDrawer>
</div>
</Popover>
}
}

View file

@ -24,20 +24,29 @@ pub fn Browser() -> impl IntoView {
// Browser stuff
let game_browser_context = expect_context::<ReadSignal<Vec<GameBrowserMeta>>>();
let (join_id, set_join_id) = signal("".to_string());
let (delete_id, set_delete_id) = signal("".to_string());
let join_id = RwSignal::new("".to_string());
let delete_id = RwSignal::new("".to_string());
let nav_context = expect_context::<RwSignal<String>>();
Effect::new(move |_| {
if join_id() != "" {
set_websocket_send(to_string(&GameJoinRequest { id: join_id() }).unwrap());
nav_context.set("game".to_string());
join_id.set("".to_string());
}
});
Effect::new(move |_| {
if delete_id() != "" {
set_websocket_send(
to_string(&GameDeleteRequest {
delete_game_id: delete_id(),
})
.unwrap(),
);
delete_id.set("".to_string());
}
});
let show_create_game = RwSignal::new(false);
@ -51,14 +60,11 @@ pub fn Browser() -> impl IntoView {
position=PopoverPosition::BottomStart
>
<PopoverTrigger slot>
<h2 class="text-2xl">
"Game Browser"
<Button
icon=icondata::TbHelp
appearance=ButtonAppearance::Transparent
size=ButtonSize::Small
/>
</h2>
</PopoverTrigger>
<p>"Yes, the delete button works. Please don't abuse it."</p>
</Popover>
@ -135,7 +141,7 @@ pub fn Browser() -> impl IntoView {
on_click={
let game_id = game.uuid.clone();
move |_| {
set_join_id(game_id.clone());
join_id.set(game_id.clone());
}
}
>
@ -146,7 +152,7 @@ pub fn Browser() -> impl IntoView {
size=ButtonSize::Small
icon=icondata::TiDeleteOutline
on_click=move |_| {
set_delete_id(game.uuid.clone());
delete_id.set(game.uuid.clone());
}
>
"Delete"

View file

@ -43,6 +43,8 @@ pub fn CreateGame() -> impl IntoView {
let toggle_show_packs = move |_| show_packs.set(!show_packs());
let drawer_context = expect_context::<RwSignal<bool>>();
let nav_context = expect_context::<RwSignal<String>>();
let request_new_game = move |_| {
set_websocket_send(
to_string(&NewGameRequest {
@ -53,6 +55,7 @@ pub fn CreateGame() -> impl IntoView {
);
input_game_name.set(String::new());
drawer_context.set(false);
nav_context.set("game".to_string());
};
view! {

View file

@ -79,7 +79,7 @@ pub fn Chat() -> impl IntoView {
<span class="flex justify-between">
<textarea
node_ref=chat_history_ref
class="w-full h-60 p-1 font-mono rounded-md resize-none bg-neutral-900 text-neutral-200"
class="opacity-80 w-full h-60 p-1 font-mono rounded-md resize-none bg-neutral-900 text-neutral-200 drop-shadow-md"
readonly=true
wrap="soft"
>
@ -95,14 +95,16 @@ pub fn Chat() -> impl IntoView {
<form onsubmit="return false" on:submit=send_message autocomplete="off">
<FieldContextProvider>
<Field label="Message" name="message">
<thaw::Input
<Input
rules=vec![InputRule::required(true.into())]
class="drop-shadow-md"
value=chat_input
placeholder="talk shit..."
/>
</Field>
<Button
button_type=ButtonType::Submit
class="drop-shadow-md"
on_click={
let field_context = FieldContextInjection::expect_context();
move |e: ev::MouseEvent| {

View file

@ -39,7 +39,6 @@ pub fn Game() -> impl IntoView {
view! {
<div class="my-2">
<h2 class="text-2xl">Game</h2>
<Show when=move || { connected() } fallback=|| view! { <p>"Disconnected."</p> }>
<Show
when=move || game_meta.get().is_some() && connected()

View file

@ -3,4 +3,5 @@ pub mod browser;
pub mod chat;
pub mod debug;
pub mod game;
pub mod theme_button;
pub mod websocket;

View file

@ -0,0 +1,40 @@
use leptos::prelude::*;
use thaw::*;
/// In charge of light/dark modes
#[component]
pub fn ThemeButton() -> impl IntoView {
let theme = expect_context::<RwSignal<Theme>>();
let icon = RwSignal::new(None);
Effect::new(move |_| {
if theme().name == "dark" {
icon.set(Some(icondata::BsMoon));
} else {
icon.set(Some(icondata::BsSun));
}
});
let on_click = move |_| {
icon.update(|icon| {
*icon = match icon {
Some(data) => {
if *data == icondata::BsMoon {
theme.set(Theme::light());
icondata::BsSun
} else {
theme.set(Theme::dark());
icondata::BsMoon
}
}
None => {
theme.set(Theme::dark());
icondata::BsMoon
}
}
.into();
});
};
view! { <Button class="drop-shadow-md" icon on_click appearance=ButtonAppearance::Transparent /> }
}

View file

@ -4,6 +4,7 @@ use leptos_router::{
components::{Route, Router, Routes},
StaticSegment,
};
use leptos_use::use_media_query;
use thaw::*;
// Modules
@ -16,7 +17,16 @@ use crate::pages::home::Home;
/// An app router which renders the homepage and handles 404's
#[component]
pub fn App() -> impl IntoView {
let theme = RwSignal::new(Theme::dark());
let theme = RwSignal::new(Theme::light());
let prefers_dark = use_media_query("(prefers-color-scheme: dark)");
Effect::new(move |_| {
if prefers_dark() {
theme.set(Theme::dark());
} else {
theme.set(Theme::light());
}
});
provide_context(theme);
provide_meta_context();

View file

@ -3,6 +3,7 @@ use crate::components::browser::*;
use crate::components::chat::*;
use crate::components::debug::*;
use crate::components::game::*;
use crate::components::theme_button::*;
use crate::components::websocket::*;
use leptos::prelude::*;
use thaw::*;
@ -17,29 +18,8 @@ pub fn Home() -> impl IntoView {
modal.set(true);
};
let theme = expect_context::<RwSignal<Theme>>();
let icon = RwSignal::new(Some(icondata::BsMoon));
let on_click = move |_| {
icon.update(|icon| {
*icon = match icon {
Some(data) => {
if *data == icondata::BsMoon {
theme.set(Theme::light());
icondata::BsSun
} else {
theme.set(Theme::dark());
icondata::BsMoon
}
}
None => {
theme.set(Theme::dark());
icondata::BsMoon
}
}
.into();
});
};
let selected_value = RwSignal::new("home".to_string());
provide_context(selected_value);
view! {
<ErrorBoundary fallback=|errors| {
@ -60,67 +40,104 @@ pub fn Home() -> impl IntoView {
</ul>
}
}>
<Websocket />
<div class="container m-auto">
<div class="container m-auto relative">
<div
class="p-1 sm:p-5 sm:rounded-2xl sm:shadow-black sm:shadow-lg"
class="p-1 sm:p-5 sm:rounded-2xl sm:shadow-black sm:shadow-lg min-h-screen sm:min-h-0"
style="background-color: var(--colorNeutralBackground4);"
>
// Header
<div class="flex flex-wrap justify-between">
<h1 class="text-4xl sm:text-6xl md:text-7xl lg:text-8xl tracking-tighter">
"Cards For Humanity"
</h1>
<Button icon on_click appearance=ButtonAppearance::Transparent />
<ThemeButton />
</div>
<div class="flex justify-between">
<TabList selected_value>
<Tab value="home">
<Button
appearance=ButtonAppearance::Transparent
icon=icondata::BiHomeAlt2Regular
/>
</Tab>
<Tab value="browser">
<Button
appearance=ButtonAppearance::Transparent
icon=icondata::RiMenuSearchSystemLine
/>
</Tab>
<Tab value="game">
<Button
appearance=ButtonAppearance::Transparent
icon=icondata::LuGamepad
/>
</Tab>
<Tab value="chat">
<Button
appearance=ButtonAppearance::Transparent
icon=icondata::BsChatLeftText
/>
</Tab>
<Tab value="debug">
<Button
appearance=ButtonAppearance::Transparent
icon=icondata::AiBugOutlined
/>
</Tab>
</TabList>
<div class="mt-2">
<Auth />
</div>
</div>
<Divider />
<Dialog open=modal>
<DialogSurface>
<DialogBody>
<DialogTitle>"Hey!"</DialogTitle>
<DialogContent>
<p class="indent-2 text-pretty">
<Show when=move || selected_value() == "home".to_string()>
<div class="p-4">
<h2 class="text-2xl">"Hey!"</h2>
<p class="indent-4 text-pretty my-3">
{"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 "}
<Link href="mailto:adam@doordesk.net">
adam@doordesk.net
</Link>
<Link href="mailto:adam@doordesk.net">adam@doordesk.net</Link>
{". 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 |_| modal.set(false)
appearance=ButtonAppearance::Primary
>
"Got it"
</Button>
</DialogActions>
</DialogBody>
</DialogSurface>
</Dialog>
</div>
</Show>
<Websocket />
<Auth />
<Divider />
<Show when=move || selected_value() == "browser".to_string()>
<Browser />
<Divider />
</Show>
<Show when=move || selected_value() == "game".to_string()>
<Game />
<Divider />
</Show>
<Show when=move || selected_value() == "chat".to_string()>
<Chat />
<Divider />
</Show>
<Show when=move || selected_value() == "debug".to_string()>
<Debug />
</Show>
// Footer
<div
class="fixed sm:static bottom-0 left-0 w-full sm:w-auto"
style="background-color: var(--colorNeutralBackground4);"
>
<Divider />
<div class="m-2">
<Link class="p-2" href="https://git.doordesk.net/adam/cards/">
"Git"
"About"
</Link>
<Link class="p-2" href="mailto:adam@doordesk.net">
"Email Me"
"Contact"
</Link>
</div>
</div>
</div>
</div>
</ErrorBoundary>
}
}