diff options
| -rw-r--r-- | database/src/lib.rs | 5 | ||||
| -rw-r--r-- | server/src/ui/home.rs | 53 | ||||
| -rw-r--r-- | ui/client-style/src/node_list.css | 1 | ||||
| -rw-r--r-- | ui/src/components/node_card.rs | 4 | ||||
| -rw-r--r-- | ui/src/components/node_list.rs | 18 | ||||
| -rw-r--r-- | ui/src/components/node_page.rs | 12 |
6 files changed, 79 insertions, 14 deletions
diff --git a/database/src/lib.rs b/database/src/lib.rs index 6210a27..984502e 100644 --- a/database/src/lib.rs +++ b/database/src/lib.rs @@ -35,13 +35,13 @@ pub trait Transaction { fn count(&mut self, query: Query) -> Result<u64>; } -#[derive(Default)] +#[derive(Default, Clone)] pub struct Query { pub filter: Filter, pub sort: Sort, } -#[derive(Default)] +#[derive(Default, Clone)] pub enum Sort { #[default] None, @@ -49,6 +49,7 @@ pub enum Sort { TextSearch(Path, String), } +#[derive(Clone)] pub struct ValueSort { pub order: SortOrder, pub path: Path, diff --git a/server/src/ui/home.rs b/server/src/ui/home.rs index 2fb4903..99946a0 100644 --- a/server/src/ui/home.rs +++ b/server/src/ui/home.rs @@ -6,10 +6,59 @@ use super::error::MyResult; use crate::{request_info::RequestInfo, ui_responder::UiResponse}; -use jellycommon::jellyobject::ObjectBuffer; +use anyhow::Result; +use jellycommon::{ + KIND_VIDEO, NKU_NODE, NLSTYLE_INLINE, NO_KIND, NO_RELEASEDATE, NODELIST_DISPLAYSTYLE, + NODELIST_ITEM, NODELIST_TITLE, VIEW_NODE_LIST, + jellyobject::{Object, ObjectBuffer, Path}, +}; +use jellydb::{Filter, MultiBehaviour, Query, SortOrder, ValueSort}; use rocket::get; #[get("/home")] pub fn r_home(ri: RequestInfo<'_>) -> MyResult<UiResponse> { - Ok(ri.respond_ui(ObjectBuffer::new(&mut []))) + ri.require_user()?; + + let mut page = ObjectBuffer::empty(); + + let root = home_row( + &ri, + "home.bin.latest_video", + Query { + filter: Filter::Match(Path(vec![NO_KIND.0]), KIND_VIDEO.0.to_be_bytes().to_vec()), + sort: jellydb::Sort::Value(ValueSort { + order: SortOrder::Descending, + path: Path(vec![NO_RELEASEDATE.0]), + multi: MultiBehaviour::First, + offset: None, + }), + }, + )?; + + page = page + .as_object() + .insert_multi(VIEW_NODE_LIST, &[root.as_object()]); + + Ok(ri.respond_ui(page)) +} + +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) } diff --git a/ui/client-style/src/node_list.css b/ui/client-style/src/node_list.css index 370d8df..c9d66eb 100644 --- a/ui/client-style/src/node_list.css +++ b/ui/client-style/src/node_list.css @@ -21,6 +21,7 @@ } .nl.inline { + display: flex; overflow-x: auto; max-width: 100%; flex-wrap: nowrap; diff --git a/ui/src/components/node_card.rs b/ui/src/components/node_card.rs index 00382c8..fc5738a 100644 --- a/ui/src/components/node_card.rs +++ b/ui/src/components/node_card.rs @@ -25,9 +25,9 @@ markup::define! { img[src=u_image(node.get(NO_PICTURES).unwrap_or_default().get(PICT_COVER).unwrap_or_default(), 512), loading="lazy"]; } .cardhover.item { - // @if node.media.is_some() { + @if node.has(NO_TRACK.0) { a.play.icon[href=u_node_slug_player(&slug)] { "play_arrow" } - // } + } @Props { ri, nku: *nku, full: false } } } diff --git a/ui/src/components/node_list.rs b/ui/src/components/node_list.rs index cea6cb1..87ccb08 100644 --- a/ui/src/components/node_list.rs +++ b/ui/src/components/node_list.rs @@ -6,11 +6,23 @@ use crate::{RenderInfo, components::node_card::NodeCard}; use jellycommon::{jellyobject::Object, *}; +use jellyui_locale::tr; markup::define! { NodeList<'a>(ri: &'a RenderInfo<'a>, nl: Object<'a>) { - ul.nl.grid { @for nku in nl.iter(NODELIST_ITEM) { - li { @NodeCard { ri, nku } } - }} + @let ds = nl.get(NODELIST_DISPLAYSTYLE).unwrap_or(NLSTYLE_GRID); + @if ds == NLSTYLE_GRID { + ul.nl.grid { @for nku in nl.iter(NODELIST_ITEM) { + li { @NodeCard { ri, nku } } + }} + } + @if ds == NLSTYLE_INLINE { + @if let Some(title) = nl.get(NODELIST_TITLE) { + h2 { @tr(ri.lang, title) } + } + ul.nl.inline { @for nku in nl.iter(NODELIST_ITEM) { + li { @NodeCard { ri, nku } } + }} + } } } diff --git a/ui/src/components/node_page.rs b/ui/src/components/node_page.rs index c045dcc..921f65d 100644 --- a/ui/src/components/node_page.rs +++ b/ui/src/components/node_page.rs @@ -105,11 +105,13 @@ markup::define! { // } // } // } - details { - summary { @tr(ri.lang, "media.tracks") } - ol { @for track in node.iter(NO_TRACK) { - li { "track" @track.get(TR_NAME) } - }} + @if node.has(NO_TRACK.0) { + details { + summary { @tr(ri.lang, "media.tracks") } + ol { @for track in node.iter(NO_TRACK) { + li { "track" @track.get(TR_NAME) } + }} + } } @if let Some(idents) = node.get(NO_IDENTIFIERS) { details { |