aboutsummaryrefslogtreecommitdiff
path: root/server/src/routes/ui/browser.rs
blob: e811516e4d5a3a64b53d67afc7697c8a8866cf0e (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
81
/*
    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) 2023 metamuffin <metamuffin.org>
*/
use super::{
    account::session::Session,
    error::MyError,
    layout::DynLayoutPage,
    node::NodeCard,
    sort::{filter_and_sort_nodes, NodeFilterSort, NodeFilterSortForm},
};
use crate::{database::DataAcid, uri};
use jellybase::database::{ReadableTable, T_NODE, T_USER_NODE};
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() {}

#[get("/items?<page>&<filter..>")]
pub fn r_all_items_filter(
    sess: Session,
    db: &State<DataAcid>,
    page: Option<usize>,
    filter: NodeFilterSort,
) -> Result<DynLayoutPage<'_>, MyError> {
    let mut items = {
        let txn = db.begin_read()?;
        let nodes = txn.open_table(T_NODE)?;
        let node_users = txn.open_table(T_USER_NODE)?;
        let i = nodes
            .iter()?
            .map(|a| {
                let (x, y) = a.unwrap();
                let (x, y) = (x.value().to_owned(), y.value().0);
                let z = node_users
                    .get(&(sess.user.name.as_str(), x.as_str()))
                    .unwrap()
                    .map(|z| z.value().0)
                    .unwrap_or_default();
                let y = y.public;
                (x, y, z)
            })
            .collect::<Vec<_>>();
        drop(nodes);
        i
    };

    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" }
                @NodeFilterSortForm { f: &filter }
                ul.children { @for (id, node, udata) in &items[from..to] {
                    li {@NodeCard { id, node, udata }}
                }}
                p.pagecontrols {
                    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 + 1 < max_page {
                        a.next[href=uri!(r_all_items_filter(Some(page + 1), filter.clone()))] { "Next page" }
                    }
                }
            }
        },
        ..Default::default()
    })
}