/* 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) 2026 metamuffin */ use super::error::MyResult; use crate::{request_info::RequestInfo, ui_responder::UiResponse}; use anyhow::{Result, anyhow}; use jellycommon::{ jellyobject::{Object, Path}, *, }; use jellydb::{Filter, MultiBehaviour, Query, Sort, SortOrder, ValueSort}; use rocket::get; #[get("/n/")] pub fn r_node(ri: RequestInfo<'_>, slug: &str) -> MyResult { ri.require_user()?; let mut node = None; let mut children = None; ri.state.database.transaction(&mut |txn| { if let Some(row) = txn.query_single(Query { filter: Filter::Match(Path(vec![NO_SLUG.0]), slug.as_bytes().to_vec()), sort: Sort::None, })? { let n = txn.get(row)?.unwrap(); node = Some(Object::EMPTY.insert(NKU_NODE, n.as_object())); let (order, path) = if n.as_object().get(NO_KIND).unwrap_or(KIND_COLLECTION) == KIND_CHANNEL { (SortOrder::Descending, Path(vec![NO_RELEASEDATE.0])) } else { (SortOrder::Ascending, Path(vec![NO_TITLE.0])) }; let rows = txn .query(Query { sort: Sort::Value(ValueSort { multi: MultiBehaviour::First, offset: None, order, path, }), filter: Filter::Match(Path(vec![NO_PARENT.0]), row.to_be_bytes().to_vec()), })? .collect::>>()?; children = Some( rows.into_iter() .map(|(row, _)| { Ok(Object::EMPTY.insert(NKU_NODE, txn.get(row)?.unwrap().as_object())) }) .collect::>>()?, ); } Ok(()) })?; let (Some(node), Some(children)) = (node, children) else { Err(anyhow!("not found"))? }; let children = children.iter().map(|c| c.as_object()).collect::>(); let mut children_list = Object::EMPTY.insert(NODELIST_DISPLAYSTYLE, NLSTYLE_GRID); children_list = children_list .as_object() .insert_multi(NODELIST_ITEM, &children); Ok(ri.respond_ui( Object::EMPTY .insert(VIEW_NODE_PAGE, node.as_object()) .as_object() .insert(VIEW_NODE_LIST, children_list.as_object()), )) }