aboutsummaryrefslogtreecommitdiff
path: root/server/src/ui/browser.rs
blob: f7eac932606fc604ef9b63d253d5fb2659a9f554 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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()
        })
    })
}