diff options
author | metamuffin <metamuffin@disroot.org> | 2023-12-14 13:32:33 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-12-14 13:32:33 +0100 |
commit | 3249838ec4d112142bda51c825b7db909fd16ff3 (patch) | |
tree | 22d3e3f63f996e89248bf2a8952b2394798152a3 /server | |
parent | 4ffdad8d8eec70ce47afb36049f96992653b5548 (diff) | |
download | jellything-3249838ec4d112142bda51c825b7db909fd16ff3.tar jellything-3249838ec4d112142bda51c825b7db909fd16ff3.tar.bz2 jellything-3249838ec4d112142bda51c825b7db909fd16ff3.tar.zst |
home page with toplevel, latest release and daily random
Diffstat (limited to 'server')
-rw-r--r-- | server/src/routes/ui/home.rs | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/server/src/routes/ui/home.rs b/server/src/routes/ui/home.rs index c544336..d9d1100 100644 --- a/server/src/routes/ui/home.rs +++ b/server/src/routes/ui/home.rs @@ -3,28 +3,84 @@ 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, layout::LayoutPage}; +use super::{account::session::Session, layout::LayoutPage, node::NodeCard}; use crate::{ database::Database, routes::ui::{error::MyResult, layout::DynLayoutPage}, }; +use anyhow::Context; +use chrono::{Datelike, Utc}; use jellybase::CONF; +use jellycommon::NodePublic; use rocket::{get, State}; use tokio::fs::read_to_string; #[get("/")] -pub fn r_home(_sess: Session, _db: &State<Database>) -> DynLayoutPage { - LayoutPage { +pub fn r_home(sess: Session, db: &State<Database>) -> MyResult<DynLayoutPage> { + let mut items = db + .node + .iter() + .map(|e| e.context("listing")) + .collect::<anyhow::Result<Vec<_>>>()? + .into_iter() + .map(|(k, n)| (k, n.public)) + .collect::<Vec<(String, NodePublic)>>(); + + let random = (0..16) + .flat_map(|i| Some(items[cheap_daily_random(i).checked_rem(items.len())?].clone())) + .collect::<Vec<_>>(); + + let toplevel = db + .node + .get(&"library".to_string())? + .context("root node missing")? + .public + .children + .into_iter() + .map(|n| { + Ok(( + n.clone(), + db.node.get(&n)?.context("child does not exist")?.public, + )) + }) + .collect::<anyhow::Result<Vec<_>>>()? + .into_iter() + .collect::<Vec<_>>(); + + items.sort_by_key(|(_, n)| { + n.release_date + .map(|d| d.naive_utc().timestamp()) + .unwrap_or(0) + }); + + let latest = items + .iter() + .take(16) + .map(|k| k.to_owned()) + .collect::<Vec<_>>(); + + Ok(LayoutPage { title: "Home".to_string(), content: markup::new! { - p { "Welcome to " @CONF.brand } + p { "Welcome back " @sess.user.display_name } + h2 { "Explore " @CONF.brand } + .homelist { ul {@for (id, node) in &toplevel { + li { @NodeCard { id, node } } + }}} + h2 { "Latest Releases" } + .homelist { ul {@for (id, node) in &latest { + li { @NodeCard { id, node } } + }}} + h2 { "Today's Picks" } + .homelist { ul {@for (id, node) in &random { + li { @NodeCard { id, node } } + }}} p.error { "TODO: continue watching" } p.error { "TODO: recently added" } p.error { "TODO: best rating" } - p.error { "TODO: random" } }, ..Default::default() - } + }) } #[get("/", rank = 2)] @@ -38,3 +94,14 @@ pub async fn r_home_unpriv() -> MyResult<DynLayoutPage<'static>> { ..Default::default() }) } + +fn cheap_daily_random(i: usize) -> usize { + xorshift(xorshift(Utc::now().num_days_from_ce() as u64) + i as u64) as usize +} + +fn xorshift(mut x: u64) -> u64 { + x ^= x << 13; + x ^= x >> 7; + x ^= x << 17; + x +} |