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/routes/ui/browser.rs | 52 ++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 9 deletions(-) (limited to 'server/src/routes/ui/browser.rs') 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() -- cgit v1.2.3-70-g09d2 From b8d46141a13610f7451d7ad809691b0dd99b5f89 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 7 Aug 2023 11:59:45 +0200 Subject: sort filter fixup --- server/src/routes/ui/browser.rs | 4 ++-- server/src/routes/ui/sort.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'server/src/routes/ui/browser.rs') diff --git a/server/src/routes/ui/browser.rs b/server/src/routes/ui/browser.rs index 14d32ba..d2c24bc 100644 --- a/server/src/routes/ui/browser.rs +++ b/server/src/routes/ui/browser.rs @@ -54,11 +54,11 @@ pub fn r_all_items_filter( li {@NodeCard { id, node: &node }} }} p.pagecontrols { - "Page " @page " of " + span.current { "Page " @{page + 1} " of " @max_page " " } @if page > 0 { a.prev[href=uri!(r_all_items_filter(Some(page - 1), filter.clone()))] { "Previous page" } " " } - @if page < max_page { + @if page + 1 < max_page { a.next[href=uri!(r_all_items_filter(Some(page + 1), filter.clone()))] { "Next page" } } } diff --git a/server/src/routes/ui/sort.rs b/server/src/routes/ui/sort.rs index ccc3529..4db8f3d 100644 --- a/server/src/routes/ui/sort.rs +++ b/server/src/routes/ui/sort.rs @@ -47,24 +47,24 @@ pub fn filter_and_sort_nodes(f: &NodeFilterSort, nodes: &mut Vec<(String, NodePu markup::define! { NodeFilterSortForm<'a>(f: &'a NodeFilterSort) { - details { + details.filtersort { summary { "Filter and Sort" } form[method="GET", action=""] { - fieldset { + fieldset.filter { legend { "Filter" } @use NodeKind::*; - @for (value, label) in [(Movie, "Movie"), (Episode, "Episode"), (Video, "Video"), (Channel, "Channel")] { + @for (value, label) in [(Movie, "Movie"), (Episode, "Episode"), (Video, "Video"), (Channel, "Channel"), (Series, "Series"), (Season, "Season"), (Collection, "Collection")] { label { input[type="checkbox", name="filter_kind", value=A(value), checked=f.filter_kind.as_ref().map(|k|k.contains(&value)).unwrap_or(true)]; @label } br; } } - fieldset { + fieldset.sortby { legend { "Sort By" } @use SortProperty::*; @for (value, label) in [(Title, "Title"), (ReleaseDate, "Release Date")] { label { input[type="radio", name="sort_by", value=value, checked=Some(value)==f.sort_by]; @label } br; } } - fieldset { + fieldset.sortorder { legend { "Sort Order" } @use SortOrder::*; @for (value, label) in [(Ascending, "Ascending"), (Descending, "Descending")] { -- cgit v1.2.3-70-g09d2