aboutsummaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/src/library.rs9
-rw-r--r--server/src/routes/stream.rs3
-rw-r--r--server/src/routes/ui/node.rs46
-rw-r--r--server/src/routes/ui/style/directorypage.css38
-rw-r--r--server/src/routes/ui/style/layout.css5
5 files changed, 66 insertions, 35 deletions
diff --git a/server/src/library.rs b/server/src/library.rs
index 2b5cf9b..e810c65 100644
--- a/server/src/library.rs
+++ b/server/src/library.rs
@@ -16,6 +16,7 @@ use std::{
pub struct Library {
pub root: Arc<Node>,
+ pub root_path: PathBuf,
}
#[derive(Debug, Clone)]
@@ -43,6 +44,7 @@ pub struct Item {
impl Library {
pub fn open(path: &Path) -> anyhow::Result<Self> {
Ok(Self {
+ root_path: path.to_path_buf(),
root: Node::from_path(path.to_path_buf(), PathBuf::new(), true)
.context("indexing root")?
.ok_or(anyhow!("root need directory.json"))?,
@@ -91,6 +93,13 @@ impl Node {
Node::Item(i) => &i.identifier,
}
}
+ pub fn banner(&self) -> &Option<PathBuf> {
+ match self {
+ Node::Directory(d) => &d.info.banner,
+ Node::Item(i) => &i.info.banner,
+ }
+ }
+
pub fn from_path(
path: PathBuf,
mut lib_path: PathBuf,
diff --git a/server/src/routes/stream.rs b/server/src/routes/stream.rs
index af81d64..b2b708b 100644
--- a/server/src/routes/stream.rs
+++ b/server/src/routes/stream.rs
@@ -74,11 +74,12 @@ pub fn r_stream(
None => 0..(isize::MAX as usize),
};
+ let path_base = library.root_path.clone();
tokio::task::spawn_blocking(move || {
if let Err(e) = remuxer.generate_into(
b,
urange,
- item.fs_path.parent().unwrap().to_path_buf(),
+ path_base,
item.info.clone(),
tracks,
webm.unwrap_or(false),
diff --git a/server/src/routes/ui/node.rs b/server/src/routes/ui/node.rs
index fc57eea..d03173b 100644
--- a/server/src/routes/ui/node.rs
+++ b/server/src/routes/ui/node.rs
@@ -5,16 +5,18 @@
*/
use super::error::MyError;
use super::player::player_uri;
+use crate::uri;
use crate::{
library::{Directory, Item, Library, Node},
routes::ui::{
account::session::Session,
layout::{DynLayoutPage, LayoutPage},
},
+ CONF,
};
-use anyhow::{anyhow, Context};
+use anyhow::Context;
use log::info;
-use rocket::{get, http::ContentType, uri, State};
+use rocket::{get, http::ContentType, State};
use std::{ops::Deref, path::PathBuf, sync::Arc};
use tokio::fs::File;
@@ -44,7 +46,20 @@ markup::define! {
}
}
DirectoryCard(dir: Arc<Directory>) {
- div.card.dir { a[href=&uri!(r_library_node(&dir.lib_path)).to_string()] { @dir.info.name } }
+ div.card.dir {
+ div.banner {
+ a[href=uri!(r_library_node(&dir.lib_path))] {
+ img[src=uri!(r_item_assets(&dir.lib_path))];
+ }
+ div.hover { a[href=uri!(r_library_node(&dir.lib_path))] { "Open" } }
+ }
+ p.title {
+ a[href=uri!(r_library_node(&dir.lib_path))] {
+ @dir.info.name
+ }
+ }
+ }
+ // a[href=&uri!(r_library_node(&dir.lib_path))] { @dir.info.name } }
}
DirectoryPage(dir: Arc<Directory>) {
div.page.dir {
@@ -62,13 +77,13 @@ markup::define! {
ItemCard(item: Arc<Item>) {
div.card.item {
div.banner {
- a[href=uri!(r_library_node(&item.lib_path)).to_string()] {
- img[src=uri!(r_item_assets(&item.lib_path)).to_string()];
+ a[href=uri!(r_library_node(&item.lib_path))] {
+ img[src=uri!(r_item_assets(&item.lib_path))];
}
div.hover { a[href=&player_uri(&item.lib_path)] { "▶" } }
}
p.title {
- a[href=uri!(r_library_node(&item.lib_path)).to_string()] {
+ a[href=uri!(r_library_node(&item.lib_path))] {
@item.info.title
}
}
@@ -76,10 +91,10 @@ markup::define! {
}
ItemPage(item: Arc<Item>) {
// TODO different image here
- img.backdrop[src=uri!(r_item_assets(&item.lib_path)).to_string()];
+ img.backdrop[src=uri!(r_item_assets(&item.lib_path))];
div.page.item {
div.banner {
- img[src=uri!(r_item_assets(&item.lib_path)).to_string()];
+ img[src=uri!(r_item_assets(&item.lib_path))];
}
div.title {
h1 { @item.info.title }
@@ -102,15 +117,12 @@ pub async fn r_item_assets(
) -> Result<(ContentType, File), MyError> {
let node = library
.nested_path(&path)
- .context("retrieving library node")?
- .get_item()?
- .clone();
- let path = node.fs_path.parent().unwrap().join(
- node.info
- .banner
- .clone()
- .ok_or(anyhow!("no banner available"))?,
- );
+ .context("retrieving library node")?;
+ let path = if let Some(p) = node.banner() {
+ library.root_path.join(p)
+ } else {
+ CONF.asset_path.join("fallback.jpeg")
+ };
info!("loading asset from {path:?}");
Ok((ContentType::WEBP, File::open(path).await?))
}
diff --git a/server/src/routes/ui/style/directorypage.css b/server/src/routes/ui/style/directorypage.css
index e46a1fe..0c04af7 100644
--- a/server/src/routes/ui/style/directorypage.css
+++ b/server/src/routes/ui/style/directorypage.css
@@ -18,34 +18,42 @@
display: block;
}
-.card.item {
- width: var(--card-size);
- height: calc(var(--card-size) * var(--banner-aspect));
+.card {
padding: 1em;
+ height: var(--card-size);
+}
+.card.item {
+ width: calc(var(--card-size) / var(--item-banner-aspect));
}
.card.dir {
- width: calc(var(--card-size) * 2);
- height: calc(var(--card-size) * var(--banner-aspect));
+ width: calc(var(--card-size) / var(--dir-banner-aspect));
}
-.card.item .title {
+.card .title {
margin-top: 0.1em;
text-align: center;
text-overflow: ellipsis;
}
-.card.item .banner {
+.card .banner {
display: grid;
}
-.card.item .banner a {
+.card .banner a {
grid-area: 1 / 1;
}
-.card.item .banner a img {
- width: 100%;
- height: 100%;
+
+.card.item .banner img {
+ width: calc(var(--card-size) / var(--item-banner-aspect));
+ height: var(--card-size);
+}
+.card.dir .banner img {
+ width: calc(var(--card-size) / var(--dir-banner-aspect));
+ height: var(--card-size);
+}
+.card .banner a img {
object-fit: cover;
object-position: center;
}
-.card.item .banner .hover {
+.card .banner .hover {
pointer-events: none;
grid-area: 1 / 1;
transition: opacity 0.3s, backdrop-filter 0.3s;
@@ -54,12 +62,12 @@
justify-content: center;
align-items: center;
}
-.card.item .banner:hover .hover {
+.card .banner:hover .hover {
opacity: 1;
background-color: #0004;
backdrop-filter: blur(3px);
}
-.card.item .banner .hover a {
+.card .banner .hover a {
text-decoration: none;
font-stretch: 200%;
width: 1em;
@@ -73,7 +81,7 @@
background-color: #0005;
transition: background-color 0.2s, font-size 0.2s;
}
-.card.item .banner .hover a:hover {
+.card .banner .hover a:hover {
background-color: #0008;
font-size: 2.4em;
}
diff --git a/server/src/routes/ui/style/layout.css b/server/src/routes/ui/style/layout.css
index 412d1ed..89c12e2 100644
--- a/server/src/routes/ui/style/layout.css
+++ b/server/src/routes/ui/style/layout.css
@@ -10,9 +10,10 @@
}
:root {
- --card-size: 12em;
+ --card-size: 17em;
--bar-height: 5em;
- --banner-aspect: 1.41;
+ --item-banner-aspect: 1.41;
+ --dir-banner-aspect: (1.41 / 2);
--accent-light: rgb(255, 163, 87);
--accent-dark: rgb(199, 90, 0);
--backdrop-height: 18em;