aboutsummaryrefslogtreecommitdiff
path: root/server/src/ui/browser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/ui/browser.rs')
-rw-r--r--server/src/ui/browser.rs80
1 files changed, 80 insertions, 0 deletions
diff --git a/server/src/ui/browser.rs b/server/src/ui/browser.rs
new file mode 100644
index 0000000..f7eac93
--- /dev/null
+++ b/server/src/ui/browser.rs
@@ -0,0 +1,80 @@
+/*
+ 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::{
+ error::MyError,
+ layout::{trs, DynLayoutPage, LayoutPage},
+ node::NodeCard,
+ sort::{filter_and_sort_nodes, NodeFilterSort, NodeFilterSortForm, SortOrder, SortProperty},
+};
+use crate::{
+ api::AcceptJson, database::Database, locale::AcceptLanguage, logic::session::Session, uri,
+};
+use jellybase::locale::tr;
+use jellycommon::{api::ApiItemsResponse, Visibility};
+use rocket::{get, serde::json::Json, Either, State};
+
+/// This function is a stub and only useful for use in the uri! macro.
+#[get("/items")]
+pub fn r_all_items() {}
+
+#[get("/items?<page>&<filter..>")]
+pub fn r_all_items_filter(
+ sess: Session,
+ db: &State<Database>,
+ aj: AcceptJson,
+ page: Option<usize>,
+ filter: NodeFilterSort,
+ lang: AcceptLanguage,
+) -> Result<Either<DynLayoutPage<'_>, Json<ApiItemsResponse>>, MyError> {
+ let AcceptLanguage(lang) = lang;
+ let mut items = db.list_nodes_with_udata(sess.user.name.as_str())?;
+
+ items.retain(|(n, _)| matches!(n.visibility, Visibility::Visible));
+
+ filter_and_sort_nodes(
+ &filter,
+ (SortProperty::Title, SortOrder::Ascending),
+ &mut items,
+ );
+
+ let page_size = 100;
+ let page = page.unwrap_or(0);
+ let offset = page * page_size;
+ let from = offset.min(items.len());
+ let to = (offset + page_size).min(items.len());
+ let max_page = items.len().div_ceil(page_size);
+
+ Ok(if *aj {
+ Either::Right(Json(ApiItemsResponse {
+ count: items.len(),
+ pages: max_page,
+ items: items[from..to].to_vec(),
+ }))
+ } else {
+ Either::Left(LayoutPage {
+ title: "All Items".to_owned(),
+ content: markup::new! {
+ .page.dir {
+ h1 { "All Items" }
+ @NodeFilterSortForm { f: &filter, lang: &lang }
+ ul.children { @for (node, udata) in &items[from..to] {
+ li {@NodeCard { node, udata, lang: &lang }}
+ }}
+ p.pagecontrols {
+ span.current { @tr(lang, "page.curr").replace("{cur}", &(page + 1).to_string()).replace("{max}", &max_page.to_string()) " " }
+ @if page > 0 {
+ a.prev[href=uri!(r_all_items_filter(Some(page - 1), filter.clone()))] { @trs(&lang, "page.prev") } " "
+ }
+ @if page + 1 < max_page {
+ a.next[href=uri!(r_all_items_filter(Some(page + 1), filter.clone()))] { @trs(&lang, "page.next") }
+ }
+ }
+ }
+ },
+ ..Default::default()
+ })
+ })
+}