diff options
Diffstat (limited to 'server/src/routes/ui/search.rs')
-rw-r--r-- | server/src/routes/ui/search.rs | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/server/src/routes/ui/search.rs b/server/src/routes/ui/search.rs index d020e2e..c5944ec 100644 --- a/server/src/routes/ui/search.rs +++ b/server/src/routes/ui/search.rs @@ -1,53 +1,68 @@ +/* + This file is part of jellything (https://codeberg.org/metamuffin/jellything) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2025 metamuffin <metamuffin.org> +*/ use super::{ account::session::Session, error::MyResult, layout::{DynLayoutPage, LayoutPage}, node::{DatabaseNodeUserDataExt, NodeCard}, }; +use crate::routes::api::AcceptJson; +use anyhow::anyhow; use jellybase::database::Database; -use jellycommon::Visibility; -use rocket::{get, State}; +use jellycommon::{api::ApiSearchResponse, Visibility}; +use rocket::{get, serde::json::Json, Either, State}; use std::time::Instant; #[get("/search?<query>&<page>")] pub async fn r_search<'a>( session: Session, db: &State<Database>, + aj: AcceptJson, query: Option<&str>, page: Option<usize>, -) -> MyResult<DynLayoutPage<'a>> { - let timing = Instant::now(); +) -> MyResult<Either<DynLayoutPage<'a>, Json<ApiSearchResponse>>> { let results = if let Some(query) = query { + let timing = Instant::now(); let (count, ids) = db.search(query, 32, page.unwrap_or_default() * 32)?; let mut nodes = ids .into_iter() .map(|id| db.get_node_with_userdata(id, &session)) .collect::<Result<Vec<_>, anyhow::Error>>()?; nodes.retain(|(n, _)| n.visibility >= Visibility::Reduced); - Some((count, nodes)) + let search_dur = timing.elapsed(); + Some((count, nodes, search_dur)) } else { None }; - let search_dur = timing.elapsed(); let query = query.unwrap_or_default().to_string(); - Ok(LayoutPage { - title: "Search".to_string(), - class: Some("search"), - content: markup::new! { - h1 { "Search" } - form[action="", method="GET"] { - input[type="text", name="query", placeholder="Search Term", value=&query]; - input[type="submit", value="Search"]; - } - @if let Some((count, results)) = &results { - h2 { "Results" } - p.stats { @format!("Found {count} nodes in {search_dur:?}.") } - ul.children {@for (node, udata) in results.iter() { - li { @NodeCard { node, udata } } - }} - // TODO pagination - } - }, + Ok(if *aj { + let Some((count, results, _)) = results else { + Err(anyhow!("no query"))? + }; + Either::Right(Json(ApiSearchResponse { count, results })) + } else { + Either::Left(LayoutPage { + title: "Search".to_string(), + class: Some("search"), + content: markup::new! { + h1 { "Search" } + form[action="", method="GET"] { + input[type="text", name="query", placeholder="Search Term", value=&query]; + input[type="submit", value="Search"]; + } + @if let Some((count, results, search_dur)) = &results { + h2 { "Results" } + p.stats { @format!("Found {count} nodes in {search_dur:?}.") } + ul.children {@for (node, udata) in results.iter() { + li { @NodeCard { node, udata } } + }} + // TODO pagination + } + }, + }) }) } |