use crate::aska::WindTemplate;
use crate::rendering;
use crate::routes::response::*;
use crate::routes::{gem, t, ugate};
use askama::Template;
use mdiu::Block;
use nostr_sdk::prelude::*;
use windmark_titanesque::{context::RouteContext, response::Response};
const NOTES_PER_PAGE: usize = 128;
#[derive(Template)]
#[template(path = "search_notes.gmi", escape = "txt")]
pub struct NotesSearchTemplate {
results_count: usize,
page_cur: usize,
page_last: usize,
matching_notes: Vec<Block>,
}
impl NotesSearchTemplate {
fn display_results_count(&self) -> String {
t!(
"search_results_summary",
count = self.results_count,
current_page = self.page_cur + 1,
last_page = self.page_last + 1
)
.to_string()
}
}
pub async fn search_content(ctx: RouteContext) -> Response {
let Some(user) = ugate(ctx.certificate).await else {
return resp_nocert();
};
let Some(searchq) = ctx.parameters.get("searchq") else {
if let Some(q) = dec_urlq(&ctx.url) {
return Response::temporary_redirect(format!(
"/search/notes/{}/0",
q
));
} else {
return Response::input(t!("search_query_input"));
}
};
let page = match ctx
.parameters
.get("page")
.unwrap_or(&String::from("0"))
.parse::<usize>()
{
Ok(num) => num,
Err(_error) => 0,
};
let sfilter = Filter::new().kind(Kind::TextNote).search(searchq);
if let Ok(events) = user.client.database().query(sfilter).await {
let results_count = events.len();
if results_count == 0 {
return resp_noresults_for_query();
}
let page_max = events.len() / NOTES_PER_PAGE;
let start = page * NOTES_PER_PAGE;
let end = start + NOTES_PER_PAGE;
match rendering::render_notes(
events,
&user.client,
Some(start),
Some(end),
rendering::NoteRenderMode::Normal,
)
.await
{
Ok(blocks) => {
Response::success(WindTemplate::render(
NotesSearchTemplate {
results_count,
page_cur: page,
page_last: page_max,
matching_notes: blocks,
},
))
}
Err(_err) => {
Response::temporary_failure("Rendering error")
}
}
} else {
resp_db_query_error()
}
}