aboutsummaryrefslogtreecommitdiff
path: root/server/src/routes/ui
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-01-24 08:56:01 +0100
committermetamuffin <metamuffin@disroot.org>2024-01-24 08:56:01 +0100
commitdaba95cad0d58cf9fbf460d582729857f46b5390 (patch)
tree271c2839df5eedd4b9f0d6266725cef082719b68 /server/src/routes/ui
parentd4772cb6fb78c3d0a69371fc6cd822260b208857 (diff)
downloadjellything-daba95cad0d58cf9fbf460d582729857f46b5390.tar
jellything-daba95cad0d58cf9fbf460d582729857f46b5390.tar.bz2
jellything-daba95cad0d58cf9fbf460d582729857f46b5390.tar.zst
add search draft
Diffstat (limited to 'server/src/routes/ui')
-rw-r--r--server/src/routes/ui/layout.rs2
-rw-r--r--server/src/routes/ui/mod.rs1
-rw-r--r--server/src/routes/ui/search.rs74
3 files changed, 77 insertions, 0 deletions
diff --git a/server/src/routes/ui/layout.rs b/server/src/routes/ui/layout.rs
index faf5527..3772c06 100644
--- a/server/src/routes/ui/layout.rs
+++ b/server/src/routes/ui/layout.rs
@@ -13,6 +13,7 @@ use crate::{
admin::rocket_uri_macro_r_admin_dashboard,
browser::rocket_uri_macro_r_all_items,
node::rocket_uri_macro_r_library_node,
+ search::rocket_uri_macro_r_search,
},
uri,
};
@@ -45,6 +46,7 @@ markup::define! {
@if let Some(_) = session {
a.library[href=uri!(r_library_node("library"))] { "My Library" } " "
a.library[href=uri!(r_all_items())] { "All Items" } " "
+ a.library[href=uri!(r_search(None::<&'static str>))] { "Search" } " "
}
div.account {
@if let Some(session) = session {
diff --git a/server/src/routes/ui/mod.rs b/server/src/routes/ui/mod.rs
index ea78ea5..da96103 100644
--- a/server/src/routes/ui/mod.rs
+++ b/server/src/routes/ui/mod.rs
@@ -31,6 +31,7 @@ pub mod home;
pub mod layout;
pub mod node;
pub mod player;
+pub mod search;
pub mod sort;
pub mod style;
diff --git a/server/src/routes/ui/search.rs b/server/src/routes/ui/search.rs
new file mode 100644
index 0000000..dc90df1
--- /dev/null
+++ b/server/src/routes/ui/search.rs
@@ -0,0 +1,74 @@
+use super::{
+ account::session::Session,
+ error::MyResult,
+ layout::{DynLayoutPage, LayoutPage},
+ node::NodeCard,
+};
+use edit_distance::edit_distance;
+use jellybase::database::{DataAcid, ReadableTable, T_NODE, T_USER_NODE};
+use rocket::{get, State};
+
+#[get("/search?<query>")]
+pub async fn r_search<'a>(
+ session: Session,
+ db: &State<DataAcid>,
+ query: Option<&str>,
+) -> MyResult<DynLayoutPage<'a>> {
+ let results = if let Some(query) = query {
+ let mut items = {
+ let txn = db.begin_read()?;
+ let nodes = txn.open_table(T_NODE)?;
+ let node_users = txn.open_table(T_USER_NODE)?;
+ let i = nodes
+ .iter()?
+ .map(|a| {
+ let (x, y) = a.unwrap();
+ let (x, y) = (x.value().to_owned(), y.value().0);
+ let z = node_users
+ .get(&(session.user.name.as_str(), x.as_str()))
+ .unwrap()
+ .map(|z| z.value().0)
+ .unwrap_or_default();
+ let y = y.public;
+ (x, y, z)
+ })
+ .collect::<Vec<_>>();
+ drop(nodes);
+ i
+ };
+
+ let query = query.to_lowercase();
+ items.sort_by_cached_key(|(_, n, _)| {
+ n.title
+ .as_ref()
+ .map(|x| x.to_lowercase())
+ .unwrap_or_default()
+ .split(" ")
+ .map(|tok| edit_distance(query.as_str(), tok))
+ .min()
+ .unwrap_or(usize::MAX)
+ });
+
+ Some(items.into_iter().take(64).collect::<Vec<_>>())
+ } else {
+ None
+ };
+
+ Ok(LayoutPage {
+ title: "Search".to_string(),
+ class: None,
+ content: markup::new! {
+ h1 { "Search" }
+ form[action="", method="GET"] {
+ input[type="text", name="query"];
+ input[type="submit"];
+ }
+ @if let Some(results) = &results {
+ h2 { "Results" }
+ ul.children {@for (id, node, udata) in results.iter() {
+ li { @NodeCard { id, node, udata } }
+ }}
+ }
+ },
+ })
+}