From f7c2cf802cc9fdaa7789a1c84b1e51f1c969a128 Mon Sep 17 00:00:00 2001 From: Vinod J M Date: Sat, 14 Jan 2023 21:10:55 +0530 Subject: [PATCH] Backend and frontend fixes --- backend/api/src/lib.rs | 125 ++++++++++++++++++++++++++++++++++++++++- frontend/src/main.rs | 66 +++++++++++++++------- 2 files changed, 168 insertions(+), 23 deletions(-) diff --git a/backend/api/src/lib.rs b/backend/api/src/lib.rs index 7226659..35981a1 100644 --- a/backend/api/src/lib.rs +++ b/backend/api/src/lib.rs @@ -260,6 +260,7 @@ pub async fn main() { .route("/api/update", post(update_book)) .route("/api/delete/:id", get(delete_book)) .route("/api/authentication_check", get(authentication_check)) + .route("/api/refresh_search_index", get(refresh_meili_index)) .route_layer(RequireAuthorizationLayer::::login()) .route("/api/list", get(list_book)) .route("/api/list_search", get(list_search_book)) @@ -713,6 +714,122 @@ async fn delete_book( "success" } + +async fn refresh_meili_index( + Extension(ref conn): Extension, + Extension(ref meili_client): Extension, + Extension(user): Extension, +) -> impl IntoResponse { + dotenvy::dotenv().ok(); + let userid = user.id; + + let page: usize = 0; + let sort: String = "desc".to_string(); + let per_page: usize = 12; + + let books = QueryCore::find_books_plus_meta_in_page(conn, page, per_page, userid, sort.clone()) + .await + .expect("could not list books"); + + let num_pages = books.1; + for pg_idx in 0..num_pages { + let books = QueryCore::find_books_plus_meta_in_page(conn, pg_idx.try_into().unwrap(), per_page, userid, sort.clone()) + .await + .expect("could not list books"); + + for bookandmeta in books.0.into_iter() { + let bookui = BookUI { + id: bookandmeta.clone().book.id, + title: bookandmeta.clone().book.title, + open_library_key: bookandmeta.clone().book.open_library_key, + edition_count: bookandmeta.clone().book.edition_count, + first_publish_year: bookandmeta.clone().book.first_publish_year, + median_page_count: bookandmeta.clone().book.median_page_count, + goodread_id: bookandmeta.clone().book.goodread_id, + description: bookandmeta.clone().book.description, + cover: bookandmeta.clone().book.cover, + location: bookandmeta.clone().book.location, + time_added: bookandmeta.clone().book.time_added, + rating: bookandmeta.clone().book.rating, + comments: bookandmeta.clone().book.comments, + author_name: Some( + bookandmeta + .clone() + .authors + .into_iter() + .map(|u| u.author_name) + .collect(), + ), + person: Some( + bookandmeta + .clone() + .persons + .into_iter() + .map(|u| u.person) + .collect(), + ), + place: Some( + bookandmeta + .clone() + .places + .into_iter() + .map(|u| u.place) + .collect(), + ), + subject: Some( + bookandmeta + .clone() + .subjects + .into_iter() + .map(|u| u.subject) + .collect(), + ), + time: Some( + bookandmeta + .clone() + .times + .into_iter() + .map(|u| u.time) + .collect(), + ), + isbn: Some( + bookandmeta + .clone() + .isbns + .into_iter() + .map(|u| u.isbn) + .collect(), + ), + }; + + let book_meili = BookMeili { + id: bookui.id, + open_library_key: bookui.open_library_key.unwrap_or("".to_string()), + title: bookui.title, + edition_count: bookui.edition_count.unwrap_or(0), + first_publish_year: bookui.first_publish_year.unwrap_or(0), + median_page_count: bookui.median_page_count.unwrap_or(0), + goodread_id: bookui.goodread_id.unwrap_or("".to_string()), + description: bookui.description.unwrap_or("".to_string()), + cover: bookui.cover.unwrap_or("".to_string()), + location: bookui.location.unwrap_or("".to_string()), + time_added: bookui.time_added.unwrap_or("".to_string()), + rating: bookui.rating.unwrap_or(0), + comments: bookui.comments.unwrap_or("".to_string()), + author_name: bookui.author_name.unwrap_or(vec!["".to_string()]), + person: bookui.person.unwrap_or(vec!["".to_string()]), + place: bookui.place.unwrap_or(vec!["".to_string()]), + subject: bookui.subject.unwrap_or(vec!["".to_string()]), + time: bookui.time.unwrap_or(vec!["".to_string()]), + isbn: bookui.isbn.unwrap_or(vec!["".to_string()]), + }; + booksman_search::create_or_update_book(book_meili, userid, meili_client).await; + } + } + + "success" +} + async fn list_book( Extension(ref conn): Extension, axum::extract::Query(params): axum::extract::Query>, @@ -734,7 +851,11 @@ async fn list_book( for bookandmeta in books.0.into_iter() { let mut cover = bookandmeta.clone().book.cover; if !cover.is_none() { - cover = Some(format!("{}/images/{}", backend_url, cover.unwrap())); + if cover.clone().unwrap() != "".to_string() { + cover = Some(format!("{}/images/{}", backend_url, cover.unwrap())); + } else { + cover = Some(format!("{}/images/placeholder.jpg", backend_url)); + } } else { cover = Some(format!("{}/images/placeholder.jpg", backend_url)); } @@ -1022,7 +1143,7 @@ async fn create_book( .expect("could not create book"); } let book_meili = BookMeili { - id: doc_sent.id, + id: created_book.last_insert_id, open_library_key: doc_sent.open_library_key.unwrap_or("".to_string()), title: doc_sent.title, edition_count: doc_sent.edition_count.unwrap_or(0), diff --git a/frontend/src/main.rs b/frontend/src/main.rs index dad01da..5758024 100644 --- a/frontend/src/main.rs +++ b/frontend/src/main.rs @@ -291,6 +291,8 @@ pub fn Header(cx: Scope) -> View { app_state.search.set(task); app_state.openlibrary.set(false); app_state.internalsearch.set(true); + app_state.pagenum.set(1); + app_state.pagedisplay.set(1); app_state.refreshing.set(true); info!("Fetching search 2\n"); } @@ -300,6 +302,8 @@ pub fn Header(cx: Scope) -> View { let click_listall = |_| { app_state.openlibrary.set(false); app_state.internalsearch.set(false); + app_state.pagenum.set(1); + app_state.pagedisplay.set(1); app_state.refreshing.set(true); }; @@ -432,7 +436,7 @@ pub fn Header(cx: Scope) -> View { (if *app_state.editmode.get() == true { view!{ cx, - div(class="w-1/2 flex"){ + div(class="w-2/5 flex"){ (if *app_state.userid.get() != 0 { view!{ cx, button(on:click=click_listall, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-layer-group") span(class="inline-block"){"All" }} @@ -447,7 +451,7 @@ pub fn Header(cx: Scope) -> View { view!{cx, ""} }) } - div(class="w-1/2 flex"){ + div(class="w-2/5 flex"){ button(on:click=click_addbook, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-circle-plus") span(class="inline-block"){"Add" }} //button(on:click=click_addbook) { "+ Add New" } //input(ref=input_ref3, @@ -469,6 +473,7 @@ pub fn Header(cx: Scope) -> View { view!{cx, (if *app_state.userid.get() != 0 { view!{ cx, + div(class="w-2/5 flex"){ button(on:click=click_listall, class="bg-gray-300 hover:bg-gray-200 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center") { i(class="fa-solid fa-layer-group") span(class="inline-block"){"All" }} div(class="min-w-40 inline-flex"){ input(ref=input_ref2, @@ -477,7 +482,9 @@ pub fn Header(cx: Scope) -> View { bind:value=value2, on:keyup=handle_submit_seachall, )} - }} else { + } + } + } else { view!{cx, ""} }) } @@ -794,7 +801,8 @@ async fn ListDB(cx: Scope<'_>) -> View { let mut currbooks = (*app_state_scr.clone().books.get()).clone(); currbooks.extend(res.books.iter().cloned()); app_state_scr.books.set(currbooks); - app_state_scr.maxpage.set(res.num_pages) + app_state_scr.maxpage.set(res.num_pages); + app_state_scr.scrolling.set(false); }); } else { info!("IntSearch triggered2"); @@ -810,10 +818,10 @@ async fn ListDB(cx: Scope<'_>) -> View { let mut currbooks = (*app_state_scr.clone().books.get()).clone(); currbooks.extend(res.books.iter().cloned()); app_state_scr.books.set(currbooks); - app_state_scr.maxpage.set(res.num_pages) + app_state_scr.maxpage.set(res.num_pages); + app_state_scr.scrolling.set(false); }); } - app_state.scrolling.set(false); } } else { //info!("LibrarySearch triggered?"); @@ -837,7 +845,7 @@ async fn ListDB(cx: Scope<'_>) -> View { let handle_load_more = move |_| { let app_state = app_state.clone(); - if *app_state.scrolling.get() == true { + if *app_state.scrolling.get() == false { app_state.scrollevent.set(true); } }; @@ -846,7 +854,7 @@ async fn ListDB(cx: Scope<'_>) -> View { //let csignal = csignal.clone(); //csignal.set(true); let app_state2 = app_state2.clone(); - if *app_state2.scrolling.get() == true { + if *app_state2.scrolling.get() == false { app_state2.scrollevent.set(true); } info!("Got scroll event"); @@ -879,13 +887,21 @@ async fn ListDB(cx: Scope<'_>) -> View { key =|x| x.id ) } br{} - (if *app_state.maxpage.get() > 1 && *app_state.maxpage.get() > *app_state.pagedisplay.get() { + (if *app_state.scrolling.get() == true { view!{ cx, - div(class="flex flex-col items-center"){ - button(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center",on:click=handle_load_more){ "Load More" } + div(class="flex flex-col items-center m-5"){ + div(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"){ "Loading ..." } } }} else { - view!{ cx, ""} + view!{ cx, + (if *app_state.maxpage.get() > 1 && *app_state.maxpage.get() > *app_state.pagedisplay.get() { + view!{ cx, + div(class="flex flex-col items-center m-5"){ + button(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center",on:click=handle_load_more){ "Load More" } + } + }} else { + view!{ cx, ""} + })} }) } @@ -901,13 +917,22 @@ async fn ListDB(cx: Scope<'_>) -> View { key =|x| x.id ) } br{} - (if *app_state.maxpage.get() > 1 && *app_state.maxpage.get() > *app_state.pagedisplay.get() { + + (if *app_state.scrolling.get() == true { view!{ cx, - div(class="flex flex-col items-center"){ - button(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center",on:click=handle_load_more){ "Load More" } + div(class="flex flex-col items-center m-5"){ + div(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center"){ "Loading ..." } } }} else { - view!{ cx, ""} + view!{ cx, + (if *app_state.maxpage.get() > 1 && *app_state.maxpage.get() > *app_state.pagedisplay.get() { + view!{ cx, + div(class="flex flex-col items-center m-5"){ + button(class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded inline-flex items-center",on:click=handle_load_more){ "Load More" } + } + }} else { + view!{ cx, ""} + })} }) } @@ -941,7 +966,7 @@ pub fn BookDB(cx: Scope, bookitem: BookUIProp) -> View { .description .unwrap_or("".to_string()); let locloc = bookitem.bookitem.clone().location.unwrap_or("".to_string()); - if locdesc.clone().len() > 200 { + if locdesc.clone().chars().count() > 200 { locdesc = format!("{:.200}...", locdesc.clone()) } //let locref = create_rc_signal(false); @@ -1038,7 +1063,7 @@ pub fn BookDB_View(cx: Scope, bookitem: BookUIProp) -> View { .description .unwrap_or("".to_string()); let locloc = bookitem.bookitem.clone().location.unwrap_or("".to_string()); - if locdesc.clone().len() > 200 { + if locdesc.clone().chars().count() > 200 { locdesc = format!("{:.200}...", locdesc.clone()) } @@ -1060,7 +1085,7 @@ pub fn BookDB_View(cx: Scope, bookitem: BookUIProp) -> View { app_state.displayingbook.set(bookdisplay_div.clone()); }; view! { cx, - div(class="col-span-1 px-4 py-4 bg-gray-200 border-2 border-gray-400 rounded m-3"){ + div(class="col-span-1 px-4 py-4 bg-gray-200 border-2 border-gray-400 rounded m-3", on:click=handle_display_div){ div(class="card-buttons"){ @@ -1068,7 +1093,7 @@ pub fn BookDB_View(cx: Scope, bookitem: BookUIProp) -> View { button( class="bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 border-black-500 rounded inline-flex items-center", on:click=handle_display){ i(class="fa-solid fa-circle-info") } } - div(class="card-main", on:click=handle_display_div){ + div(class="card-main"){ img(class="float-right m-1",src=coverurl,width="100") div(class="card-title font-bold text-lg"){ @@ -2226,7 +2251,6 @@ fn App(cx: Scope) -> View { ListOL {} ListDB{} } - //PageBar{} } } }