/* 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) 2023 metamuffin */ 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::Context; use log::info; use rocket::{get, http::ContentType, State}; use std::{ops::Deref, path::PathBuf, sync::Arc}; use tokio::fs::File; #[get("/library/")] pub async fn r_library_node( _sess: Session, path: PathBuf, library: &State, ) -> Result, MyError> { let node = library .nested_path(&path) .context("retrieving library node")?; Ok(LayoutPage { title: node.title().to_string(), content: markup::new! { @NodePage { node: node.clone() } }, ..Default::default() }) } markup::define! { NodePage(node: Arc) { @match node.deref() { Node::Directory(dir) => { @DirectoryPage { dir: dir.clone() } } Node::Item(item) => { @ItemPage { item: item.clone() } } } } DirectoryCard(dir: Arc) { 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) { div.page.dir { h1 { @dir.info.name } @if let Some(parent) = dir.lib_path.parent() { a.dirup[href=uri!(r_library_node(&parent))] { "Go up" } } ul.directorylisting { @for el in &dir.children { li { @match el.deref().to_owned() { Node::Directory(dir) => { @DirectoryCard { dir } } Node::Item(item) => { @ItemCard { item } } } } } } } } ItemCard(item: Arc) { div.card.item { div.banner { 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))] { @item.info.title } } } } ItemPage(item: Arc) { // TODO different image here img.backdrop[src=uri!(r_item_assets(&item.lib_path))]; div.page.item { div.banner { img[src=uri!(r_item_assets(&item.lib_path))]; } div.title { h1 { @item.info.title } // TODO release date, duration, ratings a.play[href=&player_uri(&item.lib_path)] { "Watch now" } } div.details { h3 { @item.info.description_head } p { @item.info.description } } } } } #[get("/item_assets/")] pub async fn r_item_assets( _sess: Session, path: PathBuf, library: &State, ) -> Result<(ContentType, File), MyError> { let node = library .nested_path(&path) .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?)) }