diff options
-rw-r--r-- | locale/en.ini | 3 | ||||
-rw-r--r-- | server/src/ui/account/settings.rs | 46 | ||||
-rw-r--r-- | server/src/ui/admin/mod.rs | 4 | ||||
-rw-r--r-- | server/src/ui/admin/user.rs | 52 | ||||
-rw-r--r-- | ui/src/account/settings.rs | 13 | ||||
-rw-r--r-- | ui/src/admin/mod.rs | 6 | ||||
-rw-r--r-- | ui/src/admin/user.rs | 10 | ||||
-rw-r--r-- | ui/src/lib.rs | 2 | ||||
-rw-r--r-- | ui/src/scaffold.rs | 13 |
9 files changed, 73 insertions, 76 deletions
diff --git a/locale/en.ini b/locale/en.ini index 863a51c..6594832 100644 --- a/locale/en.ini +++ b/locale/en.ini @@ -110,6 +110,8 @@ admin.invite_create_success=Invite created: {invite} admin.invite_delete_success=Invite deleted admin.import_success=Import finished admin.update_search_success=Search index updated +admin.users.remove_success=User removed +admin.users.permission_update_success=Permissions updated page.curr=Page {cur} of {max} page.prev=Previous page @@ -160,6 +162,7 @@ settings.immutable=Immutable settings.apply=Apply settings.player_preference=Preferred Media Player settings.player_preference.changed=Media Player preference changed. +settings.native_secret.changed=Native secret updated. eid.isrc=ISRC eid.barcode=Barcode diff --git a/server/src/ui/account/settings.rs b/server/src/ui/account/settings.rs index 677683b..d31c4ba 100644 --- a/server/src/ui/account/settings.rs +++ b/server/src/ui/account/settings.rs @@ -8,7 +8,10 @@ use crate::{ helper::{RequestInfo, A}, ui::error::MyResult, }; -use jellycommon::user::{PlayerKind, Theme}; +use jellycommon::{ + routes::u_account_settings, + user::{PlayerKind, Theme}, +}; use jellylogic::account::{ update_user_display_name, update_user_native_secret, update_user_password, update_user_player_preference, update_user_theme, @@ -17,7 +20,8 @@ use jellyui::{account::settings::SettingsPage, locale::tr, render_page, scaffold use rocket::{ form::{self, validate::len, Contextual, Form}, get, post, - response::content::RawHtml, + request::FlashMessage, + response::{content::RawHtml, Flash, Redirect}, FromForm, }; use std::ops::Range; @@ -37,11 +41,11 @@ fn option_len<'v>(value: &Option<String>, range: Range<usize>) -> form::Result<' value.as_ref().map(|v| len(v, range)).unwrap_or(Ok(())) } -// TODO use FlashMessage -fn settings_page(flash: Option<Result<String, String>>, ri: RequestInfo) -> RawHtml<String> { +#[get("/account/settings")] +pub fn r_account_settings(ri: RequestInfo, flash: Option<FlashMessage>) -> RawHtml<String> { RawHtml(render_page( &SettingsPage { - flash, + flash: &flash.map(FlashMessage::into_inner), session: &SessionInfo { user: ri.session.user.clone(), }, @@ -51,23 +55,18 @@ fn settings_page(flash: Option<Result<String, String>>, ri: RequestInfo) -> RawH )) } -#[get("/account/settings")] -pub fn r_account_settings(ri: RequestInfo) -> RawHtml<String> { - settings_page(None, ri) -} - #[post("/account/settings", data = "<form>")] pub fn r_account_settings_post( ri: RequestInfo, form: Form<Contextual<SettingsForm>>, -) -> MyResult<RawHtml<String>> { +) -> MyResult<Flash<Redirect>> { let form = match &form.value { Some(v) => v, None => { - return Ok(settings_page( - Some(Err(format_form_error(form).to_string())), - ri, - )) + return Ok(Flash::error( + Redirect::to(u_account_settings()), + format_form_error(form), + )); } }; @@ -95,15 +94,14 @@ pub fn r_account_settings_post( } if let Some(native_secret) = &form.native_secret { update_user_native_secret(&ri.session, native_secret)?; - out += "Native secret updated.\n"; + out += &*tr(ri.lang, "settings.native_secret.changed"); + out += "\n"; } + let out = if out.is_empty() { + tr(ri.lang, "settings.no_change").to_string() + } else { + out + }; - Ok(settings_page( - Some(Ok(if out.is_empty() { - tr(ri.lang, "settings.no_change").to_string() - } else { - out - })), - ri, // using the old session here, results in outdated theme being displayed - )) + Ok(Flash::success(Redirect::to(u_account_settings()), out)) } diff --git a/server/src/ui/admin/mod.rs b/server/src/ui/admin/mod.rs index e124a13..02a7605 100644 --- a/server/src/ui/admin/mod.rs +++ b/server/src/ui/admin/mod.rs @@ -28,8 +28,6 @@ pub async fn r_admin_dashboard( flash: Option<FlashMessage<'_>>, ) -> MyResult<RawHtml<String>> { ri.session.assert_admin()?; - let flash = None; - let invites = list_invites(&ri.session)?; let last_import_err = get_import_errors(&ri.session).await; @@ -44,7 +42,7 @@ pub async fn r_admin_dashboard( busy, last_import_err: &last_import_err, invites: &invites, - flash, + flash: &flash.map(FlashMessage::into_inner), lang: &ri.lang, }, ri.render_info(), diff --git a/server/src/ui/admin/user.rs b/server/src/ui/admin/user.rs index afbe8f0..fa84f52 100644 --- a/server/src/ui/admin/user.rs +++ b/server/src/ui/admin/user.rs @@ -5,13 +5,22 @@ */ use crate::{helper::RequestInfo, ui::error::MyResult}; use anyhow::Context; -use jellycommon::user::UserPermission; +use jellycommon::{ + routes::{u_admin_user, u_admin_users}, + user::UserPermission, +}; use jellylogic::admin::user::{admin_users, delete_user, get_user, update_user_perms, GrantState}; use jellyui::{ admin::user::{AdminUserPage, AdminUsersPage}, + locale::tr, render_page, }; -use rocket::{form::Form, get, post, response::content::RawHtml, FromForm, FromFormField}; +use rocket::{ + form::Form, + get, post, + response::{content::RawHtml, Flash, Redirect}, + FromForm, FromFormField, +}; #[get("/admin/users")] pub fn r_admin_users(ri: RequestInfo) -> MyResult<RawHtml<String>> { @@ -19,7 +28,7 @@ pub fn r_admin_users(ri: RequestInfo) -> MyResult<RawHtml<String>> { let r = admin_users(&ri.session)?; Ok(RawHtml(render_page( &AdminUsersPage { - flash: None, + flash: &None, lang: &ri.lang, users: &r.users, }, @@ -34,7 +43,7 @@ pub fn r_admin_user<'a>(ri: RequestInfo, name: &'a str) -> MyResult<RawHtml<Stri Ok(RawHtml(render_page( &AdminUserPage { - flash: None, + flash: &None, lang: &ri.lang, user: &user, }, @@ -60,7 +69,7 @@ pub fn r_admin_user_permission( ri: RequestInfo, form: Form<UserPermissionForm>, name: &str, -) -> MyResult<RawHtml<String>> { +) -> MyResult<Flash<Redirect>> { ri.session.assert_admin()?; let perm = serde_json::from_str::<UserPermission>(&form.permission) .context("parsing provided permission")?; @@ -76,30 +85,21 @@ pub fn r_admin_user_permission( }, )?; - let user = get_user(&ri.session, name)?; - - Ok(RawHtml(render_page( - &AdminUserPage { - flash: Some(Ok("Permissions updated".to_string())), - lang: &ri.lang, - user: &user, - }, - ri.render_info(), - ))) + Ok(Flash::success( + Redirect::to(u_admin_user(name)), + tr( + ri.lang, + &"admin.users.permission_update_success".to_string(), + ), + )) } #[post("/admin/<name>/remove")] -pub fn r_admin_remove_user(ri: RequestInfo, name: &str) -> MyResult<RawHtml<String>> { +pub fn r_admin_remove_user(ri: RequestInfo, name: &str) -> MyResult<Flash<Redirect>> { ri.session.assert_admin()?; delete_user(&ri.session, name)?; - let r = admin_users(&ri.session)?; - - Ok(RawHtml(render_page( - &AdminUsersPage { - flash: Some(Ok("User removed".to_string())), - lang: &ri.lang, - users: &r.users, - }, - ri.render_info(), - ))) + Ok(Flash::success( + Redirect::to(u_admin_users()), + tr(ri.lang, &"admin.users.remove_success".to_string()), + )) } diff --git a/ui/src/account/settings.rs b/ui/src/account/settings.rs index 7c5a3b8..7334c62 100644 --- a/ui/src/account/settings.rs +++ b/ui/src/account/settings.rs @@ -4,9 +4,9 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ use crate::{ - Page, + FlashM, Page, locale::{Language, tr, trs}, - scaffold::SessionInfo, + scaffold::{FlashDisplay, SessionInfo}, }; use jellycommon::{ routes::{u_account_login, u_account_settings}, @@ -24,14 +24,9 @@ impl Page for SettingsPage<'_> { } markup::define! { - SettingsPage<'a>(flash: Option<Result<String, String>>, session: &'a SessionInfo, lang: &'a Language) { + SettingsPage<'a>(session: &'a SessionInfo, lang: &'a Language, flash: &'a FlashM) { h1 { "Settings" } - @if let Some(flash) = &flash { - @match flash { - Ok(mesg) => { section.message { p.success { @mesg } } } - Err(err) => { section.message { p.error { @format!("{err}") } } } - } - } + @FlashDisplay {flash} h2 { @trs(&lang, "account") } a.switch_account[href=u_account_login()] { "Switch Account" } form[method="POST", action=u_account_settings()] { diff --git a/ui/src/admin/mod.rs b/ui/src/admin/mod.rs index 394f1c6..c2afc9d 100644 --- a/ui/src/admin/mod.rs +++ b/ui/src/admin/mod.rs @@ -7,7 +7,7 @@ pub mod log; pub mod user; -use crate::{locale::{tr, Language}, scaffold::FlashDisplay, Page}; +use crate::{FlashM, Page, locale::Language, scaffold::FlashDisplay}; use jellycommon::routes::{ u_admin_import, u_admin_invite_create, u_admin_invite_remove, u_admin_log, u_admin_update_search, u_admin_users, @@ -23,9 +23,9 @@ impl Page for AdminDashboardPage<'_> { } markup::define!( - AdminDashboardPage<'a>(lang: &'a Language, busy: Option<&'static str>, last_import_err: &'a [String], flash: Option<Result<String, String>>, invites: &'a [String]) { + AdminDashboardPage<'a>(lang: &'a Language, busy: Option<&'static str>, last_import_err: &'a [String], flash: &'a FlashM, invites: &'a [String]) { h1 { "Admin Panel" } - @FlashDisplay { flash: flash.clone() } + @FlashDisplay { flash } @if !last_import_err.is_empty() { section.message.error { details { diff --git a/ui/src/admin/user.rs b/ui/src/admin/user.rs index 613fc08..225482e 100644 --- a/ui/src/admin/user.rs +++ b/ui/src/admin/user.rs @@ -4,7 +4,7 @@ Copyright (C) 2025 metamuffin <metamuffin.org> */ -use crate::{Page, locale::Language, scaffold::FlashDisplay}; +use crate::{FlashM, Page, locale::Language, scaffold::FlashDisplay}; use jellycommon::{ routes::{u_admin_user, u_admin_user_permission, u_admin_user_remove, u_admin_users}, user::{PermissionSet, User, UserPermission}, @@ -28,9 +28,9 @@ impl Page for AdminUsersPage<'_> { } markup::define! { - AdminUsersPage<'a>(lang: &'a Language, users: &'a [User], flash: Option<Result<String, String>>) { + AdminUsersPage<'a>(lang: &'a Language, users: &'a [User], flash: &'a FlashM) { h1 { "User Management" } - @FlashDisplay { flash: flash.clone() } + @FlashDisplay { flash } h2 { "All Users" } ul { @for u in *users { li { @@ -38,10 +38,10 @@ markup::define! { } }} } - AdminUserPage<'a>(lang: &'a Language, user: &'a User, flash: Option<Result<String, String>>) { + AdminUserPage<'a>(lang: &'a Language, user: &'a User, flash: &'a FlashM) { h1 { @format!("{:?}", user.display_name) " (" @user.name ")" } a[href=u_admin_users()] "Back to the User List" - @FlashDisplay { flash: flash.clone() } + @FlashDisplay { flash } form[method="POST", action=u_admin_user_remove(&user.name)] { // input[type="text", name="name", value=&user.name, hidden]; input.danger[type="submit", value="Remove user(!)"]; diff --git a/ui/src/lib.rs b/ui/src/lib.rs index c71e30f..cbf15bf 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -28,6 +28,8 @@ use std::{ sync::{LazyLock, Mutex}, }; +pub type FlashM = Option<(String, String)>; + #[rustfmt::skip] #[derive(Debug, Deserialize, Serialize, Default)] pub struct Config { diff --git a/ui/src/scaffold.rs b/ui/src/scaffold.rs index a115ec3..95074cf 100644 --- a/ui/src/scaffold.rs +++ b/ui/src/scaffold.rs @@ -5,7 +5,7 @@ */ use crate::{ - CONF, + CONF, FlashM, locale::{Language, escape, tr, trs}, }; use jellycommon::{ @@ -72,11 +72,12 @@ markup::define! { } } - FlashDisplay(flash: Option<Result<String, String>>) { - @if let Some(flash) = &flash { - @match flash { - Ok(mesg) => { section.message { p.success { @mesg } } } - Err(err) => { section.message { p.error { @err } } } + FlashDisplay<'a>(flash: &'a FlashM) { + @if let Some((kind,message)) = &flash { + @match kind.as_str() { + "success" => { section.message { p.success { @message } } } + "error" => { section.message { p.error { @message } } } + _ => { section.message { p { @message } } } } } } |