aboutsummaryrefslogtreecommitdiff
path: root/server/src/routes/ui/search.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/routes/ui/search.rs')
-rw-r--r--server/src/routes/ui/search.rs63
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
+ }
+ },
+ })
})
}