aboutsummaryrefslogtreecommitdiff
path: root/ui/src/node_page.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-01-23 04:19:24 +0100
committermetamuffin <metamuffin@disroot.org>2026-01-23 04:19:24 +0100
commit3671a4e07565c86f8071fb2309f463aeaf684ba3 (patch)
tree9a9057c7dcc174ada17a45a195502ff94b2f2946 /ui/src/node_page.rs
parent10cdaaa30a6b4a187797434dc8d959780f0e8fbf (diff)
downloadjellything-3671a4e07565c86f8071fb2309f463aeaf684ba3.tar
jellything-3671a4e07565c86f8071fb2309f463aeaf684ba3.tar.bz2
jellything-3671a4e07565c86f8071fb2309f463aeaf684ba3.tar.zst
move ui code around
Diffstat (limited to 'ui/src/node_page.rs')
-rw-r--r--ui/src/node_page.rs218
1 files changed, 0 insertions, 218 deletions
diff --git a/ui/src/node_page.rs b/ui/src/node_page.rs
deleted file mode 100644
index f52ea5b..0000000
--- a/ui/src/node_page.rs
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- 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 crate::{Page, scaffold::RenderInfo};
-use jellycommon::{
- jellyobject::{Object, Tag, TypedTag},
- *,
-};
-use std::marker::PhantomData;
-
-impl Page for NodePage<'_> {
- fn title(&self) -> String {
- self.node.node.get(NO_TITLE).unwrap_or_default().to_string()
- }
- fn class(&self) -> Option<&'static str> {
- Some("node-page")
- }
- fn to_render(&self) -> markup::DynRender<'_> {
- markup::new!(@self)
- }
-}
-
-pub struct NodeUdata<'a> {
- pub node: Object<'a>,
- pub udata: Object<'a>,
-}
-
-markup::define! {
- NodePage<'a>(
- ri: &'a RenderInfo<'a>,
- node: NodeUdata<'a>,
- children: &'a [NodeUdata<'a>],
- parents: &'a [NodeUdata<'a>],
- similar: &'a [NodeUdata<'a>],
- ) {
- // @if !matches!(node.kind, NodeKind::Collection) && !player {
- // img.backdrop[src=u_node_image(&node.slug, PictureSlot::Backdrop, 2048), loading="lazy"];
- // }
- // .page.node {
- // @if !matches!(node.kind, NodeKind::Collection) && !player {
- // @let cls = format!("bigposter {}", aspect_class(node.kind));
- // div[class=cls] { img[src=u_node_image(&node.slug, PictureSlot::Cover, 2048), loading="lazy"]; }
- // }
- // .title {
- // h1 { @node.title }
- // ul.parents { @for (node, _) in *parents { li {
- // a.component[href=u_node_slug(&node.slug)] { @node.title }
- // }}}
- // @if node.media.is_some() {
- // a.play[href=u_node_slug_player(&node.slug)] { @trs(lang, "node.player_link") }
- // }
- // @if !matches!(node.kind, NodeKind::Collection | NodeKind::Channel) {
- // @if matches!(udata.watched, WatchedState::None | WatchedState::Pending | WatchedState::Progress(_)) {
- // form.mark_watched[method="POST", action=u_node_slug_watched(&node.slug, ApiWatchedState::Watched)] {
- // input[type="submit", value=trs(lang, "node.watched.set")];
- // }
- // }
- // @if matches!(udata.watched, WatchedState::Watched) {
- // form.mark_unwatched[method="POST", action=u_node_slug_watched(&node.slug, ApiWatchedState::None)] {
- // input[type="submit", value=trs(lang, "node.watched.unset")];
- // }
- // }
- // @if matches!(udata.watched, WatchedState::None) {
- // form.mark_unwatched[method="POST", action=u_node_slug_watched(&node.slug, ApiWatchedState::Pending)] {
- // input[type="submit", value=trs(lang, "node.watchlist.set")];
- // }
- // }
- // @if matches!(udata.watched, WatchedState::Pending) {
- // form.mark_unwatched[method="POST", action=u_node_slug_watched(&node.slug, ApiWatchedState::None)] {
- // input[type="submit", value=trs(lang, "node.watchlist.unset")];
- // }
- // }
- // form.rating[method="POST", action=u_node_slug_update_rating(&node.slug)] {
- // input[type="range", name="rating", min=-10, max=10, step=1, value=udata.rating];
- // input[type="submit", value=trs(lang, "node.update_rating")];
- // }
- // }
- // }
- // .details {
- // @Props { node, udata, full: true, lang }
- // h3 { @node.tagline }
- // @if let Some(description) = &node.description {
- // p { @for line in description.lines() { @line br; } }
- // }
- // @if let Some(media) = &node.media {
- // @if !media.chapters.is_empty() {
- // h2 { @trs(lang, "node.chapters") }
- // ul.children.hlist { @for chap in &media.chapters {
- // @let (inl, sub) = format_chapter(chap);
- // li { .card."aspect-thumb" {
- // .poster {
- // a[href=u_node_slug_player_time(&node.slug, chap.time_start.unwrap_or(0.))] {
- // img[src=u_node_slug_thumbnail(&node.slug, chapter_key_time(chap, media.duration), 1024), loading="lazy"];
- // }
- // .cardhover { .props { p { @inl } } }
- // }
- // .title { span { @sub } }
- // }}
- // }}
- // }
- // @if !node.credits.is_empty() {
- // h2 { @trs(lang, "node.people") }
- // @for (group, people) in &node.credits {
- // details[open=group==&CreditCategory::Cast] {
- // summary { h3 { @format!("{}", group) } }
- // ul.children.hlist { @for (i, pe) in people.iter().enumerate() {
- // li { .card."aspect-port" {
- // .poster {
- // a[href="#"] {
- // img[src=u_node_slug_person_asset(&node.slug, *group, i, 1024), loading="lazy"];
- // }
- // }
- // .title {
- // // TODO span { @pe.person.name } br;
- // @if let Some(c) = pe.characters.first() {
- // span.subtitle { @c }
- // }
- // @if let Some(c) = pe.jobs.first() {
- // span.subtitle { @c }
- // }
- // }
- // }}
- // }}
- // }
- // }
- // }
- // details {
- // summary { @trs(lang, "media.tracks") }
- // ol { @for track in &media.tracks {
- // li { @format!("{track}") }
- // }}
- // }
- // }
- // @if !node.identifiers.is_empty() {
- // details {
- // summary { @trs(lang, "node.external_ids") }
- // table {
- // @for (key, value) in &node.identifiers { tr {
- // tr {
- // td { @trs(lang, &format!("id.{}", key)) }
- // @if let Some(url) = external_id_url(*key, value) {
- // td { a[href=url] { pre { @value } } }
- // } else {
- // td { pre { @value } }
- // }
- // }
- // }}
- // }
- // }
- // }
- // @if !node.tags.is_empty() {
- // details {
- // summary { @trs(lang, "node.tags") }
- // ol { @for tag in &node.tags {
- // li { @tag }
- // }}
- // }
- // }
- // }
- // @if matches!(node.kind, NodeKind::Collection | NodeKind::Channel) {
- // @NodeFilterSortForm { f: filter, lang }
- // }
- // @if !similar.is_empty() {
- // h2 { @trs(lang, "node.similar") }
- // ul.children.hlist {@for (node, udata) in similar.iter() {
- // li { @NodeCard { node, udata, lang } }
- // }}
- // }
- // @match node.kind {
- // NodeKind::Show | NodeKind::Series | NodeKind::Season => {
- // ol { @for (node, udata) in children.iter() {
- // li { @NodeCardWide { node, udata, lang } }
- // }}
- // }
- // NodeKind::Collection | NodeKind::Channel | _ => {
- // ul.children {@for (node, udata) in children.iter() {
- // li { @NodeCard { node, udata, lang } }
- // }}
- // }
- // }
- // }
- }
-}
-
-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(kind: Tag) -> &'static str {
- match kind {
- KIND_VIDEO | KIND_EPISODE => "aspect-thumb",
- KIND_COLLECTION => "aspect-land",
- KIND_SEASON | KIND_SHOW | KIND_SERIES | KIND_MOVIE | KIND_SHORTFORMVIDEO => "aspect-port",
- KIND_CHANNEL | KIND_MUSIC | _ => "aspect-square",
- }
-}
-
-fn external_id_url(key: Tag, value: &str) -> Option<String> {
- Some(match TypedTag(key, PhantomData) {
- IDENT_YOUTUBE_VIDEO => format!("https://youtube.com/watch?v={value}"),
- IDENT_YOUTUBE_CHANNEL => format!("https://youtube.com/channel/{value}"),
- IDENT_YOUTUBE_CHANNEL_HANDLE => format!("https://youtube.com/channel/@{value}"),
- IDENT_MUSICBRAINZ_RELEASE => format!("https://musicbrainz.org/release/{value}"),
- IDENT_MUSICBRAINZ_ARTIST => format!("https://musicbrainz.org/artist/{value}"),
- IDENT_MUSICBRAINZ_RELEASE_GROUP => {
- format!("https://musicbrainz.org/release-group/{value}")
- }
- IDENT_MUSICBRAINZ_RECORDING => {
- format!("https://musicbrainz.org/recording/{value}")
- }
- _ => return None,
- })
-}