feat: first steps to fetching word

This commit is contained in:
itsscb 2024-08-22 14:56:13 +02:00
parent f02173e9ca
commit 5a7d66b52b
7 changed files with 129 additions and 16 deletions

View File

@ -5,11 +5,13 @@ edition = "2021"
[dependencies]
axum = "0.7.4"
http = "1.1.0"
rand = "0.8.5"
shuttle-axum = "0.45.0"
shuttle-runtime = "0.45.0"
tokio = "1.28.2"
tower-http = { version = "0.5.2", features = ["fs"] }
tower-http = { version = "0.5.2", features = ["fs", "cors"] }
yew = "0.21.0"
[workspace]

View File

@ -10,8 +10,10 @@ web-sys = { version = "0.3.69", features = ["HtmlElement", "HtmlInputElement", "
yew = { version = "0.21.0", features = ["csr"] }
yew-router = { version = "0.18.0"}
gloo-console = "0.3.0"
wasm-bindgen-futures = "0.4.43"
yewdux = "0.10.0"
surrealdb = "1.5.4"
gloo-net = "0.6.0"
serde = {version = "1.0.198", features = ["derive"]}
serde_json = "1.0.116"
regex = "1.10.4"

View File

@ -4,18 +4,18 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>wordl</title>
<link rel="stylesheet" href="/styles-2d4b9067b081b869.css" integrity="sha384&#x2D;CdHsGkjNlZspxDHxL&#x2B;kbV7gPNf65&#x2F;kjgMc4Irmu7j1U9awEK&#x2F;gviS&#x2B;9F6DhzZ2Ok"/>
<link rel="stylesheet" href="/styles-ee33d68e538eb411.css" integrity="sha384&#x2D;VemAqPaskVP87p4noZgkqPXi9J04CRYEjIS2QPGi7Odp6o&#x2B;XdpPGWYbkxwQuac0P"/>
<!-- <link data-trunk href="./assets/favicon.ico" rel="icon" type="image/x-icon"> -->
<link rel="manifest" href="public/manifest.json" />
<link rel="modulepreload" href="/wordl-frontend-ec1c68cebf137781.js" crossorigin=anonymous integrity="sha384-sD6lSOk5++qRMptRdZGUIeZNBI8zJRaOoHyLTRYrXrr2A3uTm806FdoHl/VBFszR">
<link rel="preload" href="/wordl-frontend-ec1c68cebf137781_bg.wasm" crossorigin=anonymous integrity="sha384-+aX7cO9xqU24eMR3ZV0pwShAWkZft3WAvjb8ljtvXAJZcdFUgPN4yP9jyEmit9kv" as="fetch" type="application/wasm"></head>
<link rel="modulepreload" href="/wordl-frontend-b775e5ac46c429c2.js" crossorigin=anonymous integrity="sha384-d9YxtVTJZK55F/tw4RJfGfKHiNOpv6M7cWFUlG56t7ji+lbNzt/d2srIXLbGnbJw">
<link rel="preload" href="/wordl-frontend-b775e5ac46c429c2_bg.wasm" crossorigin=anonymous integrity="sha384-OeuJrCitX0Yk7zu7SEZ0vUlWgR9nwWRfBOEOGtT78f3NzadCDbBZwMxWmg+6xIvI" as="fetch" type="application/wasm"></head>
<body class="bg-black text-white">
<script type="module" nonce="169I6f+oniwmB3SabaDvjw==">
import init, * as bindings from '/wordl-frontend-ec1c68cebf137781.js';
const wasm = await init('/wordl-frontend-ec1c68cebf137781_bg.wasm');
<script type="module" nonce="bkDD0eidqI71oXS/PsNg0A==">
import init, * as bindings from '/wordl-frontend-b775e5ac46c429c2.js';
const wasm = await init('/wordl-frontend-b775e5ac46c429c2_bg.wasm');
window.wasmBindings = bindings;

View File

@ -554,6 +554,10 @@ video {
--tw-contain-style: ;
}
.static {
position: static;
}
.\!order-first {
order: -9999 !important;
}

View File

@ -554,6 +554,10 @@ video {
--tw-contain-style: ;
}
.static {
position: static;
}
.\!order-first {
order: -9999 !important;
}

View File

@ -1,11 +1,17 @@
use gloo_net::http::Request;
use gloo_console::log;
use serde::{Deserialize, Serialize};
use web_sys::wasm_bindgen::convert::OptionIntoWasmAbi;
use web_sys::wasm_bindgen::JsCast;
use web_sys::HtmlElement;
use yew::prelude::*;
use yew::{classes, function_component, html, Callback, Html};
use yew::{classes, function_component, Callback, Html};
// use yew::{FetchTask, Request, Response, FetchService};
use crate::CharStatus;
static NEW_WORD_URI: &str = "https://wordl.shuttleapp.rs/word";
fn set_focus(index: usize) {
if let Some(w) = web_sys::window() {
if let Some(d) = w.document() {
@ -87,10 +93,93 @@ fn string_to_html(input: &[CharStatus<String>]) -> Html {
}
}
#[derive(Serialize,Deserialize, Debug)]
struct Word(String);
fn get_word(handle: UseStateHandle<String>) {
use_effect_with((), move |()| {
// let word = handle.clone();
wasm_bindgen_futures::spawn_local(async move {
log!("retrieving word");
let res = Request::get(NEW_WORD_URI).send().await;
log!(format!("RESPONSE: {res:?}"));
match res {
Ok(r) => {
log!(format!("{r:?}"));
match r.body() {
Some(j) => {
let j = j.to_string();
let data = format!("{j:?}");
log!(&data);
handle.set(data);
},
None => log!("no body"),
}
},
Err(e) => log!(format!("FETCH: {e:?}")),
}
// let res: Word = Request::get(NEW_WORD_URI).send().await.unwrap().json().await.unwrap();
// log!(res);
// handle.set(res.0);
// if let Ok(r) = res {
// if let Some(w) = r.body() {
// word.set(w.to_string());
// }
// }
});
|| ()
});
}
#[function_component]
pub fn Home() -> Html {
let got_word = "HALLO";
let length = got_word.len();
// let got_word = "HALLO";
// let length = got_word.len();
log!("STARTING");
let word: UseStateHandle<String> = use_state(String::new);
// get_word(word.clone());
{
let handle = word.clone();
use_effect_with((), move |()| {
// let word = handle.clone();
wasm_bindgen_futures::spawn_local(async move {
log!("retrieving word");
let res = Request::get(NEW_WORD_URI).send().await;
log!(format!("RESPONSE: {res:?}"));
match res {
Ok(r) => {
log!(format!("{r:?}"));
match r.json::<Word>().await {
Ok(j) => {
let data = format!("{j:?}");
log!(&data);
handle.set(data);
},
Err(e) => log!(format!("{e:?}")),
}
},
Err(e) => log!(format!("FETCH: {e:?}")),
}
// let res: Word = Request::get(NEW_WORD_URI).send().await.unwrap().json().await.unwrap();
// log!(res);
// handle.set(res.0);
// if let Ok(r) = res {
// if let Some(w) = r.body() {
// word.set(w.to_string());
// }
// }
});
|| ()
});
}
let length = word.len();
let submitted_words: UseStateHandle<Vec<Vec<CharStatus<String>>>> = use_state(|| std::vec::Vec::with_capacity(length));
@ -98,11 +187,12 @@ pub fn Home() -> Html {
let input_values: UseStateHandle<Vec<String>> = use_state(|| vec![String::new(); length]);
let game_over = use_state(|| false);
let game_over_check = {
let word = word.clone();
let submitted_words = submitted_words.clone();
let iv = input_values.clone();
let game_over = game_over.clone();
Callback::from(move |_| {
if submitted_words.iter().count() >= length - 1 || crate::compare_strings(got_word, &iv.join("")).iter().all(|v| matches!(v, CharStatus::Match(_))){
if submitted_words.iter().count() >= length - 1 || crate::compare_strings(&word, &iv.join("")).iter().all(|v| matches!(v, CharStatus::Match(_))){
game_over.set(true);
}
})
@ -112,6 +202,7 @@ pub fn Home() -> Html {
let input_values = input_values.clone();
let submitted_words = submitted_words.clone();
let game_over = game_over.clone();
let word = word.clone();
Callback::from(move |_e: MouseEvent| {
if *game_over {
submitted_words.set(std::vec::Vec::with_capacity(length));
@ -124,7 +215,7 @@ pub fn Home() -> Html {
return;
}
let mut new_items = (*submitted_words).clone();
new_items.push(crate::compare_strings(got_word, &values.join("")));
new_items.push(crate::compare_strings(&word, &values.join("")));
submitted_words.set(new_items);
game_over_check.emit(MouseEvent::none());
})
@ -156,6 +247,7 @@ pub fn Home() -> Html {
)
}
>
<h1>{(*word).clone()}</h1>
<div
class="h-4/6 flex flex-col"
>
@ -174,9 +266,7 @@ pub fn Home() -> Html {
}
>
{
if *game_over {
html!(<div></div>)
} else {
if !*game_over && !word.is_empty() {
node_refs.iter().enumerate().map(|(index, node_ref)| {
let on_input = {
let node_ref = node_ref.clone();
@ -212,6 +302,8 @@ pub fn Home() -> Html {
/>
}
}).collect::<Html>()
} else {
html!(<div></div>)
}
}
</div>

View File

@ -1,13 +1,22 @@
use axum::{routing::get, Router};
use rand::seq::SliceRandom;
use tower_http::services::ServeDir;
use tower_http::cors::{Any,CorsLayer};
use http::Method;
#[shuttle_runtime::main]
async fn main() -> shuttle_axum::ShuttleAxum {
let cors = CorsLayer::new()
.allow_origin(Any) // Allow all origins; adjust as necessary
.allow_methods(vec![Method::GET]) // Specify allowed methods
.allow_headers(Any);
let router = Router::new()
// .route("/", get(hello_world))
.nest_service("/", ServeDir::new("frontend/dist"))
.route("/word", get(word));
.route("/word", get(word))
.layer(cors);
Ok(router.into())
}