|
|
|
|
@@ -13,6 +13,7 @@ use web_sys::{Event, HtmlInputElement, KeyboardEvent}; // 0.3.5
|
|
|
|
|
use dotenv_codegen::dotenv;
|
|
|
|
|
use itertools::Itertools;
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
use wasm_bindgen::closure::Closure;
|
|
|
|
|
//use gloo_timers::future::TimeoutFuture;
|
|
|
|
|
//#[macro_use]
|
|
|
|
|
//extern crate dotenv_codegen;
|
|
|
|
|
@@ -90,23 +91,9 @@ pub struct AppState {
|
|
|
|
|
pub loggedin: RcSignal<bool>,
|
|
|
|
|
pub editmode: RcSignal<bool>,
|
|
|
|
|
pub dropdownselect: RcSignal<bool>,
|
|
|
|
|
pub scrolling: RcSignal<bool>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO
|
|
|
|
|
let callback: Closure<dyn FnMut()> = Closure::new(move || {
|
|
|
|
|
info!("Got scroll event");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let window = web_sys::window().expect("Failed to get window");
|
|
|
|
|
window
|
|
|
|
|
.add_event_listener_with_callback_and_bool(
|
|
|
|
|
"scroll",
|
|
|
|
|
callback.as_ref().unchecked_ref(),
|
|
|
|
|
false, // Changing this to true does not help :/
|
|
|
|
|
)
|
|
|
|
|
.expect("Failed to set listener");
|
|
|
|
|
callback.forget();*/
|
|
|
|
|
|
|
|
|
|
async fn login_user(user: AxumUser) -> Result<reqwasm::http::Response, reqwasm::Error> {
|
|
|
|
|
let backend_url : &'static str = dotenv!("BACKEND_URL");
|
|
|
|
|
let url = format!("{}/api/login", backend_url);
|
|
|
|
|
@@ -140,6 +127,19 @@ async fn list_users() -> Result<HashMap<String,i32>, reqwasm::Error> {
|
|
|
|
|
Ok(res)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async fn authentication_check() -> Result<bool, reqwasm::Error> {
|
|
|
|
|
let backend_url : &'static str = dotenv!("BACKEND_URL");
|
|
|
|
|
let url = format!("{}/api/authentication_check", backend_url);
|
|
|
|
|
let resp = Request::get(&url).send().await?;
|
|
|
|
|
if resp.status() == 200 {
|
|
|
|
|
Ok(true)
|
|
|
|
|
} else {
|
|
|
|
|
Ok(false)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async fn fetch_books(search: String) -> Result<Vec<BookUI>, reqwasm::Error> {
|
|
|
|
|
//dotenvy::dotenv().ok();
|
|
|
|
|
let backend_url : &'static str = dotenv!("BACKEND_URL");
|
|
|
|
|
@@ -432,6 +432,20 @@ pub fn DropDownUser<G: Html>(cx: Scope, value: StringProp) -> View<G> {
|
|
|
|
|
#[component]
|
|
|
|
|
async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|
|
|
|
let app_state = use_context::<AppState>(cx);
|
|
|
|
|
let callback_signal = use_context::<RcSignal<bool>>(cx);
|
|
|
|
|
let csignal = callback_signal.clone();
|
|
|
|
|
//callback_signal.clone().set(false);
|
|
|
|
|
create_effect(cx, || {
|
|
|
|
|
let app_state = app_state.clone();
|
|
|
|
|
let cxsignal = callback_signal.clone();
|
|
|
|
|
if *cxsignal.get() == true {
|
|
|
|
|
cxsignal.set(false);
|
|
|
|
|
if *app_state.pagedisplay.get() < *app_state.maxpage.get()-1 {
|
|
|
|
|
app_state.pagedisplay.set(*app_state.pagedisplay.get()+1);
|
|
|
|
|
app_state.scrolling.set(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
create_effect(cx, || {
|
|
|
|
|
let app_state = app_state.clone();
|
|
|
|
|
@@ -440,6 +454,8 @@ async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|
|
|
|
app_state.openlibrary.track();
|
|
|
|
|
app_state.internalsearch.track();
|
|
|
|
|
app_state.refreshing.track();
|
|
|
|
|
//let csignal = csignals2.clone();
|
|
|
|
|
|
|
|
|
|
//let tempb = app_state.books.get();
|
|
|
|
|
//spawn_local( async move { info!(
|
|
|
|
|
// "The state changed. Old value: {:?}",
|
|
|
|
|
@@ -481,6 +497,40 @@ async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if *app_state.scrolling.get()==true {
|
|
|
|
|
app_state.scrolling.set(false);
|
|
|
|
|
if *app_state.internalsearch.get() == false {
|
|
|
|
|
info!("DB triggered");
|
|
|
|
|
spawn_local(async move {
|
|
|
|
|
let res = list_books(*app_state.pagedisplay.get(), *app_state.userid.get(), "desc".to_string())
|
|
|
|
|
.await.unwrap();
|
|
|
|
|
let mut currbooks = (*app_state.clone().books.get()).clone();
|
|
|
|
|
currbooks.extend(res.books.iter().cloned());
|
|
|
|
|
app_state.books.set(
|
|
|
|
|
currbooks
|
|
|
|
|
);
|
|
|
|
|
app_state.maxpage.set(
|
|
|
|
|
res.num_pages
|
|
|
|
|
)
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
info!("IntSearch triggered");
|
|
|
|
|
|
|
|
|
|
spawn_local(async move {
|
|
|
|
|
let res = search_books(app_state.search.get().to_string(), *app_state.pagedisplay.get(), *app_state.userid.get())
|
|
|
|
|
.await.unwrap();
|
|
|
|
|
let mut currbooks = (*app_state.clone().books.get()).clone();
|
|
|
|
|
currbooks.extend(res.books.iter().cloned());
|
|
|
|
|
app_state.books.set(
|
|
|
|
|
currbooks
|
|
|
|
|
);
|
|
|
|
|
app_state.maxpage.set(
|
|
|
|
|
res.num_pages
|
|
|
|
|
)
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
if *app_state.refreshing.get() == false {
|
|
|
|
|
@@ -501,6 +551,22 @@ async fn ListDB<G: Html>(cx: Scope<'_>) -> View<G> {
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let callback: Closure<dyn FnMut()> = Closure::new(move || {
|
|
|
|
|
//let csignal = callback_signal.clone();
|
|
|
|
|
csignal.set(true);
|
|
|
|
|
info!("Got scroll event");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let window = web_sys::window().expect("Failed to get window");
|
|
|
|
|
window
|
|
|
|
|
.add_event_listener_with_callback_and_bool(
|
|
|
|
|
"scroll",
|
|
|
|
|
callback.as_ref().unchecked_ref(),
|
|
|
|
|
false, // Changing this to true does not help :/
|
|
|
|
|
)
|
|
|
|
|
.expect("Failed to set listener");
|
|
|
|
|
callback.forget();
|
|
|
|
|
|
|
|
|
|
let docs = create_memo(cx, || app_state.books.get().iter().cloned().collect::<Vec<_>>());
|
|
|
|
|
view! {cx,
|
|
|
|
|
p {
|
|
|
|
|
@@ -1118,14 +1184,17 @@ async fn PageBar<G: Html>(cx: Scope<'_>) -> View<G> {
|
|
|
|
|
let input_ref = create_node_ref(cx);
|
|
|
|
|
|
|
|
|
|
let handle_add = move |_| {
|
|
|
|
|
if *app_state.pagenum.get() < *app_state.maxpage.get()-1 {
|
|
|
|
|
app_state.pagenum.set(*app_state.pagenum.get()+1);
|
|
|
|
|
app_state.pagedisplay.set(*app_state.pagenum.get()+1);
|
|
|
|
|
app_state.refreshing.set(true);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let handle_sub = move |_| {
|
|
|
|
|
if *app_state.pagenum.get()>1 {
|
|
|
|
|
app_state.pagenum.set(*app_state.pagenum.get()-1);
|
|
|
|
|
app_state.pagedisplay.set(*app_state.pagenum.get()-1);
|
|
|
|
|
app_state.refreshing.set(true);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
@@ -1137,6 +1206,7 @@ async fn PageBar<G: Html>(cx: Scope<'_>) -> View<G> {
|
|
|
|
|
let pg = currpg.get().as_ref().clone().parse::<u32>().unwrap_or(1);
|
|
|
|
|
if pg>0 && pg<*app_state.maxpage.get() {
|
|
|
|
|
app_state.pagenum.set(pg);
|
|
|
|
|
app_state.pagedisplay.set(pg);
|
|
|
|
|
app_state.refreshing.set(true);
|
|
|
|
|
} else {
|
|
|
|
|
currpg.set((*app_state.pagenum.get()).to_string());
|
|
|
|
|
@@ -1178,6 +1248,7 @@ async fn LoginScreenUI<G: Html>(cx: Scope<'_>) -> View<G> {
|
|
|
|
|
let input_refU = create_node_ref(cx);
|
|
|
|
|
let passval = create_signal(cx, String::new());
|
|
|
|
|
let input_refP = create_node_ref(cx);
|
|
|
|
|
let node_ref = create_node_ref(cx);
|
|
|
|
|
|
|
|
|
|
let handle_register = move |_| {
|
|
|
|
|
let app_state = app_state.clone();
|
|
|
|
|
@@ -1198,6 +1269,8 @@ async fn LoginScreenUI<G: Html>(cx: Scope<'_>) -> View<G> {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let handle_login = move |_| {
|
|
|
|
|
let app_state = app_state.clone();
|
|
|
|
|
let userstr = (*userval.get()).clone();
|
|
|
|
|
let user = AxumUser{
|
|
|
|
|
id: 0,
|
|
|
|
|
name: (*userval.get()).clone(),
|
|
|
|
|
@@ -1207,23 +1280,52 @@ async fn LoginScreenUI<G: Html>(cx: Scope<'_>) -> View<G> {
|
|
|
|
|
login_user(user)
|
|
|
|
|
.await.expect("Couldn't login user");
|
|
|
|
|
});
|
|
|
|
|
app_state.loggedin.set(true);
|
|
|
|
|
app_state.useridloggedin.set( *(*app_state.userlist.get()).get(&(*userval.get()).clone()).unwrap_or(&0));
|
|
|
|
|
app_state.userid.set( *(*app_state.userlist.get()).get(&(*userval.get()).clone()).unwrap_or(&0));
|
|
|
|
|
spawn_local(async move {
|
|
|
|
|
let auth = authentication_check().await.unwrap_or(false);
|
|
|
|
|
app_state.loggedin.set(auth);
|
|
|
|
|
if auth == true {
|
|
|
|
|
app_state.useridloggedin.set( *(*app_state.userlist.get()).get(&userstr).unwrap_or(&0));
|
|
|
|
|
app_state.userid.set( *(*app_state.userlist.get()).get(&userstr).unwrap_or(&0));
|
|
|
|
|
app_state.userscreen.set(false);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
create_effect(cx, || {
|
|
|
|
|
if *app_state.userscreen.get() == true {
|
|
|
|
|
let dom_node = node_ref.try_get::<DomNode>();
|
|
|
|
|
if dom_node.is_some() {
|
|
|
|
|
dom_node.unwrap().set_attribute("popup-display","true");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
let dom_node = node_ref.try_get::<DomNode>();
|
|
|
|
|
if dom_node.is_some() {
|
|
|
|
|
dom_node.unwrap().set_attribute("popup-display","false");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
let handle_close = move |_| {
|
|
|
|
|
app_state.displaying.set(false);
|
|
|
|
|
|
|
|
|
|
let dom_node = node_ref.try_get::<DomNode>();
|
|
|
|
|
if dom_node.is_some() {
|
|
|
|
|
dom_node.unwrap().set_attribute("popup-display","false");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
view! {cx,
|
|
|
|
|
div {
|
|
|
|
|
div(class="modal-box", ref=node_ref){
|
|
|
|
|
|
|
|
|
|
(if *app_state.userscreen.get() == true {
|
|
|
|
|
view!{cx,
|
|
|
|
|
|
|
|
|
|
div(class="modal-content"){
|
|
|
|
|
input(ref=input_refU,bind:value=userval)
|
|
|
|
|
input(ref=input_refP,bind:value=passval)
|
|
|
|
|
|
|
|
|
|
button(on:click=handle_login){ "LOGIN" }
|
|
|
|
|
button(on:click=handle_register){ "REGISTER" }
|
|
|
|
|
|
|
|
|
|
button(class="close", on:click=handle_close){ "CLOSE" }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}else {
|
|
|
|
|
view!{cx,""}
|
|
|
|
|
@@ -1262,6 +1364,7 @@ fn App<G: Html>(cx: Scope) -> View<G> {
|
|
|
|
|
loggedin: create_rc_signal(bool::default()),
|
|
|
|
|
editmode: create_rc_signal(bool::default()),
|
|
|
|
|
dropdownselect: create_rc_signal(bool::default()),
|
|
|
|
|
scrolling: create_rc_signal(bool::default()),
|
|
|
|
|
};
|
|
|
|
|
provide_context(cx, app_state);
|
|
|
|
|
|
|
|
|
|
|