feat: adds dynamic word retreival

looks like we're live :)
This commit is contained in:
itsscb 2024-08-22 20:43:05 +02:00
parent 7553025731
commit 6b9e50ef43
6 changed files with 134 additions and 100 deletions

View File

@ -22,3 +22,4 @@ gloo-net = "0.6.0"
serde = { version = "1.0.198", features = ["derive"] } serde = { version = "1.0.198", features = ["derive"] }
serde_json = "1.0.116" serde_json = "1.0.116"
regex = "1.10.4" regex = "1.10.4"
tracing = "0.1.40"

View File

@ -9,13 +9,13 @@
<link rel="manifest" href="public/manifest.json" /> <link rel="manifest" href="public/manifest.json" />
<link rel="modulepreload" href="/wordl-frontend-fc53a686d7997e96.js" crossorigin=anonymous integrity="sha384-mYYngEqwNe/MByGAOghKzFvwKtcFKa49nvztLGp2bWtEr122LZIy90IwuEsz1d3/"> <link rel="modulepreload" href="/wordl-frontend-f12cb96db58e762c.js" crossorigin=anonymous integrity="sha384-bBxFiVwzR66Z1hv0ruG4aGTidjq8XBRcL0Crsv4fRIK6kj1hmLn4dH0tm6t9qsCH">
<link rel="preload" href="/wordl-frontend-fc53a686d7997e96_bg.wasm" crossorigin=anonymous integrity="sha384-91qkiGfY7l6p7THqCtyecHAhThTZ71cH0SN3l03GQI8qH7nFwZxck5c25JS+LlCd" as="fetch" type="application/wasm"></head> <link rel="preload" href="/wordl-frontend-f12cb96db58e762c_bg.wasm" crossorigin=anonymous integrity="sha384-rH9nswm1hLZCk8ksVMGninp4DCq3b/MGGV6gv4p6gPvfWUVvNswadaIr2RbcyaNS" as="fetch" type="application/wasm"></head>
<body class="bg-black text-white"> <body class="bg-black text-white">
<script type="module" nonce="z1ycfrQCqxwlbyPwNQ2Ltg=="> <script type="module" nonce="FBx2FAPOfqu3mKchrgJ5jg==">
import init, * as bindings from '/wordl-frontend-fc53a686d7997e96.js'; import init, * as bindings from '/wordl-frontend-f12cb96db58e762c.js';
const wasm = await init('/wordl-frontend-fc53a686d7997e96_bg.wasm'); const wasm = await init('/wordl-frontend-f12cb96db58e762c_bg.wasm');
window.wasmBindings = bindings; window.wasmBindings = bindings;

View File

@ -20,6 +20,15 @@ function takeObject(idx) {
return ret; return ret;
} }
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
heap_next = heap[idx];
heap[idx] = obj;
return idx;
}
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
@ -38,15 +47,6 @@ function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
} }
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
heap_next = heap[idx];
heap[idx] = obj;
return idx;
}
let WASM_VECTOR_LEN = 0; let WASM_VECTOR_LEN = 0;
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
@ -324,14 +324,14 @@ function __wbg_get_imports() {
const ret = false; const ret = false;
return ret; return ret;
}; };
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
const ret = getStringFromWasm0(arg0, arg1);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_object_clone_ref = function(arg0) { imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
const ret = getObject(arg0); const ret = getObject(arg0);
return addHeapObject(ret); return addHeapObject(ret);
}; };
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
const ret = getStringFromWasm0(arg0, arg1);
return addHeapObject(ret);
};
imports.wbg.__wbg_listenerid_6dcf1c62b7b7de58 = function(arg0, arg1) { imports.wbg.__wbg_listenerid_6dcf1c62b7b7de58 = function(arg0, arg1) {
const ret = getObject(arg1).__yew_listener_id; const ret = getObject(arg1).__yew_listener_id;
getDataViewMemory0().setInt32(arg0 + 4 * 1, isLikeNone(ret) ? 0 : ret, true); getDataViewMemory0().setInt32(arg0 + 4 * 1, isLikeNone(ret) ? 0 : ret, true);
@ -435,11 +435,6 @@ function __wbg_get_imports() {
wasm.__wbindgen_free(arg0, arg1 * 4, 4); wasm.__wbindgen_free(arg0, arg1 * 4, 4);
console.error(...v0); console.error(...v0);
}; };
imports.wbg.__wbg_log_7c3433e130418e14 = function(arg0, arg1) {
var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
wasm.__wbindgen_free(arg0, arg1 * 4, 4);
console.log(...v0);
};
imports.wbg.__wbg_fetch_eeae7120f2a07ede = function(arg0) { imports.wbg.__wbg_fetch_eeae7120f2a07ede = function(arg0) {
const ret = fetch(getObject(arg0)); const ret = fetch(getObject(arg0));
return addHeapObject(ret); return addHeapObject(ret);
@ -963,16 +958,16 @@ function __wbg_get_imports() {
const ret = wasm.memory; const ret = wasm.memory;
return addHeapObject(ret); return addHeapObject(ret);
}; };
imports.wbg.__wbindgen_closure_wrapper913 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper916 = function(arg0, arg1, arg2) {
const ret = makeClosure(arg0, arg1, 370, __wbg_adapter_38); const ret = makeClosure(arg0, arg1, 381, __wbg_adapter_38);
return addHeapObject(ret); return addHeapObject(ret);
}; };
imports.wbg.__wbindgen_closure_wrapper1061 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper1023 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 417, __wbg_adapter_41); const ret = makeMutClosure(arg0, arg1, 408, __wbg_adapter_41);
return addHeapObject(ret); return addHeapObject(ret);
}; };
imports.wbg.__wbindgen_closure_wrapper1155 = function(arg0, arg1, arg2) { imports.wbg.__wbindgen_closure_wrapper1116 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 455, __wbg_adapter_44); const ret = makeMutClosure(arg0, arg1, 446, __wbg_adapter_44);
return addHeapObject(ret); return addHeapObject(ret);
}; };

Binary file not shown.

View File

@ -1,4 +1,5 @@
use gloo_console::log; // use gloo_console::log;
use tracing::{debug, error, info};
use gloo_net::http::Request; use gloo_net::http::Request;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use web_sys::wasm_bindgen::convert::OptionIntoWasmAbi; use web_sys::wasm_bindgen::convert::OptionIntoWasmAbi;
@ -11,6 +12,7 @@ use yew::{classes, function_component, Callback, Html};
use crate::CharStatus; use crate::CharStatus;
static NEW_WORD_URI: &str = "https://wordl.shuttleapp.rs/word"; static NEW_WORD_URI: &str = "https://wordl.shuttleapp.rs/word";
static MAX_TRIES: usize = 5;
fn set_focus(index: usize) { fn set_focus(index: usize) {
if let Some(w) = web_sys::window() { if let Some(w) = web_sys::window() {
@ -100,114 +102,137 @@ fn string_to_html(input: &[CharStatus<String>]) -> Html {
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
struct Word(String); struct Word(String);
#[allow(dead_code)]
fn get_word(handle: UseStateHandle<String>) { fn get_word(handle: UseStateHandle<String>) {
use_effect_with((), move |()| { use_effect_with((), move |()| {
// let word = handle.clone();
wasm_bindgen_futures::spawn_local(async move { wasm_bindgen_futures::spawn_local(async move {
log!("retrieving word"); info!("retreiving word");
let res = Request::get(NEW_WORD_URI).send().await; let res = Request::get(NEW_WORD_URI).send().await;
log!(format!("RESPONSE: {res:?}")); debug!(RESULT = format!("{res:?}"));
match res { match res {
Ok(r) => { Ok(r) => {
log!(format!("{r:?}")); debug!(RESPONSE = format!("{r:?}"));
match r.body() { match r.text().await {
Some(j) => { Ok(w) => {
let j = j.to_string(); debug!(WORD = &w);
let data = format!("{j:?}"); handle.set(w);
log!(&data);
handle.set(data);
} }
None => log!("no body"), Err(e) => error!(ERROR = format!("{e:?}"),"failed to get request body"),
} }
} }
Err(e) => log!(format!("FETCH: {e:?}")), Err(e) => error!(ERROR = format!("{e:?}"),"failed to retreive word"),
} }
// 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());
// }
// }
}); });
|| () || ()
}); });
} }
fn fetch_new_word(
word: &UseStateHandle<String>,
loading: &UseStateHandle<bool>,
submitted_words: &UseStateHandle<Vec<Vec<CharStatus<String>>>>,
input_values: &UseStateHandle<Vec<String>>,
game_over: &UseStateHandle<bool>,
length: &UseStateHandle<usize>,
node_refs: &UseStateHandle<Vec<NodeRef>>,
) {
let handle = word.clone();
let loading = loading.clone();
let submitted_words = submitted_words.clone();
let input_values = input_values.clone();
let game_over = game_over.clone();
let length = length.clone();
let node_refs = node_refs.clone();
wasm_bindgen_futures::spawn_local(async move {
debug!("retrieving word");
let res = Request::get(NEW_WORD_URI).send().await;
debug!(RESULT = format!("{res:?}"));
match res {
Ok(r) => {
debug!(RESPONSE = format!("{r:?}"));
match r.text().await {
Ok(w) => {
debug!(WORD = &w);
length.set(w.len());
node_refs.set(vec![NodeRef::default(); w.len()]);
input_values.set(vec![String::new(); w.len()]);
handle.set(w.to_uppercase());
submitted_words.set(Vec::with_capacity(MAX_TRIES));
game_over.set(false);
loading.set(false);
}
Err(e) => error!(ERROR = format!("{e:?}"), "failed to get request body"),
}
}
Err(e) => error!(ERROR = format!("{e:?}"), "failed to retrieve word"),
}
});
}
#[function_component] #[function_component]
pub fn Home() -> Html { pub fn Home() -> Html {
// let got_word = "HALLO";
// let length = got_word.len();
log!("STARTING");
let word: UseStateHandle<String> = use_state(String::new); let word: UseStateHandle<String> = use_state(String::new);
let loading: UseStateHandle<bool> = use_state(|| true);
// get_word(word.clone()); let length = use_state(|| 0usize);
let submitted_words: UseStateHandle<Vec<Vec<CharStatus<String>>>> =
use_state(|| std::vec::Vec::with_capacity(MAX_TRIES));
let node_refs = use_state(|| vec![NodeRef::default(); 10]);
let input_values: UseStateHandle<Vec<String>> = use_state(|| vec![String::new(); *length]);
let game_over = use_state(|| false);
{ {
let handle = word.clone(); let handle = word.clone();
use_effect_with((), move |()| { let loading = loading.clone();
// 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:?}")),
// }
// },
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()); let submitted_words = submitted_words.clone();
// } let input_values = input_values.clone();
// } let game_over = game_over.clone();
let length = length.clone();
let node_refs = node_refs.clone();
use_effect_with((), move |()| {
wasm_bindgen_futures::spawn_local(async move {
debug!("retreiving word");
let res = Request::get(NEW_WORD_URI).send().await;
debug!(RESULT = format!("{res:?}"));
match res {
Ok(r) => {
debug!(RESPONSE = format!("{r:?}"));
match r.text().await {
Ok(w) => {
debug!(WORD = &w);
length.set(w.len());
node_refs.set(vec![NodeRef::default(); w.len()]);
input_values.set(vec![String::new(); w.len()]);
handle.set(w.to_uppercase());
submitted_words.set(std::vec::Vec::with_capacity(MAX_TRIES));
game_over.set(false);
loading.set(false);
}
Err(e) => error!(ERROR = format!("{e:?}"),"failed to get request body"),
}
}
Err(e) => error!(ERROR = format!("{e:?}"),"failed to retreive word"),
}
}); });
|| () || ()
}); });
} }
let length = word.len();
let submitted_words: UseStateHandle<Vec<Vec<CharStatus<String>>>> =
use_state(|| std::vec::Vec::with_capacity(length));
let node_refs = use_state(|| vec![NodeRef::default(); length]);
let input_values: UseStateHandle<Vec<String>> = use_state(|| vec![String::new(); length]);
let game_over = use_state(|| false);
let game_over_check = { let game_over_check = {
let word = word.clone(); let word = word.clone();
let submitted_words = submitted_words.clone(); let submitted_words = submitted_words.clone();
let iv = input_values.clone(); let iv = input_values.clone();
let game_over = game_over.clone(); let game_over = game_over.clone();
let length = length.clone();
Callback::from(move |_| { Callback::from(move |_| {
if submitted_words.iter().count() >= length - 1 if submitted_words.iter().count() >= *length - 1
|| crate::compare_strings(&word, &iv.join("")) || crate::compare_strings(&word, &iv.join(""))
.iter() .iter()
.all(|v| matches!(v, CharStatus::Match(_))) .all(|v| matches!(v, CharStatus::Match(_)))
@ -221,12 +246,22 @@ pub fn Home() -> Html {
let input_values = input_values.clone(); let input_values = input_values.clone();
let submitted_words = submitted_words.clone(); let submitted_words = submitted_words.clone();
let game_over = game_over.clone(); let game_over = game_over.clone();
let length = length.clone();
let word = word.clone(); let word = word.clone();
let node_refs = node_refs.clone();
let loading = loading.clone();
Callback::from(move |_e: MouseEvent| { Callback::from(move |_e: MouseEvent| {
if *game_over { if *game_over {
submitted_words.set(std::vec::Vec::with_capacity(length)); let input_values = input_values.clone();
input_values.set(vec![String::new(); length]); let submitted_words = submitted_words.clone();
game_over.set(false); let game_over = game_over.clone();
let length = length.clone();
let word = word.clone();
let loading = loading.clone();
let node_refs = node_refs.clone();
fetch_new_word(&word, &loading, &submitted_words, &input_values, &game_over, &length, &node_refs);
return; return;
} }
let values: Vec<_> = input_values.iter().cloned().collect(); let values: Vec<_> = input_values.iter().cloned().collect();
@ -266,7 +301,7 @@ pub fn Home() -> Html {
) )
} }
> >
<h1>{(*word).clone()}</h1> // <h1>{(*word).clone()} {" NODE_REFS: "}{node_refs.len()} {" WORD_LEN: "}{*length}</h1>
<div <div
class="h-4/6 flex flex-col" class="h-4/6 flex flex-col"
> >
@ -285,7 +320,10 @@ pub fn Home() -> Html {
} }
> >
{ {
if !*game_over && !word.is_empty() { if *loading {
html!(<p>{"Loading..."}</p>)
}
else if !*game_over {
node_refs.iter().enumerate().map(|(index, node_ref)| { node_refs.iter().enumerate().map(|(index, node_ref)| {
let on_input = { let on_input = {
let node_ref = node_ref.clone(); let node_ref = node_ref.clone();