diff options
Diffstat (limited to 'server')
| -rw-r--r-- | server/src/main.rs | 2 | ||||
| -rw-r--r-- | server/src/request_info.rs | 7 | ||||
| -rw-r--r-- | server/src/ui/account/mod.rs | 37 | ||||
| -rw-r--r-- | server/src/ui/account/settings.rs | 17 | ||||
| -rw-r--r-- | server/src/ui/admin/import.rs | 28 | ||||
| -rw-r--r-- | server/src/ui/admin/log.rs | 19 | ||||
| -rw-r--r-- | server/src/ui/admin/mod.rs | 37 | ||||
| -rw-r--r-- | server/src/ui/admin/users.rs | 46 | ||||
| -rw-r--r-- | server/src/ui/home.rs | 97 | ||||
| -rw-r--r-- | server/src/ui/items.rs | 45 | ||||
| -rw-r--r-- | server/src/ui/player.rs | 90 | ||||
| -rw-r--r-- | server/src/ui_responder.rs | 56 |
12 files changed, 159 insertions, 322 deletions
diff --git a/server/src/main.rs b/server/src/main.rs index f3eabcf..8209879 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -32,7 +32,6 @@ pub mod request_info; pub mod responders; pub mod routes; pub mod ui; -pub mod ui_responder; #[rocket::main] async fn main() { @@ -84,7 +83,6 @@ pub fn create_state() -> Result<Arc<State>> { let cache_storage = jellykv::rocksdb::new(&config.cache_path)?; let db_storage = jellykv::rocksdb::new(&config.database_path)?; - // let db_storage = jellykv::memory::new(); let state = Arc::new(State { cache: Cache::new(Box::new(cache_storage), config.max_memory_cache_size).into(), diff --git a/server/src/request_info.rs b/server/src/request_info.rs index 4a0a781..442c7fb 100644 --- a/server/src/request_info.rs +++ b/server/src/request_info.rs @@ -14,11 +14,12 @@ use jellycommon::{ USER_ADMIN, jellyobject::{Object, ObjectBuffer}, }; -use jellyui::RenderInfo; +use jellyui::{Page, RenderInfo, Scaffold}; use rocket::{ Request, async_trait, http::{MediaType, Status}, request::{FlashMessage, FromRequest, Outcome}, + response::content::RawHtml, }; use std::sync::Arc; @@ -77,8 +78,12 @@ impl<'a> RequestInfo<'a> { status_message: None, user: self.user.as_ref().map(|u| u.as_object()), config: &self.state.config.ui, + message: self.flash.as_ref().map(|f| (f.kind(), f.message())), } } + pub fn respond_ui(&self, page: &dyn Page) -> RawHtml<String> { + RawHtml(Scaffold { page }.to_string()) + } } #[derive(Debug, Default)] diff --git a/server/src/ui/account/mod.rs b/server/src/ui/account/mod.rs index ab5093d..b106fc7 100644 --- a/server/src/ui/account/mod.rs +++ b/server/src/ui/account/mod.rs @@ -12,33 +12,37 @@ use crate::{ auth::{hash_password, login}, request_info::RequestInfo, ui::error::MyResult, - ui_responder::UiResponse, }; use anyhow::anyhow; use jellycommon::{ - jellyobject::{OBB, Path}, + jellyobject::Path, routes::{u_account_login, u_home}, *, }; use jellydb::{Filter, Query}; +use jellyui::components::login::{AccountLogin, AccountLogout, AccountSetPassword}; use rocket::{ Either, FromForm, form::{Contextual, Form}, get, http::{Cookie, CookieJar}, post, - response::{Flash, Redirect}, + response::{Flash, Redirect, content::RawHtml}, }; use serde::{Deserialize, Serialize}; #[get("/account/login")] -pub async fn r_account_login(ri: RequestInfo<'_>) -> UiResponse { - ri.respond_ui(OBB::new().with(VIEW_ACCOUNT_LOGIN, ())) +pub async fn r_account_login(ri: RequestInfo<'_>) -> RawHtml<String> { + ri.respond_ui(&AccountLogin { + ri: &ri.render_info(), + }) } #[get("/account/logout")] -pub fn r_account_logout(ri: RequestInfo<'_>) -> UiResponse { - ri.respond_ui(OBB::new().with(VIEW_ACCOUNT_LOGOUT, ())) +pub fn r_account_logout(ri: RequestInfo<'_>) -> RawHtml<String> { + ri.respond_ui(&AccountLogout { + ri: &ri.render_info(), + }) } #[derive(FromForm, Serialize, Deserialize)] @@ -60,7 +64,7 @@ pub fn r_account_login_post( ri: RequestInfo<'_>, jar: &CookieJar, form: Form<Contextual<LoginForm>>, -) -> MyResult<Either<Redirect, UiResponse>> { +) -> MyResult<Either<Redirect, RawHtml<String>>> { let form = match &form.value { Some(v) => v, None => return Err(MyError(anyhow!(format_form_error(form)))), @@ -88,18 +92,11 @@ pub fn r_account_login_post( Ok(()) })?; } else { - return Ok(Either::Right( - ri.respond_ui( - OBB::new().with( - VIEW_ACCOUNT_SET_PASSWORD, - OBB::new() - .with(SETPW_USERNAME, &form.username) - .with(SETPW_PASSWORD, &form.password) - .finish() - .as_object(), - ), - ), - )); + return Ok(Either::Right(ri.respond_ui(&AccountSetPassword { + ri: &ri.render_info(), + password: &form.password, + username: &form.username, + }))); } } diff --git a/server/src/ui/account/settings.rs b/server/src/ui/account/settings.rs index c1068f6..9a98c09 100644 --- a/server/src/ui/account/settings.rs +++ b/server/src/ui/account/settings.rs @@ -4,22 +4,20 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ use super::format_form_error; -use crate::{ - auth::hash_password, request_info::RequestInfo, ui::error::MyResult, ui_responder::UiResponse, -}; +use crate::{auth::hash_password, request_info::RequestInfo, ui::error::MyResult}; use anyhow::anyhow; use jellycommon::{ - jellyobject::{OBB, Object, ObjectBuffer, Path, Tag}, + jellyobject::{Object, ObjectBuffer, Path, Tag}, routes::u_account_settings, *, }; use jellydb::{Filter, Query}; -use jellyui::tr; +use jellyui::{components::user::UserSettings, tr}; use rocket::{ FromForm, form::{self, Contextual, Form, validate::len}, get, post, - response::{Flash, Redirect}, + response::{Flash, Redirect, content::RawHtml}, }; use std::ops::Range; @@ -38,9 +36,12 @@ fn option_len<'v>(value: &Option<String>, range: Range<usize>) -> form::Result<' } #[get("/account/settings")] -pub fn r_account_settings(ri: RequestInfo) -> MyResult<UiResponse> { +pub fn r_account_settings(ri: RequestInfo) -> MyResult<RawHtml<String>> { let user = ri.require_user()?; - Ok(ri.respond_ui(OBB::new().with(VIEW_USER_SETTINGS, user))) + Ok(ri.respond_ui(&UserSettings { + ri: &ri.render_info(), + user, + })) } #[post("/account/settings", data = "<form>")] diff --git a/server/src/ui/admin/import.rs b/server/src/ui/admin/import.rs index 78db4a4..e199de4 100644 --- a/server/src/ui/admin/import.rs +++ b/server/src/ui/admin/import.rs @@ -4,27 +4,23 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{request_info::RequestInfo, ui::error::MyResult, ui_responder::UiResponse}; -use jellycommon::{ - jellyobject::{OBB, ObjectBuffer}, - routes::u_admin_import, - *, -}; +use crate::{request_info::RequestInfo, ui::error::MyResult}; +use jellycommon::routes::u_admin_import; use jellyimport::{ ImportConfig, import_wrap, is_importing, reporting::{IMPORT_ERRORS, IMPORT_PROGRESS}, }; -use jellyui::tr; +use jellyui::{components::admin::AdminImport, tr}; use rocket::{ get, post, - response::{Flash, Redirect}, + response::{Flash, Redirect, content::RawHtml}, }; use rocket_ws::{Message, Stream, WebSocket}; use std::time::Duration; use tokio::{spawn, time::sleep}; #[get("/admin/import", rank = 2)] -pub async fn r_admin_import(ri: RequestInfo<'_>) -> MyResult<UiResponse> { +pub async fn r_admin_import(ri: RequestInfo<'_>) -> MyResult<RawHtml<String>> { ri.require_admin()?; let last_import_err = IMPORT_ERRORS.read().await.clone(); @@ -33,15 +29,11 @@ pub async fn r_admin_import(ri: RequestInfo<'_>) -> MyResult<UiResponse> { .map(|e| e.as_str()) .collect::<Vec<_>>(); - let mut data = ObjectBuffer::empty(); - if is_importing() { - data = data.as_object().insert(ADMIN_IMPORT_BUSY, ()); - } - data = data - .as_object() - .insert_multi(ADMIN_IMPORT_ERROR, &last_import_err); - - Ok(ri.respond_ui(OBB::new().with(VIEW_ADMIN_IMPORT, data.as_object()))) + Ok(ri.respond_ui(&AdminImport { + busy: is_importing(), + errors: &last_import_err, + ri: &ri.render_info(), + })) } #[post("/admin/import?<incremental>")] diff --git a/server/src/ui/admin/log.rs b/server/src/ui/admin/log.rs index 0965a25..168ec6a 100644 --- a/server/src/ui/admin/log.rs +++ b/server/src/ui/admin/log.rs @@ -8,7 +8,7 @@ use crate::{ request_info::RequestInfo, ui::error::MyResult, }; -use jellyui::{Scaffold, ServerLogPage, render_log_line}; +use jellyui::components::admin_log::{ServerLogPage, render_log_line}; use rocket::{get, response::content::RawHtml}; use rocket_ws::{Message, Stream, WebSocket}; use serde_json::json; @@ -21,18 +21,11 @@ pub fn r_admin_log(ri: RequestInfo, warnonly: bool) -> MyResult<RawHtml<String>> .map(|l| render_log_line(&l)) .collect::<Vec<_>>(); - Ok(RawHtml( - Scaffold { - class: "theme-purple", - main: ServerLogPage { - messages: &messages, - warnonly, - }, - ri: &ri.render_info(), - title: "Admin Log", - } - .to_string(), - )) + Ok(ri.respond_ui(&ServerLogPage { + ri: &ri.render_info(), + messages: &messages, + warnonly, + })) } #[get("/admin/log?stream&<warnonly>&<html>", rank = 1)] diff --git a/server/src/ui/admin/mod.rs b/server/src/ui/admin/mod.rs index 10037b5..6119b74 100644 --- a/server/src/ui/admin/mod.rs +++ b/server/src/ui/admin/mod.rs @@ -9,34 +9,21 @@ pub mod log; pub mod users; use super::error::MyResult; -use crate::{request_info::RequestInfo, ui_responder::UiResponse}; -use jellycommon::{ - jellyobject::{OBB, ObjectBuffer}, - *, -}; -use jellyui::tr; -use rocket::get; +use crate::request_info::RequestInfo; +use jellyui::components::admin::AdminDashboard; +use rocket::{get, response::content::RawHtml}; #[get("/admin/dashboard")] -pub async fn r_admin_dashboard(ri: RequestInfo<'_>) -> MyResult<UiResponse> { +pub async fn r_admin_dashboard(ri: RequestInfo<'_>) -> MyResult<RawHtml<String>> { ri.require_admin()?; - let mut db_debug = String::new(); - ri.state.database.transaction(&mut |txn| { - db_debug = txn.debug_info()?; - Ok(()) - })?; + // let mut db_debug = String::new(); + // ri.state.database.transaction(&mut |txn| { + // db_debug = txn.debug_info()?; + // Ok(()) + // })?; - let mut page = OBB::new(); - page.push(VIEW_TITLE, &*tr(ri.lang, "admin.dashboard.title")); - page.push(VIEW_ADMIN_DASHBOARD, ()); - page.push( - VIEW_ADMIN_INFO, - ObjectBuffer::new(&mut [ - (ADMIN_INFO_TITLE.0, &"Database Debug"), - (ADMIN_INFO_TEXT.0, &db_debug.as_str()), - ]) - .as_object(), - ); - Ok(ri.respond_ui(page)) + Ok(ri.respond_ui(&AdminDashboard { + ri: &ri.render_info(), + })) } diff --git a/server/src/ui/admin/users.rs b/server/src/ui/admin/users.rs index 172facc..85f241b 100644 --- a/server/src/ui/admin/users.rs +++ b/server/src/ui/admin/users.rs @@ -6,28 +6,29 @@ use std::str::FromStr; +use crate::{auth::hash_password, request_info::RequestInfo, ui::error::MyResult}; +use anyhow::anyhow; use base64::{Engine, prelude::BASE64_URL_SAFE}; use jellycommon::{ - jellyobject::{OBB, ObjectBufferBuilder, Path}, + jellyobject::{ObjectBufferBuilder, Path}, routes::u_admin_users, *, }; use jellydb::{Filter, Query}; -use jellyui::tr; +use jellyui::{ + components::admin::{AdminUser, AdminUserList}, + tr, +}; use rand::random; use rocket::{ FromForm, form::Form, get, post, - response::{Flash, Redirect}, -}; - -use crate::{ - auth::hash_password, request_info::RequestInfo, ui::error::MyResult, ui_responder::UiResponse, + response::{Flash, Redirect, content::RawHtml}, }; #[get("/admin/users")] -pub fn r_admin_users(ri: RequestInfo) -> MyResult<UiResponse> { +pub fn r_admin_users(ri: RequestInfo) -> MyResult<RawHtml<String>> { ri.require_admin()?; let mut users = Vec::new(); @@ -43,15 +44,10 @@ pub fn r_admin_users(ri: RequestInfo) -> MyResult<UiResponse> { Ok(()) })?; - let mut list = ObjectBufferBuilder::default(); - for u in users { - list.push(ADMIN_USER_LIST_ITEM, u.as_object()); - } - - let mut page = ObjectBufferBuilder::default(); - page.push(VIEW_TITLE, &*tr(ri.lang, "admin.users")); - page.push(VIEW_ADMIN_USER_LIST, list.finish().as_object()); - Ok(ri.respond_ui(page)) + Ok(ri.respond_ui(&AdminUserList { + ri: &ri.render_info(), + users: &users.iter().map(|u| u.as_object()).collect::<Vec<_>>(), + })) } #[derive(FromForm)] @@ -83,22 +79,26 @@ pub fn r_admin_new_user(ri: RequestInfo, form: Form<NewUser>) -> MyResult<Flash< } #[get("/admin/user/<name>")] -pub fn r_admin_user(ri: RequestInfo<'_>, name: &str) -> MyResult<UiResponse> { +pub fn r_admin_user(ri: RequestInfo<'_>, name: &str) -> MyResult<RawHtml<String>> { ri.require_admin()?; - let mut page = OBB::new(); + let mut user = None; ri.state.database.transaction(&mut |txn| { if let Some(row) = txn.query_single(Query { filter: Filter::Match(Path(vec![USER_LOGIN.0]), name.into()), ..Default::default() })? { - let user = txn.get(row)?.unwrap(); - page = OBB::new(); - page.push(VIEW_ADMIN_USER, user.as_object()); + user = Some(txn.get(row)?.unwrap()); } Ok(()) })?; + let Some(user) = user else { + Err(anyhow!("no such user"))? + }; - Ok(ri.respond_ui(page)) + Ok(ri.respond_ui(&AdminUser { + ri: &ri.render_info(), + user: user.as_object(), + })) } #[post("/admin/user/<name>/remove")] diff --git a/server/src/ui/home.rs b/server/src/ui/home.rs index 1a7da36..6cb6a77 100644 --- a/server/src/ui/home.rs +++ b/server/src/ui/home.rs @@ -4,77 +4,50 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use std::str::FromStr; - use super::error::MyResult; -use crate::{request_info::RequestInfo, ui_responder::UiResponse}; +use crate::request_info::RequestInfo; use anyhow::{Context, Result}; -use jellycommon::{ - jellyobject::{Object, ObjectBuffer, ObjectBufferBuilder}, - *, -}; +use jellycommon::jellyobject::{Object, ObjectBuffer}; use jellydb::Query; -use jellyui::tr; -use rocket::get; +use jellyui::components::home::HomeRow; +use rocket::{get, response::content::RawHtml}; +use std::str::FromStr; #[get("/home")] -pub fn r_home(ri: RequestInfo<'_>) -> MyResult<UiResponse> { +pub fn r_home(ri: RequestInfo<'_>) -> MyResult<RawHtml<String>> { ri.require_user()?; - let mut page = ObjectBufferBuilder::default(); - - page.push(VIEW_TITLE, &&*tr(ri.lang, "home")); - - page.push( - VIEW_NODE_LIST, - home_row( - &ri, - "home.bin.latest_video", - "FILTER (visi = visi AND kind = vide) SORT DESCENDING BY FIRST rldt", - )? - .as_object(), - ); - page.push( - VIEW_NODE_LIST, - home_row( - &ri, - "home.bin.latest_music", - "FILTER (visi = visi AND kind = musi) SORT DESCENDING BY FIRST rldt", - )? - .as_object(), - ); - page.push( - VIEW_NODE_LIST, - home_row_highlight( - &ri, - "home.bin.daily_random", - "FILTER (visi = visi AND kind = movi) SORT RANDOM", - )? - .as_object(), - ); - page.push( - VIEW_NODE_LIST, - home_row( - &ri, - "home.bin.max_rating", - "SORT DESCENDING BY FIRST rtng.imdb", - )? - .as_object(), - ); - page.push( - VIEW_NODE_LIST, - home_row_highlight( - &ri, - "home.bin.daily_random", - "FILTER (visi = visi AND kind = show) SORT RANDOM", - )? - .as_object(), - ); + let mut rows = Vec::new(); + rows.push(home_row( + &ri, + "home.bin.latest_video", + "FILTER (visi = visi AND kind = vide) SORT DESCENDING BY FIRST rldt", + )?); + rows.push(home_row( + &ri, + "home.bin.latest_music", + "FILTER (visi = visi AND kind = musi) SORT DESCENDING BY FIRST rldt", + )?); + rows.push(home_row_highlight( + &ri, + "home.bin.daily_random", + "FILTER (visi = visi AND kind = movi) SORT RANDOM", + )?); + rows.push(home_row( + &ri, + "home.bin.max_rating", + "SORT DESCENDING BY FIRST rtng.imdb", + )?); + rows.push(home_row_highlight( + &ri, + "home.bin.daily_random", + "FILTER (visi = visi AND kind = show) SORT RANDOM", + )?); - Ok(ri.respond_ui(page)) + Ok(ri.respond_ui(rows)) } -fn home_row(ri: &RequestInfo<'_>, title: &str, query: &str) -> Result<ObjectBuffer> { +fn home_row(ri: &RequestInfo<'_>, title: &str, query: &str) -> Result<HomeRow> { let q = Query::from_str(query).context("parse query")?; let mut res = ObjectBuffer::empty(); ri.state.database.transaction(&mut |txn| { @@ -96,7 +69,7 @@ fn home_row(ri: &RequestInfo<'_>, title: &str, query: &str) -> Result<ObjectBuff Ok(res) } -fn home_row_highlight(ri: &RequestInfo<'_>, title: &str, query: &str) -> Result<ObjectBuffer> { +fn home_row_highlight(ri: &RequestInfo<'_>, title: &str, query: &str) -> Result<HomeRow> { let q = Query::from_str(query).context("parse query")?; let mut res = ObjectBuffer::empty(); ri.state.database.transaction(&mut |txn| { diff --git a/server/src/ui/items.rs b/server/src/ui/items.rs index 286fc01..b800914 100644 --- a/server/src/ui/items.rs +++ b/server/src/ui/items.rs @@ -4,49 +4,56 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{request_info::RequestInfo, ui::error::MyResult, ui_responder::UiResponse}; +use crate::{request_info::RequestInfo, ui::error::MyResult}; use anyhow::anyhow; use base64::{Engine, prelude::BASE64_URL_SAFE}; use jellycommon::{ - jellyobject::{OBB, Path}, + jellyobject::{Object, Path}, *, }; use jellydb::{Filter, Query}; -use rocket::get; +use jellyui::components::items::Items; +use rocket::{get, response::content::RawHtml}; #[get("/items?<cont>")] -pub fn r_items(ri: RequestInfo, cont: Option<&str>) -> MyResult<UiResponse> { - let cont = cont +pub fn r_items(ri: RequestInfo, cont: Option<&str>) -> MyResult<RawHtml<String>> { + let cont_in = cont .map(|s| BASE64_URL_SAFE.decode(s)) .transpose() .map_err(|_| anyhow!("invalid contination token"))?; - let mut page = OBB::new(); + let mut items = Vec::new(); + let mut cont_out = None; ri.state.database.transaction(&mut |txn| { let rows = txn .query(Query { filter: Filter::Match(Path(vec![NO_KIND.0]), KIND_CHANNEL.into()), - continuation: cont.clone(), + continuation: cont_in.clone(), ..Default::default() })? .take(64) .collect::<Result<Vec<_>, _>>()?; - let mut list = OBB::new().with(NODELIST_DISPLAYSTYLE, NLSTYLE_GRID); - - let mut iterstate = Vec::new(); + items.clear(); + cont_out = None; for (r, is) in rows { let node = txn.get(r)?.unwrap(); - let nku = OBB::new().with(NKU_NODE, node.as_object()).finish(); - list.push(NODELIST_ITEM, nku.as_object()); - iterstate = is; + items.push(node); + cont_out = Some(is) } - list.push(NODELIST_CONTINUATION, &BASE64_URL_SAFE.encode(iterstate)); - - page = OBB::new(); - page.push(VIEW_NODE_LIST, list.finish().as_object()); - Ok(()) })?; - Ok(ri.respond_ui(page)) + + Ok(ri.respond_ui(&Items { + ri: &ri.render_info(), + items: &items + .iter() + .map(|node| Nku { + node: node.as_object(), + userdata: Object::EMPTY, + role: None, + }) + .collect::<Vec<_>>(), + cont: cont_out.map(|x| BASE64_URL_SAFE.encode(x)), + })) } diff --git a/server/src/ui/player.rs b/server/src/ui/player.rs index f0d6dea..1050abb 100644 --- a/server/src/ui/player.rs +++ b/server/src/ui/player.rs @@ -4,13 +4,14 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ use super::error::MyResult; -use crate::{request_info::RequestInfo, ui_responder::UiResponse}; +use crate::request_info::RequestInfo; use jellycommon::{ - jellyobject::{OBB, Object, Path}, + jellyobject::{Object, ObjectBuffer, Path}, *, }; use jellydb::{Filter, Query}; -use rocket::get; +use jellyui::components::node_page::Player; +use rocket::{get, response::content::RawHtml}; // fn jellynative_url(action: &str, seek: f64, secret: &str, node: &str, session: &str) -> String { // let protocol = if CONF.tls { "https" } else { "http" }; @@ -26,88 +27,27 @@ use rocket::get; // } #[get("/n/<slug>/player?<t>", rank = 4)] -pub fn r_player(ri: RequestInfo<'_>, t: Option<f64>, slug: &str) -> MyResult<UiResponse> { +pub fn r_player(ri: RequestInfo<'_>, t: Option<f64>, slug: &str) -> MyResult<RawHtml<String>> { ri.require_user()?; let _ = t; - let mut page = OBB::new(); + let mut node = ObjectBuffer::empty(); ri.state.database.transaction(&mut |txn| { if let Some(row) = txn.query_single(Query { filter: Filter::Match(Path(vec![NO_SLUG.0]), slug.into()), ..Default::default() })? { - let n = txn.get(row)?.unwrap(); - let nku = Object::EMPTY.insert(NKU_NODE, n.as_object()); - - page = OBB::new(); - let title = nku - .as_object() - .get(NKU_NODE) - .unwrap_or_default() - .get(NO_TITLE) - .unwrap_or_default(); - page.push(VIEW_TITLE, title); - page.push(VIEW_PLAYER, nku.as_object()); + node = txn.get(row)?.unwrap(); } Ok(()) })?; - Ok(ri.respond_ui(page)) + Ok(ri.respond_ui(&Player { + ri: &ri.render_info(), + nku: Nku { + node: node.as_object(), + userdata: Object::EMPTY, + role: None, + }, + })) } - -// pub fn player_conf<'a>(item: Arc<Node>, playing: bool) -> anyhow::Result<DynRender<'a>> { -// let mut audio_tracks = vec![]; -// let mut video_tracks = vec![]; -// let mut sub_tracks = vec![]; -// let tracks = item -// .media -// .clone() -// .ok_or(anyhow!("node does not have media"))? -// .tracks -// .clone(); -// for (tid, track) in tracks.into_iter().enumerate() { -// match &track.kind { -// SourceTrackKind::Audio { .. } => audio_tracks.push((tid, track)), -// SourceTrackKind::Video { .. } => video_tracks.push((tid, track)), -// SourceTrackKind::Subtitles => sub_tracks.push((tid, track)), -// } -// } - -// Ok(markup::new! { -// form.playerconf[method = "GET", action = ""] { -// h2 { "Select tracks for " @item.title } - -// fieldset.video { -// legend { "Video" } -// @for (i, (tid, track)) in video_tracks.iter().enumerate() { -// input[type="radio", id=tid, name="v", value=tid, checked=i==0]; -// label[for=tid] { @format!("{track}") } br; -// } -// input[type="radio", id="v-none", name="v", value=""]; -// label[for="v-none"] { "No video" } -// } - -// fieldset.audio { -// legend { "Audio" } -// @for (i, (tid, track)) in audio_tracks.iter().enumerate() { -// input[type="radio", id=tid, name="a", value=tid, checked=i==0]; -// label[for=tid] { @format!("{track}") } br; -// } -// input[type="radio", id="a-none", name="a", value=""]; -// label[for="a-none"] { "No audio" } -// } - -// fieldset.subtitles { -// legend { "Subtitles" } -// @for (_i, (tid, track)) in sub_tracks.iter().enumerate() { -// input[type="radio", id=tid, name="s", value=tid]; -// label[for=tid] { @format!("{track}") } br; -// } -// input[type="radio", id="s-none", name="s", value="", checked=true]; -// label[for="s-none"] { "No subtitles" } -// } - -// input[type="submit", value=if playing { "Change tracks" } else { "Start playback" }]; -// } -// }) -// } diff --git a/server/src/ui_responder.rs b/server/src/ui_responder.rs deleted file mode 100644 index 2c4adea..0000000 --- a/server/src/ui_responder.rs +++ /dev/null @@ -1,56 +0,0 @@ -/* - 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) 2026 metamuffin <metamuffin.org> -*/ - -use crate::request_info::RequestInfo; -use jellycommon::{ - jellyobject::{ObjectBuffer, ObjectBufferBuilder, json::object_to_json}, - *, -}; -use jellyui::render_view; -use rocket::response::{ - Responder, - content::{RawHtml, RawJson}, -}; - -pub enum UiResponse { - Html(String), - Json(String), - Object(ObjectBuffer), -} - -impl RequestInfo<'_> { - pub fn respond_ui(&self, mut view: ObjectBufferBuilder) -> UiResponse { - if let Some(flash) = &self.flash { - view.push( - VIEW_MESSAGE, - ObjectBuffer::new(&mut [ - (MESSAGE_KIND.0, &flash.kind()), - (MESSAGE_TEXT.0, &flash.message()), - ]) - .as_object(), - ); - } - let view = view.finish(); - if self.accept.is_json() || self.debug == "json" { - let value = object_to_json(view.as_object()); - UiResponse::Json(serde_json::to_string(&value).unwrap()) - } else if self.debug == "raw" { - UiResponse::Object(view) - } else { - UiResponse::Html(render_view(self.render_info(), view.as_object())) - } - } -} - -impl<'r, 'o: 'r> Responder<'r, 'o> for UiResponse { - fn respond_to(self, request: &'r rocket::Request<'_>) -> rocket::response::Result<'o> { - match self { - UiResponse::Html(x) => RawHtml(x).respond_to(request), - UiResponse::Json(x) => RawJson(x).respond_to(request), - UiResponse::Object(x) => x.to_bytes().respond_to(request), - } - } -} |