diff options
Diffstat (limited to 'server/src/frontend')
-rw-r--r-- | server/src/frontend/mod.rs | 2 | ||||
-rw-r--r-- | server/src/frontend/pages/home.rs | 14 | ||||
-rw-r--r-- | server/src/frontend/pages/layout.rs | 20 | ||||
-rw-r--r-- | server/src/frontend/pages/mod.rs | 69 | ||||
-rw-r--r-- | server/src/frontend/pages/node.rs | 60 | ||||
-rw-r--r-- | server/src/frontend/style/layout.css | 42 | ||||
-rw-r--r-- | server/src/frontend/style/mod.rs | 2 |
7 files changed, 209 insertions, 0 deletions
diff --git a/server/src/frontend/mod.rs b/server/src/frontend/mod.rs new file mode 100644 index 0000000..99c22f8 --- /dev/null +++ b/server/src/frontend/mod.rs @@ -0,0 +1,2 @@ +pub mod style; +pub mod pages; diff --git a/server/src/frontend/pages/home.rs b/server/src/frontend/pages/home.rs new file mode 100644 index 0000000..5076177 --- /dev/null +++ b/server/src/frontend/pages/home.rs @@ -0,0 +1,14 @@ +use crate::frontend::pages::node::NodePage; +use crate::{frontend::pages::HtmlTemplate, AppState}; +use rocket::{get, State}; + +#[get("/")] +pub async fn page_home(state: &State<AppState>) -> HtmlTemplate<markup::DynRender> { + HtmlTemplate( + "Home".to_string(), + markup::new! { + p { "Welcome to Jellything" } + @NodePage { node: state.library.root.clone() } + }, + ) +} diff --git a/server/src/frontend/pages/layout.rs b/server/src/frontend/pages/layout.rs new file mode 100644 index 0000000..5654d3b --- /dev/null +++ b/server/src/frontend/pages/layout.rs @@ -0,0 +1,20 @@ +use markup::Render; + +markup::define! { + Layout<Main: Render>(title: String, main: Main) { + @markup::doctype() + html { + head { + title { @title " - Jellything" } + link[rel="stylesheet", href="/assets/style.css"]; + } + body { + nav { + h1 { "Jellything" } + + } + #main { @main } + } + } + } +} diff --git a/server/src/frontend/pages/mod.rs b/server/src/frontend/pages/mod.rs new file mode 100644 index 0000000..a20fa0e --- /dev/null +++ b/server/src/frontend/pages/mod.rs @@ -0,0 +1,69 @@ +use markup::Render; +use rocket::{ + http::ContentType, + response::{self, Responder}, + Request, Response, +}; +use std::{fmt::Display, io::Cursor}; + +use self::layout::Layout; + +pub mod home; +pub mod layout; +pub mod node; + +pub struct HtmlTemplate<T>(pub String, pub T); + +impl<'r, T: Render> Responder<'r, 'static> for HtmlTemplate<T> { + fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { + let mut out = String::new(); + Layout { + title: self.0, + main: self.1, + } + .render(&mut out) + .unwrap(); + Response::build() + .header(ContentType::HTML) + .streamed_body(Cursor::new(out)) + .ok() + } +} + +#[derive(Debug)] +pub struct MyError(anyhow::Error); + +impl<'r> Responder<'r, 'static> for MyError { + fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { + let mut out = String::new(); + Layout { + title: "Error".to_string(), + main: markup::new! { + h2 { "An error occured. Nobody is sorry"} + pre.error { @format!("{:?}", self.0) } + }, + } + .render(&mut out) + .unwrap(); + Response::build() + .header(ContentType::HTML) + .streamed_body(Cursor::new(out)) + .ok() + } +} + +impl Display for MyError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} +impl From<anyhow::Error> for MyError { + fn from(err: anyhow::Error) -> MyError { + MyError(err) + } +} +impl From<std::fmt::Error> for MyError { + fn from(err: std::fmt::Error) -> MyError { + MyError(anyhow::anyhow!("{err}")) + } +} diff --git a/server/src/frontend/pages/node.rs b/server/src/frontend/pages/node.rs new file mode 100644 index 0000000..7ac4332 --- /dev/null +++ b/server/src/frontend/pages/node.rs @@ -0,0 +1,60 @@ +use crate::{ + frontend::pages::HtmlTemplate, + library::{Directory, Item, Node}, + AppState, +}; +use anyhow::Context; +use rocket::{get, uri, State}; +use std::{ops::Deref, path::PathBuf, sync::Arc}; + +use super::MyError; + +#[get("/library/<path..>")] +pub async fn page_library_node( + path: PathBuf, + state: &State<AppState>, +) -> Result<HtmlTemplate<markup::DynRender>, MyError> { + let path = path.to_str().unwrap().to_string(); + let node = state + .library + .nested(&path) + .context("retrieving library node")? + .clone(); + Ok(HtmlTemplate( + format!("{}", node.title()), + markup::new! { + @NodePage { node: node.clone() } + }, + )) +} + +markup::define! { + NodePage(node: Arc<Node>) { + @match node.deref() { + Node::Directory(dir) => { @DirectoryPage { dir: dir.clone() } } + Node::Item(item) => { @ItemPage { item: item.clone() } } + } + } + DirectoryCard(dir: Arc<Directory>) { + span { a[href=&uri!(page_library_node(&dir.lib_path)).to_string()] { @dir.data.name } } + } + DirectoryPage(dir: Arc<Directory>) { + h1 { @dir.data.name } + ul.directorylisting { + @for el in &dir.children { + li { + span.title { @match el.deref().to_owned() { + Node::Directory(dir) => { @DirectoryCard { dir } } + Node::Item(item) => { @ItemCard { item } } + }} + } + } + } + } + ItemCard(item: Arc<Item>) { + span { a[href=&uri!(page_library_node(&item.lib_path)).to_string()] { @item.data.title } } + } + ItemPage(item: Arc<Item>) { + h1 { @item.data.title } + } +} diff --git a/server/src/frontend/style/layout.css b/server/src/frontend/style/layout.css new file mode 100644 index 0000000..4418903 --- /dev/null +++ b/server/src/frontend/style/layout.css @@ -0,0 +1,42 @@ +@import url("https://s.metamuffin.org/static/font-ubuntu/include.css"); + +* { + color: white; + font-family: "Ubuntu", sans-serif; + font-weight: 300; + margin: 0px; + padding: 0px; +} + +body { + background-color: #1a1a1a; + width: 100vw; +} + +nav { + position: absolute; + top: 0px; + left: 0px; + padding: 1em; + width: calc(100vw - 2em); + height: 2em; + background-color: #41414144; +} + +nav h1 { + margin: 0px; + font-size: 1.5em; +} + +#main { + margin-top: 5em; + padding: 1em; + padding-left: 3em; + padding-right: 3em; +} + +.error { + padding: 1em; + color: rgb(255, 117, 117); + font-family: monospace; +} diff --git a/server/src/frontend/style/mod.rs b/server/src/frontend/style/mod.rs new file mode 100644 index 0000000..9d0729e --- /dev/null +++ b/server/src/frontend/style/mod.rs @@ -0,0 +1,2 @@ + +pub const CSS_BUNDLE: &'static str = include_str!("layout.css"); |