diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-01-25 23:32:53 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-01-25 23:32:53 +0100 |
| commit | 783d3598753bf84756296a2016e5dab30300519b (patch) | |
| tree | f7eaf276b65de8aab10db21d27e534f775d83167 /server/src/ui | |
| parent | 5075aede44cb8ab2df10e6debba38483e8d11e96 (diff) | |
| download | jellything-783d3598753bf84756296a2016e5dab30300519b.tar jellything-783d3598753bf84756296a2016e5dab30300519b.tar.bz2 jellything-783d3598753bf84756296a2016e5dab30300519b.tar.zst | |
work on login
Diffstat (limited to 'server/src/ui')
| -rw-r--r-- | server/src/ui/account/mod.rs | 22 | ||||
| -rw-r--r-- | server/src/ui/assets.rs | 77 | ||||
| -rw-r--r-- | server/src/ui/error.rs | 36 | ||||
| -rw-r--r-- | server/src/ui/mod.rs | 79 | ||||
| -rw-r--r-- | server/src/ui/node.rs | 44 | ||||
| -rw-r--r-- | server/src/ui/search.rs | 41 | ||||
| -rw-r--r-- | server/src/ui/stats.rs | 20 |
7 files changed, 125 insertions, 194 deletions
diff --git a/server/src/ui/account/mod.rs b/server/src/ui/account/mod.rs index 429b70a..ec8bd49 100644 --- a/server/src/ui/account/mod.rs +++ b/server/src/ui/account/mod.rs @@ -3,12 +3,17 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -pub mod settings; +// pub mod settings; use super::error::MyError; -use crate::ui::{error::MyResult, home::rocket_uri_macro_r_home}; +use crate::{ + request_info::RequestInfo, + ui::{error::MyResult, home::rocket_uri_macro_r_home}, +}; use anyhow::anyhow; +use jellycommon::{VIEW_ACCOUNT_LOGIN, jellyobject::Object}; use jellyimport::is_importing; +use jellyui::render_view; use rocket::{ FromForm, form::{Contextual, Form}, @@ -30,16 +35,9 @@ pub struct RegisterForm { } #[get("/account/register")] -pub async fn r_account_register(lang: AcceptLanguage) -> RawHtml<String> { - let AcceptLanguage(lang) = lang; - RawHtml(render_page( - &AccountRegister { lang: &lang }, - RenderInfo { - importing: false, - session: None, - lang, - }, - )) +pub async fn r_account_register(ri: RequestInfo<'_>) -> RawHtml<String> { + let ob = Object::EMPTY.insert(VIEW_ACCOUNT_LOGIN, ()); + RawHtml(render_view(ri.render_info(), ob.as_object())) } #[derive(FromForm, Serialize, Deserialize)] diff --git a/server/src/ui/assets.rs b/server/src/ui/assets.rs index 8f3fb4a..c956672 100644 --- a/server/src/ui/assets.rs +++ b/server/src/ui/assets.rs @@ -4,58 +4,57 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ use super::error::MyResult; -use anyhow::{Context, anyhow}; -use rocket::{get, http::ContentType, response::Redirect}; -use std::str::FromStr; +use crate::{request_info::RequestInfo, responders::cache::CacheControlImage}; +use anyhow::Context; +use rocket::{get, http::ContentType}; +use std::path::PathBuf; pub const AVIF_QUALITY: u32 = 70; pub const AVIF_SPEED: u8 = 5; -#[get("/image/<key..>?<size>")] +#[get("/image/<path..>?<size>")] pub async fn r_image( - _session: A<Session>, - key: A<Asset>, + ri: RequestInfo<'_>, + path: PathBuf, size: Option<usize>, ) -> MyResult<(ContentType, CacheControlImage)> { let size = size.unwrap_or(2048); - - if !key.0.0.ends_with(".image") { - Err(anyhow!("request to non-image"))? - } + let path = path.to_string_lossy().to_string(); // fit the resolution into a finite set so the maximum cache is finite too. let width = 2usize.pow(size.clamp(128, 2048).ilog2()); - let encoded = jellytranscoder::image::transcode(&key.0.0, AVIF_QUALITY, AVIF_SPEED, width) - .context("transcoding asset")?; + let encoded = + jellytranscoder::image::transcode(&ri.state.cache, &path, AVIF_QUALITY, AVIF_SPEED, width) + .context("transcoding asset")?; Ok((ContentType::AVIF, CacheControlImage(encoded))) } -#[get("/n/<id>/image/<slot>?<size>")] -pub async fn r_item_poster( - session: A<Session>, - id: A<NodeID>, - slot: &str, - size: Option<usize>, -) -> MyResult<Redirect> { - let slot = PictureSlot::from_str(slot).map_err(|_| anyhow!("slot invalid"))?; - let node = get_node(&session.0, id.0, false, false, NodeFilterSort::default())?; - let picture = node - .node - .pictures - .get(&slot) - .cloned() - .ok_or(anyhow!("no pic todo"))?; - Ok(Redirect::permanent(rocket::uri!(r_image(picture, size)))) -} +// #[get("/n/<id>/image/<slot>?<size>")] +// pub async fn r_item_poster( +// session: A<Session>, +// id: A<NodeID>, +// slot: &str, +// size: Option<usize>, +// ) -> MyResult<Redirect> { +// let slot = PictureSlot::from_str(slot).map_err(|_| anyhow!("slot invalid"))?; +// let node = get_node(&session.0, id.0, false, false, NodeFilterSort::default())?; +// let picture = node +// .node +// .pictures +// .get(&slot) +// .cloned() +// .ok_or(anyhow!("no pic todo"))?; +// Ok(Redirect::permanent(rocket::uri!(r_image(picture, size)))) +// } -#[get("/n/<id>/thumbnail?<t>&<size>")] -pub async fn r_node_thumbnail( - session: A<Session>, - id: A<NodeID>, - t: f64, - size: Option<usize>, -) -> MyResult<Redirect> { - let picture = get_node_thumbnail(&session.0, id.0, t).await?; - Ok(Redirect::permanent(rocket::uri!(r_image(picture, size)))) -} +// #[get("/n/<id>/thumbnail?<t>&<size>")] +// pub async fn r_node_thumbnail( +// session: A<Session>, +// id: A<NodeID>, +// t: f64, +// size: Option<usize>, +// ) -> MyResult<Redirect> { +// let picture = get_node_thumbnail(&session.0, id.0, t).await?; +// Ok(Redirect::permanent(rocket::uri!(r_image(picture, size)))) +// } diff --git a/server/src/ui/error.rs b/server/src/ui/error.rs index 0f279fc..578d841 100644 --- a/server/src/ui/error.rs +++ b/server/src/ui/error.rs @@ -3,38 +3,20 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -use log::info; use rocket::{ - catch, - http::{ContentType, Status}, - response::{self, content::RawHtml, Responder}, - Request, + Request, catch, + http::Status, + response::{self, Responder, content::RawHtml}, }; -use serde_json::{json, Value}; -use std::{fmt::Display, fs::File, io::Read, sync::LazyLock}; - -static ERROR_IMAGE: LazyLock<Vec<u8>> = LazyLock::new(|| { - info!("loading error image"); - let mut f = File::open(CONF.asset_path.join("error.avif")) - .expect("please create error.avif in the asset dir"); - let mut o = Vec::new(); - f.read_to_end(&mut o).unwrap(); - o -}); +use serde_json::{Value, json}; +use std::fmt::Display; #[catch(default)] pub fn r_catch(status: Status, _request: &Request) -> RawHtml<String> { catch_with_message(format!("{status}")) } fn catch_with_message(message: String) -> RawHtml<String> { - RawHtml(render_page( - &ErrorPage { status: message }, - RenderInfo { - importing: false, - session: None, - lang: Language::English, - }, - )) + RawHtml(message) // TODO } #[catch(default)] @@ -52,9 +34,9 @@ impl<'r> Responder<'r, 'static> for MyError { fn respond_to(self, req: &'r Request<'_>) -> response::Result<'static> { match req.accept().map(|a| a.preferred()) { Some(x) if x.is_json() => json!({ "error": format!("{}", self.0) }).respond_to(req), - Some(x) if x.is_avif() || x.is_png() || x.is_jpeg() => { - (ContentType::AVIF, ERROR_IMAGE.as_slice()).respond_to(req) - } + // Some(x) if x.is_avif() || x.is_png() || x.is_jpeg() => { + // (ContentType::AVIF, ERROR_IMAGE.as_slice()).respond_to(req) + // } _ => catch_with_message(format!("{:#}", self.0)).respond_to(req), } } diff --git a/server/src/ui/mod.rs b/server/src/ui/mod.rs index 92b93fe..55fad6a 100644 --- a/server/src/ui/mod.rs +++ b/server/src/ui/mod.rs @@ -4,58 +4,51 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ use error::MyResult; -use home::rocket_uri_macro_r_home; -use rocket::{ - Either, - futures::FutureExt, - get, - response::{Redirect, content::RawHtml}, -}; -use std::{future::Future, pin::Pin}; -use tokio::{ - fs::{File, read_to_string}, - io::AsyncRead, -}; +use rocket::{futures::FutureExt, get}; +use std::{future::Future, pin::Pin, sync::Arc}; +use tokio::{fs::File, io::AsyncRead}; + +use crate::State; pub mod account; -pub mod admin; +// pub mod admin; pub mod assets; pub mod error; -pub mod home; -pub mod items; +// pub mod home; +// pub mod items; pub mod node; -pub mod player; -pub mod search; -pub mod stats; +// pub mod player; +// pub mod search; +// pub mod stats; pub mod style; -#[get("/")] -pub async fn r_index( - lang: AcceptLanguage, - sess: Option<A<Session>>, -) -> MyResult<Either<Redirect, RawHtml<String>>> { - let AcceptLanguage(lang) = lang; - if sess.is_some() { - Ok(Either::Left(Redirect::temporary(rocket::uri!(r_home())))) - } else { - let front = read_to_string(CONF.asset_path.join("front.htm")).await?; - Ok(Either::Right(RawHtml(render_page( - &CustomPage { - title: "Jellything".to_string(), - body: front, - }, - RenderInfo { - importing: false, - session: None, - lang, - }, - )))) - } -} +// #[get("/")] +// pub async fn r_index( +// lang: AcceptLanguage, +// sess: Option<A<Session>>, +// ) -> MyResult<Either<Redirect, RawHtml<String>>> { +// let AcceptLanguage(lang) = lang; +// if sess.is_some() { +// Ok(Either::Left(Redirect::temporary(rocket::uri!(r_home())))) +// } else { +// let front = read_to_string(CONF.asset_path.join("front.htm")).await?; +// Ok(Either::Right(RawHtml(render_page( +// &CustomPage { +// title: "Jellything".to_string(), +// body: front, +// }, +// RenderInfo { +// importing: false, +// session: None, +// lang, +// }, +// )))) +// } +// } #[get("/favicon.ico")] -pub async fn r_favicon() -> MyResult<File> { - Ok(File::open(CONF.asset_path.join("favicon.ico")).await?) +pub async fn r_favicon(s: &rocket::State<Arc<State>>) -> MyResult<File> { + Ok(File::open(s.config.asset_path.join("favicon.ico")).await?) } pub struct Defer(Pin<Box<dyn Future<Output = String> + Send>>); diff --git a/server/src/ui/node.rs b/server/src/ui/node.rs index 85beac6..cf5c793 100644 --- a/server/src/ui/node.rs +++ b/server/src/ui/node.rs @@ -5,42 +5,12 @@ */ use super::error::MyResult; use crate::request_info::RequestInfo; -use rocket::{Either, get, response::content::RawHtml, serde::json::Json}; +use jellycommon::jellyobject::Object; +use jellyui::render_view; +use rocket::{get, response::content::RawHtml}; -#[get("/n/<id>?<parents>&<children>&<filter..>")] -pub async fn r_node( - ri: RequestInfo<'_>, - id: A<NodeID>, - filter: Option<ANodeFilterSort>, - parents: bool, - children: bool, -) -> MyResult<Either<RawHtml<String>, Json<ApiNodeResponse>>> { - let filter: Option<NodeFilterSort> = filter.map(Into::into); - let filter = filter.unwrap_or_default(); - - let r = get_node( - &ri.session, - id.0, - !ri.accept.is_json() || children, - !ri.accept.is_json() || parents, - filter.clone(), - )?; - - Ok(if ri.accept.is_json() { - Either::Right(Json(r)) - } else { - Either::Left(RawHtml(render_page( - &NodePage { - node: &r.node, - udata: &r.userdata, - children: &r.children, - parents: &r.parents, - similar: &[], - filter: &filter, - lang: &ri.lang, - player: false, - }, - ri.render_info(), - ))) - }) +#[get("/n/<slug>")] +pub fn r_node(ri: RequestInfo<'_>, slug: &str) -> MyResult<RawHtml<String>> { + ri.require_user()?; + Ok(RawHtml(render_view(ri.render_info(), Object::EMPTY))) } diff --git a/server/src/ui/search.rs b/server/src/ui/search.rs index fce79e3..8ec2697 100644 --- a/server/src/ui/search.rs +++ b/server/src/ui/search.rs @@ -10,27 +10,28 @@ use rocket::{Either, get, response::content::RawHtml, serde::json::Json}; #[get("/search?<query>&<page>")] pub async fn r_search( - ri: RequestInfo, + ri: RequestInfo<'_>, query: Option<&str>, page: Option<usize>, -) -> MyResult<Either<RawHtml<String>, Json<ApiSearchResponse>>> { - let r = query - .map(|query| search(&ri.session, query, page)) - .transpose()?; +) -> MyResult<RawHtml<String>> { + // let r = query + // .map(|query| search(&ri.session, query, page)) + // .transpose()?; - Ok(if ri.accept.is_json() { - let Some(r) = r else { - Err(anyhow!("no query"))? - }; - Either::Right(Json(r)) - } else { - Either::Left(RawHtml(render_page( - &SearchPage { - lang: &ri.lang, - query: &query.map(|s| s.to_string()), - r, - }, - ri.render_info(), - ))) - }) + // Ok(if ri.accept.is_json() { + // let Some(r) = r else { + // Err(anyhow!("no query"))? + // }; + // Either::Right(Json(r)) + // } else { + // Either::Left(RawHtml(render_page( + // &SearchPage { + // lang: &ri.lang, + // query: &query.map(|s| s.to_string()), + // r, + // }, + // ri.render_info(), + // ))) + // }) + todo!() } diff --git a/server/src/ui/stats.rs b/server/src/ui/stats.rs index fc4ae64..387ca63 100644 --- a/server/src/ui/stats.rs +++ b/server/src/ui/stats.rs @@ -3,22 +3,10 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin <metamuffin.org> */ -use super::error::MyError; -use crate::request_info::RequestInfo; -use rocket::{Either, get, response::content::RawHtml, serde::json::Json}; +use crate::{request_info::RequestInfo, ui::error::MyResult}; +use rocket::{get, response::content::RawHtml}; #[get("/stats")] -pub fn r_stats( - ri: RequestInfo, -) -> Result<Either<RawHtml<String>, Json<ApiStatsResponse>>, MyError> { - let r = stats(&ri.session)?; - - Ok(if ri.accept.is_json() { - Either::Right(Json(r)) - } else { - Either::Left(RawHtml(render_page( - &StatsPage { lang: &ri.lang, r }, - ri.render_info(), - ))) - }) +pub fn r_stats(ri: RequestInfo) -> MyResult<RawHtml<String>> { + todo!() } |