aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/src/api.rs1
-rw-r--r--server/src/routes/home.rs23
-rw-r--r--server/src/routes/items.rs25
-rw-r--r--server/src/routes/node.rs31
-rw-r--r--server/src/routes/player.rs20
-rw-r--r--server/src/routes/search.rs24
-rw-r--r--ui/src/components/props.rs7
7 files changed, 45 insertions, 86 deletions
diff --git a/common/src/api.rs b/common/src/api.rs
index 9cf5e04..061ff09 100644
--- a/common/src/api.rs
+++ b/common/src/api.rs
@@ -13,6 +13,7 @@ pub struct Nku<'a> {
pub node: Cow<'a, Object>,
pub userdata: Cow<'a, Object>,
pub role: Option<Cow<'a, str>>,
+ pub child_count: u64,
}
pub struct Stats {
diff --git a/server/src/routes/home.rs b/server/src/routes/home.rs
index 17cac83..cb3fffd 100644
--- a/server/src/routes/home.rs
+++ b/server/src/routes/home.rs
@@ -5,13 +5,12 @@
*/
use super::error::MyResult;
-use crate::request_info::RequestInfo;
+use crate::{request_info::RequestInfo, routes::node::create_nku};
use anyhow::{Context, Result};
-use jellycommon::{Nku, jellyobject::EMPTY};
use jellydb::{Query, helper::DatabaseReturnExt};
use jellyui::components::home::{Home, HomeRow};
use rocket::{get, response::content::RawHtml};
-use std::{borrow::Cow, str::FromStr};
+use std::str::FromStr;
#[get("/home")]
pub fn r_home(ri: RequestInfo<'_>) -> MyResult<RawHtml<String>> {
@@ -58,15 +57,9 @@ fn home_row(
let q = Query::from_str(query).context("parse query")?;
ri.state.database.transaction_ret(|txn| {
let rows = txn.query(q.clone())?.take(16).collect::<Result<Vec<_>>>()?;
-
let mut nkus = Vec::new();
for (row, _) in rows {
- let node = txn.get(row)?.unwrap();
- nkus.push(Nku {
- node: Cow::Owned(node),
- role: None,
- userdata: Cow::Borrowed(EMPTY),
- });
+ nkus.push(create_nku(txn, row)?);
}
Ok((title, HomeRow::Inline(nkus)))
})
@@ -83,14 +76,6 @@ fn home_row_highlight(
return Ok(None);
};
let row = row?.0;
- let node = txn.get(row)?.unwrap();
- Ok(Some((
- title,
- HomeRow::Highlight(Nku {
- node: Cow::Owned(node),
- role: None,
- userdata: Cow::Borrowed(EMPTY),
- }),
- )))
+ Ok(Some((title, HomeRow::Highlight(create_nku(txn, row)?))))
})
}
diff --git a/server/src/routes/items.rs b/server/src/routes/items.rs
index 84869a1..8db60da 100644
--- a/server/src/routes/items.rs
+++ b/server/src/routes/items.rs
@@ -4,17 +4,16 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::{request_info::RequestInfo, routes::error::MyResult};
+use crate::{
+ request_info::RequestInfo,
+ routes::{error::MyResult, node::create_nku},
+};
use anyhow::anyhow;
use base64::{Engine, prelude::BASE64_URL_SAFE};
-use jellycommon::{
- jellyobject::{EMPTY, Path},
- *,
-};
+use jellycommon::{jellyobject::Path, *};
use jellydb::{Filter, MultiBehaviour, Query, Sort, SortOrder, ValueSort};
use jellyui::components::items::Items;
use rocket::{get, response::content::RawHtml};
-use std::borrow::Cow;
#[get("/items?<cont>")]
pub fn r_items(ri: RequestInfo, cont: Option<&str>) -> MyResult<RawHtml<String>> {
@@ -45,9 +44,8 @@ pub fn r_items(ri: RequestInfo, cont: Option<&str>) -> MyResult<RawHtml<String>>
items.clear();
cont_out = None;
- for (r, is) in rows {
- let node = txn.get(r)?.unwrap();
- items.push(node);
+ for (row, is) in rows {
+ items.push(create_nku(txn, row)?);
cont_out = Some(is)
}
Ok(())
@@ -55,14 +53,7 @@ pub fn r_items(ri: RequestInfo, cont: Option<&str>) -> MyResult<RawHtml<String>>
Ok(ri.respond_ui(&Items {
ri: &ri.render_info(),
- items: &items
- .iter()
- .map(|node| Nku {
- node: Cow::Borrowed(node),
- userdata: Cow::Borrowed(EMPTY),
- role: None,
- })
- .collect::<Vec<_>>(),
+ items: &items,
cont: cont_out.map(|x| BASE64_URL_SAFE.encode(x)),
}))
}
diff --git a/server/src/routes/node.rs b/server/src/routes/node.rs
index d7ef0b5..d8d9ba5 100644
--- a/server/src/routes/node.rs
+++ b/server/src/routes/node.rs
@@ -33,11 +33,7 @@ pub fn r_node(ri: RequestInfo<'_>, slug: &str) -> MyResult<RawHtml<String>> {
children = c_children(txn, row, &n)?;
credits = c_credits(txn, &n)?;
credited = c_credited(txn, row)?;
- nku = Some(Nku {
- node: Cow::Owned(n),
- userdata: Cow::Borrowed(EMPTY),
- role: None,
- });
+ nku = Some(create_nku(txn, row)?);
}
Ok(())
})?;
@@ -80,11 +76,7 @@ fn c_children(txn: &mut dyn Transaction, row: u64, node: &Object) -> Result<Vec<
let mut list = Vec::new();
for (row, _) in children_rows {
- list.push(Nku {
- node: Cow::Owned(txn.get(row)?.unwrap()),
- role: None,
- userdata: Cow::Borrowed(EMPTY),
- });
+ list.push(create_nku(txn, row)?);
}
Ok(list)
}
@@ -103,9 +95,8 @@ fn c_credits(txn: &mut dyn Transaction, node: &Object) -> Result<Vec<(Tag, Vec<N
cats.entry(cred.get(CR_KIND).unwrap_or(CRCAT_CREW))
.or_default()
.push(Nku {
- node: Cow::Owned(txn.get(row)?.unwrap()),
role: cred.get(CR_ROLE).map(String::from).map(Cow::Owned),
- userdata: Cow::Borrowed(EMPTY),
+ ..create_nku(txn, row)?
});
}
let mut cats = cats.into_iter().collect::<Vec<_>>();
@@ -137,10 +128,22 @@ fn c_credited(txn: &mut dyn Transaction, row: u64) -> Result<Vec<Nku<'static>>>
let mut list = Vec::new();
for (row, _) in children_rows {
list.push(Nku {
- node: Cow::Owned(txn.get(row)?.unwrap()),
role: None,
- userdata: Cow::Borrowed(EMPTY),
+ ..create_nku(txn, row)?
});
}
Ok(list)
}
+
+pub fn create_nku(txn: &mut dyn Transaction, row: u64) -> Result<Nku<'static>> {
+ let child_count = txn.count(Query {
+ filter: Filter::Match(Path(vec![NO_PARENT.0]), row.into()),
+ ..Default::default()
+ })?;
+ Ok(Nku {
+ node: Cow::Owned(txn.get(row)?.unwrap()),
+ role: None,
+ userdata: Cow::Borrowed(EMPTY),
+ child_count,
+ })
+}
diff --git a/server/src/routes/player.rs b/server/src/routes/player.rs
index c6c177e..45fd6de 100644
--- a/server/src/routes/player.rs
+++ b/server/src/routes/player.rs
@@ -4,16 +4,12 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
use super::error::MyResult;
-use crate::request_info::RequestInfo;
+use crate::{request_info::RequestInfo, routes::node::create_nku};
use anyhow::anyhow;
-use jellycommon::{
- jellyobject::{EMPTY, Path},
- *,
-};
+use jellycommon::{jellyobject::Path, *};
use jellydb::{Filter, Query};
use jellyui::components::node_page::Player;
use rocket::{get, response::content::RawHtml};
-use std::borrow::Cow;
// fn jellynative_url(action: &str, seek: f64, secret: &str, node: &str, session: &str) -> String {
// let protocol = if CONF.tls { "https" } else { "http" };
@@ -33,26 +29,22 @@ pub fn r_player(ri: RequestInfo<'_>, t: Option<f64>, slug: &str) -> MyResult<Raw
ri.require_user()?;
let _ = t;
- let mut node = None;
+ let mut nku = None;
ri.state.database.transaction(&mut |txn| {
if let Some(row) = txn.query_single(Query {
filter: Filter::Match(Path(vec![NO_SLUG.0]), slug.into()),
..Default::default()
})? {
- node = Some(txn.get(row)?.unwrap());
+ nku = Some(create_nku(txn, row)?);
}
Ok(())
})?;
- let Some(node) = node else {
+ let Some(nku) = nku else {
Err(anyhow!("no such node"))?
};
Ok(ri.respond_ui(&Player {
ri: &ri.render_info(),
- nku: Nku {
- node: Cow::Borrowed(&node),
- userdata: Cow::Borrowed(EMPTY),
- role: None,
- },
+ nku,
}))
}
diff --git a/server/src/routes/search.rs b/server/src/routes/search.rs
index 401f475..1339b5d 100644
--- a/server/src/routes/search.rs
+++ b/server/src/routes/search.rs
@@ -4,18 +4,14 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use std::{borrow::Cow, time::Instant};
-
use super::error::MyResult;
-use crate::request_info::RequestInfo;
-use jellycommon::{
- jellyobject::{EMPTY, Path},
- *,
-};
+use crate::{request_info::RequestInfo, routes::node::create_nku};
+use jellycommon::{jellyobject::Path, *};
use jellydb::{Filter, Query, Sort};
use jellyui::components::search::Search;
use log::info;
use rocket::{get, response::content::RawHtml};
+use std::time::Instant;
#[get("/search?<q>")]
pub async fn r_search(ri: RequestInfo<'_>, q: Option<&str>) -> MyResult<RawHtml<String>> {
@@ -43,9 +39,8 @@ pub async fn r_search(ri: RequestInfo<'_>, q: Option<&str>) -> MyResult<RawHtml<
.collect::<Result<Vec<_>, _>>()?;
items.clear();
- for (r, _is) in rows {
- let node = txn.get(r)?.unwrap();
- items.push(node);
+ for (row, _is) in rows {
+ items.push(create_nku(txn, row)?);
}
Ok(())
})?;
@@ -54,14 +49,7 @@ pub async fn r_search(ri: RequestInfo<'_>, q: Option<&str>) -> MyResult<RawHtml<
Ok(ri.respond_ui(&Search {
query: q.unwrap_or_default(),
- items: &items
- .iter()
- .map(|node| Nku {
- node: Cow::Borrowed(node),
- userdata: Cow::Borrowed(EMPTY),
- role: None,
- })
- .collect::<Vec<_>>(),
+ items: &items,
ri: &ri.render_info(),
cont: None,
}))
diff --git a/ui/src/components/props.rs b/ui/src/components/props.rs
index db59019..7bc30d7 100644
--- a/ui/src/components/props.rs
+++ b/ui/src/components/props.rs
@@ -36,10 +36,9 @@ markup::define! {
VISI_HIDDEN => {p.visibility{@tr(ri.lang, "prop.vis.hidden")}}
VISI_VISIBLE | _ => {}
}
- // TODO
- // @if !nku.node.children.is_empty() {
- // p { @format!("{} items", nku.node.children.len()) }
- // }
+ @if nku.child_count > 0 {
+ p { @format!("{} items", nku.child_count) }
+ }
@for (kind, value) in nku.node.get(NO_RATINGS).unwrap_or(EMPTY).entries::<f64>() {
@match TypedTag::new(kind) {
RTYP_YOUTUBE_LIKES => {p.likes{ @format_count(value as usize) " Likes" }}