aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/src/lib.rs5
-rw-r--r--import/src/lib.rs31
-rw-r--r--server/src/routes/ui/node.rs16
-rw-r--r--web/style/nodecard.css12
-rw-r--r--web/style/themes.css12
5 files changed, 57 insertions, 19 deletions
diff --git a/common/src/lib.rs b/common/src/lib.rs
index 27ca24a..d06c40c 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -44,12 +44,13 @@ pub struct NodePublic {
#[serde(default)] pub poster: Option<Asset>,
#[serde(default)] pub backdrop: Option<Asset>,
-
+
#[serde(default)] pub title: Option<String>,
+ #[serde(default)] pub subtitle: Option<String>,
#[serde(default)] pub id: Option<String>,
#[serde(default)] pub path: Vec<String>,
- #[serde(default)] pub children: Vec<String>,
#[serde(default)] pub tagline: Option<String>,
+ #[serde(default)] pub children: Vec<String>,
#[serde(default)] pub description: Option<String>,
#[serde(default)] pub release_date: Option<i64>, // in unix millis
#[serde(default)] pub index: Option<usize>,
diff --git a/import/src/lib.rs b/import/src/lib.rs
index 33caa77..274b63d 100644
--- a/import/src/lib.rs
+++ b/import/src/lib.rs
@@ -21,6 +21,7 @@ use jellybase::{
};
use jellyclient::Session;
use jellycommon::{
+ chrono::{Datelike, NaiveDateTime},
Asset, ExtendedNode, ImportOptions, ImportSource, MediaInfo, Node, NodeKind, NodePrivate,
NodePublic, PeopleGroup, Rating, SourceTrack, TmdbKind, TrackSource, TraktKind,
};
@@ -143,7 +144,12 @@ pub fn merge_nodes(db: &DataAcid) -> anyhow::Result<()> {
}
pub fn generate_node_paths(db: &DataAcid) -> anyhow::Result<()> {
- fn traverse(db: &DataAcid, c: String, mut path: Vec<String>) -> anyhow::Result<()> {
+ fn traverse(
+ db: &DataAcid,
+ c: String,
+ mut path: Vec<String>,
+ parent_title: &str,
+ ) -> anyhow::Result<()> {
let node = {
let txn = db.inner.begin_write()?;
let mut table = txn.open_table(T_NODE)?;
@@ -159,6 +165,22 @@ pub fn generate_node_paths(db: &DataAcid) -> anyhow::Result<()> {
if node.public.path.is_empty() {
node.public.path = path.clone();
}
+ node.public.subtitle = match node.public.kind.unwrap_or_default() {
+ NodeKind::Movie => node.public.release_date.map(|date| {
+ format!(
+ "{}",
+ NaiveDateTime::from_timestamp_millis(date)
+ .unwrap()
+ .date()
+ .year()
+ )
+ }),
+ NodeKind::Season
+ | NodeKind::Episode
+ | NodeKind::ShortFormVideo
+ | NodeKind::Video => Some(parent_title.to_string()),
+ _ => None,
+ };
table.insert(c.as_str(), Ser(node.clone()))?;
@@ -168,12 +190,13 @@ pub fn generate_node_paths(db: &DataAcid) -> anyhow::Result<()> {
};
path.push(c);
+ let ps = node.public.title.unwrap_or_default();
for c in node.public.children {
- traverse(db, c, path.clone())?;
+ traverse(db, c, path.clone(), &ps)?;
}
Ok(())
}
- traverse(db, "library".to_string(), vec![])?;
+ traverse(db, "library".to_string(), vec![], "Root")?;
Ok(())
}
@@ -653,9 +676,9 @@ fn merge_node(x: Node, y: Node) -> anyhow::Result<Node> {
public: NodePublic {
kind: x.public.kind.or(y.public.kind),
title: x.public.title.or(y.public.title),
+ subtitle: x.public.subtitle.or(y.public.subtitle),
id: x.public.id.or(y.public.id),
path: vec![],
-
children: merge_children(x.public.children, y.public.children),
tagline: x.public.tagline.or(y.public.tagline),
description: x.public.description.or(y.public.description),
diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs
index 3da72cd..327add0 100644
--- a/server/src/routes/ui/node.rs
+++ b/server/src/routes/ui/node.rs
@@ -139,6 +139,11 @@ markup::define! {
@node.title
}
}
+ div.subtitle {
+ span {
+ @node.subtitle
+ }
+ }
}
}
NodePage<'a>(id: &'a str, node: &'a NodePublic, node_ext: &'a ExtendedNode, udata: &'a NodeUserData, children: &'a [(String, NodePublic, NodeUserData)], path: &'a [(String, NodePublic)], filter: &'a NodeFilterSort) {
@@ -355,12 +360,13 @@ impl MediaInfoExt for MediaInfo {
match maxdim {
30720.. => "32K",
15360.. => "16K",
- 7680.. => "8K",
- 3840.. => "4K",
- 2560.. => "WQHD",
- 1920.. => "Full HD",
+ 7680.. => "8K UHD",
+ 5120.. => "5K UHD",
+ 3840.. => "4K UHD",
+ 2560.. => "QHD 1440p",
+ 1920.. => "FHD 1080p",
1280.. => "HD 720p",
- 640.. => "NTSC",
+ 854.. => "SD 480p",
_ => "Unkown",
}
}
diff --git a/web/style/nodecard.css b/web/style/nodecard.css
index ab25dd3..5a48f8f 100644
--- a/web/style/nodecard.css
+++ b/web/style/nodecard.css
@@ -30,13 +30,21 @@
object-position: center;
width: 100%;
}
-.card .title {
+.card .title, .card .subtitle {
text-align: center;
margin-top: 0.5em;
text-align: center;
text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
+.card .subtitle {
+ margin-top: 0.25em;
+}
+.card .subtitle a {
+ color: var(--font-dark);
}
-.card .title a {
+.card .title a, .card .subtitle a {
text-decoration-line: none;
}
.card .title a:hover {
diff --git a/web/style/themes.css b/web/style/themes.css
index 5f01207..f405815 100644
--- a/web/style/themes.css
+++ b/web/style/themes.css
@@ -29,8 +29,8 @@ body.theme-Dark {
--font-highlight: white;
}
body.theme-Light {
- --accent-light: rgb(255, 163, 87);
- --accent-dark: rgb(199, 90, 0);
+ --accent-light: #e46600;
+ --accent-dark: #ff9036;
--c-error: rgb(255, 117, 117);
--c-warn: rgb(252, 255, 78);
--c-success: rgb(117, 255, 117);
@@ -43,10 +43,10 @@ body.theme-Light {
--background-light: #c0c0c0;
--background-very-light: #b9b9b9;
--background-disable: rgb(128, 128, 128);
- --background-prop: rgba(0, 0, 0, 0.8);
- --font: rgb(43, 43, 43);
- --font-dark: rgb(0, 0, 0);
- --font-highlight: rgb(0, 0, 0);
+ --background-prop: #e9e9e9b2;
+ --font: #0f0f0f;
+ --font-dark: #606060;
+ --font-highlight: black;
}
body.theme-Purple {
--accent-light: rgb(191, 87, 255);