add leptos future test client

This commit is contained in:
Adam 2024-07-18 04:00:56 -04:00
parent 834de62ba0
commit e183391186
21 changed files with 2055 additions and 11 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
target/
dist/

72
Cargo.lock generated
View file

@ -190,6 +190,7 @@ dependencies = [
"serde_json",
"tokio",
"tower",
"tower-http",
"tracing",
"tracing-subscriber",
]
@ -412,6 +413,12 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "http-range-header"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a397c49fec283e3d6211adbe480be95aae5f304cfb923e9970e08956d5168a"
[[package]]
name = "httparse"
version = "1.9.4"
@ -529,6 +536,16 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "mime_guess"
version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
dependencies = [
"mime",
"unicase",
]
[[package]]
name = "miniz_oxide"
version = "0.7.4"
@ -914,18 +931,18 @@ checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
[[package]]
name = "thiserror"
version = "1.0.62"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.62"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c"
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
@ -999,6 +1016,19 @@ dependencies = [
"tungstenite",
]
[[package]]
name = "tokio-util"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
]
[[package]]
name = "tower"
version = "0.4.13"
@ -1015,6 +1045,31 @@ dependencies = [
"tracing",
]
[[package]]
name = "tower-http"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
dependencies = [
"bitflags",
"bytes",
"futures-util",
"http",
"http-body",
"http-body-util",
"http-range-header",
"httpdate",
"mime",
"mime_guess",
"percent-encoding",
"pin-project-lite",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
@ -1114,6 +1169,15 @@ version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicase"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [
"version_check",
]
[[package]]
name = "unicode-bidi"
version = "0.3.15"

View file

@ -2,6 +2,7 @@
name = "cards"
version = "0.1.0"
edition = "2021"
authors = ["Adam Doyle <adam@doordesk.net>"]
[dependencies]
rand = "0.8.5"
@ -15,3 +16,4 @@ tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
anyhow = "1.0.82"
axum-extra = "0.9.3"
tower-http = { version = "0.5.2", features = ["fs", "trace"] }

6
Trunk.toml Normal file
View file

@ -0,0 +1,6 @@
[build]
target = "client/index.html"
dist = "dist"
[watch]
watch = ["client"]

2
client/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
/dist

1674
client/Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

31
client/Cargo.toml Normal file
View file

@ -0,0 +1,31 @@
[package]
name = "client"
version = "0.1.0"
edition = "2021"
authors = ["Adam Doyle <adam@doordesk.net>"]
[profile.release]
opt-level = 'z'
lto = true
codegen-units = 1
panic = "abort"
# 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"] }
console_log = "1"
log = "0.4"
console_error_panic_hook = "0.1"
# utils
# strum = { version = "0.25", features = ["derive", "strum_macros"] }
# strum_macros = "0.25"
[dev-dependencies]
wasm-bindgen = "=0.2.92"
wasm-bindgen-test = "0.3"
web-sys = { version = "0.3", features = ["Document", "Window"] }

79
client/README.md Normal file
View file

@ -0,0 +1,79 @@
<picture>
<source srcset="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_Solid_White.svg" media="(prefers-color-scheme: dark)">
<img src="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_RGB.svg" alt="Leptos Logo">
</picture>
# Leptos Client-Side Rendered (CSR) App Starter Template
This is a template for use with the [Leptos][Leptos] web framework using the [Trunk][Trunk] tool to compile and serve your app in development.
## Creating your repo from the template
This template requires you to have `cargo-generate` installed. You can install it with
```sh
cargo install cargo-generate
```
To set up your project with this template, run
```sh
cargo generate --git https://github.com/leptos-community/start-csr
```
to generate your new project, then
```sh
cd cards
```
to go to your newly created project.
By default, this template uses Rust `nightly` and requires that you've installed the `wasm` compilation target for your toolchain.
Sass and Tailwind are also supported by the Trunk build tool, but are optional additions: [see here for more info on how to set those up with Trunk][Trunk-instructions].
If you don't have Rust nightly, you can install it with
```sh
rustup toolchain install nightly --allow-downgrade
```
You can add the `wasm` compilation target to rust using
```sh
rustup target add wasm32-unknown-unknown
```
## Developing your Leptos CSR project
To develop your Leptos CSR project, running
```sh
trunk serve --port 3000 --open
```
will open your app in your default browser at `http://localhost:3000`.
## Deploying your Leptos CSR project
To build a Leptos CSR app for release, use the command
```sh
trunk build --release
```
This will output the files necessary to run your app into the `dist` folder; you can then use any static site host to serve these files.
For further information about hosting Leptos CSR apps, please refer to [the Leptos Book chapter on deployment available here][deploy-csr].
[Leptos]: https://github.com/leptos-rs/leptos
[Trunk]: https://github.com/trunk-rs/trunk
[Trunk-instructions]: https://trunkrs.dev/assets/
[deploy-csr]: https://book.leptos.dev/deployment/csr.html

15
client/index.html Normal file
View file

@ -0,0 +1,15 @@
<!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="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 -->
<link data-trunk rel="rust" data-target-path="client" data-wasm-opt="z" data-weak-refs />
</head>
<body></body>
</html>

BIN
client/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

52
client/public/styles.css Normal file
View file

@ -0,0 +1,52 @@
/* --------------------- Open Props --------------------------- */
/* the props */
@import "https://unpkg.com/open-props";
/* optional imports that use the props */
@import "https://unpkg.com/open-props/normalize.min.css";
@import "https://unpkg.com/open-props/buttons.min.css";
/* ------------------------------------------------------------ */
body {
font-family: sans-serif;
text-align: center;
}
.container {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
.buttons {
display: flex;
justify-content: space-evenly;
}
h1,
h2,
h3,
h4,
h5,
h6 {
text-align: center;
margin: 0 auto;
padding: 2rem;
}
p,
button {
margin: var(--size-6);
}
body > picture,
button {
display: block;
margin-left: auto;
margin-right: auto;
text-align: center;
margin: 2rem;
}

View file

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

View file

@ -0,0 +1,15 @@
use leptos::*;
/// A parameterized incrementing button
#[component]
pub fn Button(#[prop(default = 1)] increment: i32) -> impl IntoView {
let (count, set_count) = create_signal(0);
view! {
<button on:click=move |_| {
set_count(count() + increment)
}>
"Ligma: " {count}
</button>
}
}

View file

@ -0,0 +1 @@
pub mod counter_btn;

36
client/src/lib.rs Normal file
View file

@ -0,0 +1,36 @@
use leptos::*;
use leptos_meta::*;
use leptos_router::*;
// Modules
mod components;
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 lang="en" dir="ltr" attr:data-theme="dark"/>
// sets the document title
<Title text="Welcome to Leptos CSR"/>
// 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>
</Router>
}
}

12
client/src/main.rs Normal file
View file

@ -0,0 +1,12 @@
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/> }
})
}

40
client/src/pages/home.rs Normal file
View file

@ -0,0 +1,40 @@
use crate::components::counter_btn::Button;
use leptos::*;
/// Default Home Page
#[component]
pub fn Home() -> impl IntoView {
view! {
<ErrorBoundary fallback=|errors| {
view! {
<h1>"Uh oh! Something went wrong!"</h1>
<p>"Errors: "</p>
// Render a list of errors as strings - good for development purposes
<ul>
{move || {
errors
.get()
.into_iter()
.map(|(_, e)| view! { <li>{e.to_string()}</li> })
.collect_view()
}}
</ul>
}
}>
<div class="container">
<h1>"Cards For Humanity"</h1>
<hr/>
<div class="buttons">
<Button/>
<Button increment=5/>
</div>
</div>
</ErrorBoundary>
}
}

2
client/src/pages/mod.rs Normal file
View file

@ -0,0 +1,2 @@
pub mod home;
pub mod not_found;

View file

@ -0,0 +1,7 @@
use leptos::*;
/// 404 Not Found Page
#[component]
pub fn NotFound() -> impl IntoView {
view! { <h1>"Uh oh!" <br/> "We couldn't find that page!"</h1> }
}

View file

@ -7,6 +7,7 @@ This started as a problem trying to play games with friends who are all on diffe
## Dev stuff:
`trunk build` to build test client
`cargo run` to run server
open `localhost:3030` in your browser to run test client or connect to `ws://localhost:3030/websocket` with a custom client

View file

@ -1,6 +1,6 @@
use anyhow::{Context, Result};
use axum_extra::response::Css;
use axum::{response::Html, routing::get, Router};
use axum_extra::response::Css;
use std::{
// collections::HashSet,
fs,
@ -8,7 +8,12 @@ use std::{
sync::{Arc, Mutex},
};
use tokio::sync::broadcast;
use tower_http::{
services::{ServeDir, ServeFile},
trace::TraceLayer,
};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
pub mod gamemaster;
use crate::gamemaster::*;
pub mod api;
@ -29,7 +34,7 @@ fn load_json(path: &str) -> Result<Vec<CAHCardSet>> {
#[allow(dead_code)]
fn test() -> Result<()> {
// choose decks
let cards_input_path: &str = "data/cah-cards-full.json";
let cards_input_path: &str = "../data/cah-cards-full.json";
// TODO: this should be a master card database and pointers
// to the cards should be passed to the game instead of actual cards
@ -90,9 +95,6 @@ pub struct AppState {
}
// Include utf-8 files at **compile** time.
async fn index() -> Html<&'static str> {
Html(std::include_str!("../public/index.html"))
}
async fn test_client() -> Html<&'static str> {
Html(std::include_str!("../public/test_client.html"))
}
@ -112,7 +114,7 @@ async fn main() -> Result<()> {
tracing_subscriber::registry()
.with(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| "cards=trace".into()),
.unwrap_or_else(|_| "cards=trace,tower_http=trace".into()),
)
.with(tracing_subscriber::fmt::layer())
.init();
@ -132,12 +134,12 @@ async fn main() -> Result<()> {
// set routes and apply state
let app = Router::new()
.route("/", get(index))
.route("/spawn_clients", get(spawn_clients))
.route("/test_client", get(test_client))
.route("/reference_client", get(reference_client))
.route("/websocket", get(websocket_handler))
.route("/css", get(css))
.nest_service("/", ServeDir::new("dist"))
.with_state(app_state);
// send it