From dc7ed1ccaa5e727b3ab0569fd7fe56a2d0084bd5 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 7 Aug 2023 11:10:10 +0200 Subject: node sort ui --- server/src/routes/ui/node.rs | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'server/src/routes/ui/node.rs') diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs index 301f89c..ba16c73 100644 --- a/server/src/routes/ui/node.rs +++ b/server/src/routes/ui/node.rs @@ -3,7 +3,12 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin */ -use super::{assets::rocket_uri_macro_r_item_assets, error::MyError, player::player_uri}; +use super::{ + assets::rocket_uri_macro_r_item_assets, + error::MyError, + player::player_uri, + sort::{filter_and_sort_nodes, NodeFilterSort, NodeFilterSortForm}, +}; use crate::{ database::Database, routes::{ @@ -20,12 +25,19 @@ use anyhow::{anyhow, Context}; use jellycommon::{MediaInfo, NodeKind, NodePublic, Rating, SourceTrackKind}; use rocket::{get, serde::json::Json, Either, State}; +/// This function is a stub and only useful for use in the uri! macro. #[get("/n/")] -pub async fn r_library_node( +pub fn r_library_node(id: String) -> () { + drop(id) +} + +#[get("/n/?")] +pub async fn r_library_node_filter( _sess: Session, id: String, db: &State, aj: AcceptJson, + filter: NodeFilterSort, ) -> Result, Json>, MyError> { let node = db .node @@ -38,7 +50,7 @@ pub async fn r_library_node( return Ok(Either::Right(Json(node))); } - let children = node + let mut children = node .children .iter() .map(|c| { @@ -54,11 +66,13 @@ pub async fn r_library_node( .into_iter() .collect(); + filter_and_sort_nodes(&filter, &mut children); + Ok(Either::Left(LayoutPage { title: node.title.to_string(), show_back: true, //- !matches!(node.kind, NodeKind::Collection), content: markup::new! { - @NodePage { node: &node, id: &id, children: &children } + @NodePage { node: &node, id: &id, children: &children, filter: &filter } }, ..Default::default() })) @@ -88,7 +102,7 @@ markup::define! { } } } - NodePage<'a>(id: &'a str, node: &'a NodePublic, children: &'a Vec<(String, NodePublic)>) { + NodePage<'a>(id: &'a str, node: &'a NodePublic, children: &'a Vec<(String, NodePublic)>, filter: &'a NodeFilterSort) { @if !matches!(node.kind, NodeKind::Collection) { img.backdrop[src=uri!(r_item_assets(id, AssetRole::Backdrop, Some(2048)))]; } @@ -110,6 +124,7 @@ markup::define! { @if let NodeKind::Collection = node.kind { @if let Some(parent) = &node.parent { a.dirup[href=uri!(r_library_node(parent))] { "Go up" } + @NodeFilterSortForm { f: filter } } } @match node.kind { -- cgit v1.2.3-70-g09d2 From 6c1c53aa08eb1c3ae61b472ceb75265a180bd489 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 7 Aug 2023 11:48:38 +0200 Subject: sort and pagination in browser --- server/src/main.rs | 1 + server/src/routes/mod.rs | 4 ++-- server/src/routes/ui/browser.rs | 52 ++++++++++++++++++++++++++++++++++------- server/src/routes/ui/node.rs | 2 +- server/src/routes/ui/sort.rs | 2 +- 5 files changed, 48 insertions(+), 13 deletions(-) (limited to 'server/src/routes/ui/node.rs') diff --git a/server/src/main.rs b/server/src/main.rs index 8f26253..43b1db4 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -4,6 +4,7 @@ Copyright (C) 2023 metamuffin */ #![feature(lazy_cell)] +#![feature(int_roundings)] use crate::routes::ui::admin::log::enable_logging; use database::Database; diff --git a/server/src/routes/mod.rs b/server/src/routes/mod.rs index fe9ef39..6ebde33 100644 --- a/server/src/routes/mod.rs +++ b/server/src/routes/mod.rs @@ -27,7 +27,7 @@ use ui::{ r_admin_remove_invite, r_admin_remove_user, }, assets::r_item_assets, - browser::r_all_items, + browser::r_all_items_filter, error::{r_api_catch, r_catch}, home::{r_home, r_home_unpriv}, node::r_library_node_filter, @@ -87,7 +87,7 @@ pub fn build_rocket( r_home_unpriv, r_favicon, r_item_assets, - r_all_items, + r_all_items_filter, r_library_node_filter, r_assets_style, r_assets_font, diff --git a/server/src/routes/ui/browser.rs b/server/src/routes/ui/browser.rs index 6e772d0..14d32ba 100644 --- a/server/src/routes/ui/browser.rs +++ b/server/src/routes/ui/browser.rs @@ -3,31 +3,65 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2023 metamuffin */ -use super::{account::session::Session, error::MyError, layout::DynLayoutPage, node::NodeCard}; -use crate::database::Database; +use super::{ + account::session::Session, + error::MyError, + layout::DynLayoutPage, + node::NodeCard, + sort::{filter_and_sort_nodes, NodeFilterSort, NodeFilterSortForm}, +}; +use crate::{database::Database, uri}; use anyhow::Context; -use jellycommon::{Node, NodeKind}; +use jellycommon::NodePublic; use rocket::{get, State}; +/// This function is a stub and only useful for use in the uri! macro. #[get("/items")] -pub fn r_all_items(_sess: Session, db: &State) -> Result, MyError> { - let items = db +pub fn r_all_items() {} + +#[get("/items?&")] +pub fn r_all_items_filter( + _sess: Session, + db: &State, + page: Option, + filter: NodeFilterSort, +) -> Result, MyError> { + let mut items = db .node .iter() .map(|e| e.context("listing")) .collect::>>()? .into_iter() - .filter(|(_, n)| matches!(n.public.kind, NodeKind::Movie | NodeKind::Series)) - .collect::>(); + .map(|(k, n)| (k, n.public)) + .collect::>(); + + filter_and_sort_nodes(&filter, &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(super::layout::LayoutPage { title: "All Items".to_owned(), content: markup::new! { .page.dir { h1 { "All Items" } - ul.children { @for (id, node) in &items { - li {@NodeCard { id, node: &node.public }} + @NodeFilterSortForm { f: &filter } + ul.children { @for (id, node) in &items[from..to] { + li {@NodeCard { id, node: &node }} }} + p.pagecontrols { + "Page " @page " of " + @if page > 0 { + a.prev[href=uri!(r_all_items_filter(Some(page - 1), filter.clone()))] { "Previous page" } " " + } + @if page < max_page { + a.next[href=uri!(r_all_items_filter(Some(page + 1), filter.clone()))] { "Next page" } + } + } } }, ..Default::default() diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs index ba16c73..13afbbe 100644 --- a/server/src/routes/ui/node.rs +++ b/server/src/routes/ui/node.rs @@ -27,7 +27,7 @@ use rocket::{get, serde::json::Json, Either, State}; /// This function is a stub and only useful for use in the uri! macro. #[get("/n/")] -pub fn r_library_node(id: String) -> () { +pub fn r_library_node(id: String) { drop(id) } diff --git a/server/src/routes/ui/sort.rs b/server/src/routes/ui/sort.rs index 3ab6cef..ccc3529 100644 --- a/server/src/routes/ui/sort.rs +++ b/server/src/routes/ui/sort.rs @@ -4,7 +4,7 @@ use rocket::{ FromForm, FromFormField, UriDisplayQuery, }; -#[derive(FromForm, UriDisplayQuery)] +#[derive(FromForm, UriDisplayQuery, Default, Clone)] pub struct NodeFilterSort { sort_by: Option, filter_kind: Option>, -- cgit v1.2.3-70-g09d2