aboutsummaryrefslogtreecommitdiff
path: root/server/src/ui/home.rs
blob: c25add1748f5607f3042c873a0931e3b7c5c8ed9 (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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
    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) 2026 metamuffin <metamuffin.org>
*/

use super::error::MyResult;
use crate::{request_info::RequestInfo, ui_responder::UiResponse};
use anyhow::Result;
use jellycommon::{
    jellyobject::{Object, ObjectBuffer, ObjectBufferBuilder, Path},
    *,
};
use jellydb::{Filter, MultiBehaviour, Query, Sort, SortOrder, ValueSort};
use jellyui::tr;
use rocket::get;

#[get("/home")]
pub fn r_home(ri: RequestInfo<'_>) -> MyResult<UiResponse> {
    ri.require_user()?;

    let mut page = ObjectBufferBuilder::default();

    page.push(VIEW_TITLE, &&*tr(ri.lang, "home"));

    page.push(
        VIEW_NODE_LIST,
        home_row(
            &ri,
            "home.bin.latest_video",
            Query {
                filter: Filter::All(vec![
                    Filter::Match(Path(vec![NO_VISIBILITY.0]), VISI_VISIBLE.into()),
                    Filter::Match(Path(vec![NO_KIND.0]), KIND_VIDEO.into()),
                ]),
                sort: Sort::Value(ValueSort {
                    order: SortOrder::Descending,
                    path: Path(vec![NO_RELEASEDATE.0]),
                    multi: MultiBehaviour::First,
                    offset: None,
                }),
            },
        )?
        .as_object(),
    );
    page.push(
        VIEW_NODE_LIST,
        home_row(
            &ri,
            "home.bin.latest_music",
            Query {
                filter: Filter::All(vec![
                    Filter::Match(Path(vec![NO_VISIBILITY.0]), VISI_VISIBLE.into()),
                    Filter::Match(Path(vec![NO_KIND.0]), KIND_MUSIC.into()),
                ]),
                sort: Sort::Value(ValueSort {
                    order: SortOrder::Descending,
                    path: Path(vec![NO_RELEASEDATE.0]),
                    multi: MultiBehaviour::First,
                    offset: None,
                }),
            },
        )?
        .as_object(),
    );
    page.push(
        VIEW_NODE_LIST,
        home_row(
            &ri,
            "home.bin.max_rating",
            Query {
                filter: Filter::True,
                sort: Sort::Value(ValueSort {
                    order: SortOrder::Descending,
                    path: Path(vec![NO_RATINGS.0, RTYP_TMDB.0]),
                    multi: MultiBehaviour::First,
                    offset: None,
                }),
            },
        )?
        .as_object(),
    );

    Ok(ri.respond_ui(page.finish()))
}

fn home_row(ri: &RequestInfo<'_>, title: &str, q: Query) -> Result<ObjectBuffer> {
    let mut res = ObjectBuffer::empty();
    ri.state.database.transaction(&mut |txn| {
        let rows = txn.query(q.clone())?.take(16).collect::<Result<Vec<_>>>()?;

        let mut nkus = Vec::new();
        for (row, _) in rows {
            let node = txn.get(row)?.unwrap();
            nkus.push(ObjectBuffer::new(&mut [(NKU_NODE.0, &node.as_object())]));
        }
        let nkus = nkus.iter().map(|n| n.as_object()).collect::<Vec<_>>(); // TODO -_-

        res = Object::EMPTY.insert(NODELIST_DISPLAYSTYLE, NLSTYLE_INLINE);
        res = res.as_object().insert(NODELIST_TITLE, title);
        res = res.as_object().insert_multi(NODELIST_ITEM, &nkus);

        Ok(())
    })?;
    Ok(res)
}