aboutsummaryrefslogtreecommitdiff
path: root/ui/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-02-22 03:22:39 +0100
committermetamuffin <metamuffin@disroot.org>2026-02-22 03:22:39 +0100
commitaa13fade6fcabf9122babac7ac812a433a81b627 (patch)
treef284f4d1502e3c75d37508ee0e8219add6c095a6 /ui/src
parenteb46c37ebf2453f334bac086dbf9e91837dd082b (diff)
downloadjellything-aa13fade6fcabf9122babac7ac812a433a81b627.tar
jellything-aa13fade6fcabf9122babac7ac812a433a81b627.tar.bz2
jellything-aa13fade6fcabf9122babac7ac812a433a81b627.tar.zst
node highlight card + css cleanup
Diffstat (limited to 'ui/src')
-rw-r--r--ui/src/components/node_card.rs35
-rw-r--r--ui/src/components/node_list.rs38
-rw-r--r--ui/src/components/node_page.rs11
-rw-r--r--ui/src/components/props.rs6
-rw-r--r--ui/src/format.rs90
5 files changed, 96 insertions, 84 deletions
diff --git a/ui/src/components/node_card.rs b/ui/src/components/node_card.rs
index eb00ccc..d93825b 100644
--- a/ui/src/components/node_card.rs
+++ b/ui/src/components/node_card.rs
@@ -18,13 +18,12 @@ markup::define! {
NodeCard<'a>(ri: &'a RenderInfo<'a>, nku: Object<'a>) {
@let node = nku.get(NKU_NODE).unwrap_or_default();
@let slug = node.get(NO_SLUG).unwrap_or_default();
- @let cls = format!("node card poster {}", aspect_class(node));
- div[class=cls] {
+ div[class=&format!("card {}", aspect_class(node))] {
.poster {
a[href=u_node_slug(&slug)] {
img[src=cover_image(&node, 512), loading="lazy"];
}
- .cardhover.item {
+ .overlay {
@if node.has(NO_TRACK.0) {
a.play.icon[href=u_node_slug_player(&slug)] { "play_arrow" }
}
@@ -43,15 +42,16 @@ markup::define! {
}
}
}
+
NodeCardWide<'a>(ri: &'a RenderInfo<'a>, nku: Object<'a>) {
@let node = nku.get(NKU_NODE).unwrap_or_default();
@let slug = node.get(NO_SLUG).unwrap_or_default();
- div[class="node card widecard poster"] {
+ div[class="card wide"] {
div[class=&format!("poster {}", aspect_class(node))] {
a[href=u_node_slug(&slug)] {
img[src=cover_image(&node, 512), loading="lazy"];
}
- .cardhover.item {
+ .overlay {
@if node.has(NO_TRACK.0) {
a.play.icon[href=u_node_slug_player(&slug)] { "play_arrow" }
}
@@ -64,6 +64,31 @@ markup::define! {
}
}
}
+
+ NodeCardHightlight<'a>(ri: &'a RenderInfo<'a>, nku: Object<'a>) {
+ @let node = nku.get(NKU_NODE).unwrap_or_default();
+ @let slug = node.get(NO_SLUG).unwrap_or_default();
+ @let backdrop = u_image(node.get(NO_PICTURES).unwrap_or_default().get(PICT_BACKDROP).unwrap_or_default(), 2048);
+ div[class="card highlight", style=format!("background-image: url(\"{backdrop}\")")] {
+ .inner {
+ div.overview {
+ h2 { a[href=u_node_slug(slug)] { @node.get(NO_TITLE) } }
+ @Props { ri, nku: *nku, full: false }
+ p { b { @node.get(NO_TAGLINE) } " " @node.get(NO_DESCRIPTION) }
+ }
+ div[class=&format!("poster {}", aspect_class(node))] {
+ a[href=u_node_slug(&slug)] {
+ img[src=cover_image(&node, 512), loading="lazy"];
+ }
+ .overlay {
+ @if node.has(NO_TRACK.0) {
+ a.play.icon[href=u_node_slug_player(&slug)] { "play_arrow" }
+ }
+ }
+ }
+ }
+ }
+ }
}
fn cover_image(node: &Object, size: usize) -> String {
diff --git a/ui/src/components/node_list.rs b/ui/src/components/node_list.rs
index d1d16fb..679a11d 100644
--- a/ui/src/components/node_list.rs
+++ b/ui/src/components/node_list.rs
@@ -6,7 +6,7 @@
use crate::{
RenderInfo,
- components::node_card::{NodeCard, NodeCardWide},
+ components::node_card::{NodeCard, NodeCardHightlight, NodeCardWide},
};
use jellycommon::{jellyobject::Object, *};
use jellyui_locale::tr;
@@ -17,20 +17,28 @@ markup::define! {
@if let Some(title) = nl.get(NODELIST_TITLE) {
h2 { @tr(ri.lang, title) }
}
- @if ds == NLSTYLE_GRID {
- ul.nl.grid { @for nku in nl.iter(NODELIST_ITEM) {
- li { @NodeCard { ri, nku } }
- }}
- }
- @if ds == NLSTYLE_INLINE {
- ul.nl.inline { @for nku in nl.iter(NODELIST_ITEM) {
- li { @NodeCard { ri, nku } }
- }}
- }
- @if ds == NLSTYLE_LIST {
- ol.nl.list { @for nku in nl.iter(NODELIST_ITEM) {
- li { @NodeCardWide { ri, nku } }
- }}
+ @match ds {
+ NLSTYLE_GRID => {
+ ul.nl.grid { @for nku in nl.iter(NODELIST_ITEM) {
+ li { @NodeCard { ri, nku } }
+ }}
+ }
+ NLSTYLE_INLINE => {
+ ul.nl.inline { @for nku in nl.iter(NODELIST_ITEM) {
+ li { @NodeCard { ri, nku } }
+ }}
+ }
+ NLSTYLE_LIST => {
+ ol.nl.list { @for nku in nl.iter(NODELIST_ITEM) {
+ li { @NodeCardWide { ri, nku } }
+ }}
+ }
+ NLSTYLE_HIGHLIGHT => {
+ @if let Some(nku) = nl.get(NODELIST_ITEM) {
+ @NodeCardHightlight { ri, nku }
+ }
+ }
+ _ => {}
}
}
}
diff --git a/ui/src/components/node_page.rs b/ui/src/components/node_page.rs
index 7deaf61..5823933 100644
--- a/ui/src/components/node_page.rs
+++ b/ui/src/components/node_page.rs
@@ -181,6 +181,7 @@ markup::define! {
}
Player<'a>(ri: &'a RenderInfo<'a>, nku: Object<'a>) {
+ @let _ = ri;
@let node = nku.get(NKU_NODE).unwrap_or_default();
@let pics = node.get(NO_PICTURES).unwrap_or_default();
video[id="player", poster=pics.get(PICT_COVER).map(|p| u_image(p, 2048))] {}
@@ -188,11 +189,11 @@ markup::define! {
}
-fn chapter_key_time(c: Object, dur: f64) -> f64 {
- let start = c.get(CH_START).unwrap_or(0.);
- let end = c.get(CH_END).unwrap_or(dur);
- start * 0.8 + end * 0.2
-}
+// fn chapter_key_time(c: Object, dur: f64) -> f64 {
+// let start = c.get(CH_START).unwrap_or(0.);
+// let end = c.get(CH_END).unwrap_or(dur);
+// start * 0.8 + end * 0.2
+// }
pub fn aspect_class(node: Object<'_>) -> &'static str {
let kind = node.get(NO_KIND).unwrap_or(KIND_COLLECTION);
diff --git a/ui/src/components/props.rs b/ui/src/components/props.rs
index c11dca6..5fa9d3e 100644
--- a/ui/src/components/props.rs
+++ b/ui/src/components/props.rs
@@ -47,11 +47,11 @@ markup::define! {
RTYP_YOUTUBE_LIKES => {p.likes{ @format_count(value as usize) " Likes" }}
RTYP_YOUTUBE_VIEWS => {p{ @format_count(value as usize) " Views" }}
RTYP_YOUTUBE_SUBSCRIBERS => {p{ @format_count(value as usize) " Subscribers" }}
- RTYP_ROTTEN_TOMATOES => {p.rating{ "Rotten Tomatoes: " @value "%" }}
+ RTYP_ROTTEN_TOMATOES if *full => {p.rating{ "Rotten Tomatoes: " @value "%" }}
RTYP_METACRITIC if *full => {p.rating{ "Metacritic: " @value "/100" }}
RTYP_IMDB => {p.rating{ "IMDb " @value }}
- RTYP_TMDB => {p.rating{ "TMDB " @format!("{:.01}", value) }}
- RTYP_TRAKT => {p.rating{ "Trakt " @format!("{:.01}", value) }}
+ RTYP_TMDB if *full => {p.rating{ "TMDB " @format!("{:.01}", value) }}
+ RTYP_TRAKT if *full => {p.rating{ "Trakt " @format!("{:.01}", value) }}
_ => {}
}
}
diff --git a/ui/src/format.rs b/ui/src/format.rs
index 4eb8f84..46d7154 100644
--- a/ui/src/format.rs
+++ b/ui/src/format.rs
@@ -4,12 +4,8 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use jellycommon::{
- jellyobject::{Object, Tag},
- *,
-};
use jellyui_locale::tr;
-use std::{borrow::Cow, fmt::Write};
+use std::fmt::Write;
pub fn format_duration(d: f64) -> String {
format_duration_mode("en", d, false)
@@ -73,48 +69,30 @@ fn test_duration_long() {
pub fn format_size(size: u64) -> String {
humansize::format_size(size, humansize::DECIMAL)
}
-pub fn format_kind(lang: &str, kind: Tag) -> Cow<'static, str> {
- tr(
- lang,
- match kind {
- KIND_MOVIE => "kind.movie",
- KIND_VIDEO => "kind.video",
- KIND_MUSIC => "kind.music",
- KIND_SHORTFORMVIDEO => "kind.short_form_video",
- KIND_COLLECTION => "kind.collection",
- KIND_CHANNEL => "kind.channel",
- KIND_SHOW => "kind.show",
- KIND_SERIES => "kind.series",
- KIND_SEASON => "kind.season",
- KIND_EPISODE => "kind.episode",
- _ => "kind.unknown",
- },
- )
-}
-pub fn node_resolution_name(node: &Object) -> &'static str {
- let mut maxdim = 0;
- for t in node.iter(NO_TRACK) {
- if let Some(width) = t.get(TR_PIXEL_WIDTH) {
- maxdim = maxdim.max(width)
- }
- if let Some(height) = t.get(TR_PIXEL_HEIGHT) {
- maxdim = maxdim.max(height)
- }
- }
- match maxdim {
- 30720.. => "32K",
- 15360.. => "16K",
- 7680.. => "8K UHD",
- 5120.. => "5K UHD",
- 3840.. => "4K UHD",
- 2560.. => "QHD 1440p",
- 1920.. => "FHD 1080p",
- 1280.. => "HD 720p",
- 854.. => "SD 480p",
- _ => "Unkown",
- }
-}
+// pub fn node_resolution_name(node: &Object) -> &'static str {
+// let mut maxdim = 0;
+// for t in node.iter(NO_TRACK) {
+// if let Some(width) = t.get(TR_PIXEL_WIDTH) {
+// maxdim = maxdim.max(width)
+// }
+// if let Some(height) = t.get(TR_PIXEL_HEIGHT) {
+// maxdim = maxdim.max(height)
+// }
+// }
+// match maxdim {
+// 30720.. => "32K",
+// 15360.. => "16K",
+// 7680.. => "8K UHD",
+// 5120.. => "5K UHD",
+// 3840.. => "4K UHD",
+// 2560.. => "QHD 1440p",
+// 1920.. => "FHD 1080p",
+// 1280.. => "HD 720p",
+// 854.. => "SD 480p",
+// _ => "Unkown",
+// }
+// }
pub fn format_count(n: impl Into<usize>) -> String {
let n: usize = n.into();
@@ -128,13 +106,13 @@ pub fn format_count(n: impl Into<usize>) -> String {
}
}
-pub fn format_chapter(c: &Object) -> (String, String) {
- (
- format!(
- "{}-{}",
- c.get(CH_START).map(format_duration).unwrap_or_default(),
- c.get(CH_END).map(format_duration).unwrap_or_default(),
- ),
- c.get(CH_NAME).unwrap_or_default().to_string(),
- )
-}
+// pub fn format_chapter(c: &Object) -> (String, String) {
+// (
+// format!(
+// "{}-{}",
+// c.get(CH_START).map(format_duration).unwrap_or_default(),
+// c.get(CH_END).map(format_duration).unwrap_or_default(),
+// ),
+// c.get(CH_NAME).unwrap_or_default().to_string(),
+// )
+// }