diff options
Diffstat (limited to 'ui/src/account')
-rw-r--r-- | ui/src/account/mod.rs | 83 | ||||
-rw-r--r-- | ui/src/account/settings.rs | 92 |
2 files changed, 173 insertions, 2 deletions
diff --git a/ui/src/account/mod.rs b/ui/src/account/mod.rs index bc8d3ce..36a41c5 100644 --- a/ui/src/account/mod.rs +++ b/ui/src/account/mod.rs @@ -3,8 +3,55 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2025 metamuffin <metamuffin.org> */ -use crate::locale::{Language, tr, trs}; -use jellycommon::routes::u_account_login; +pub mod settings; + +use crate::{ + Page, + locale::{Language, tr, trs}, +}; +use jellycommon::routes::{u_account_login, u_account_register}; + +impl Page for AccountLogin<'_> { + fn title(&self) -> String { + tr( + *self.lang, + if self.logged_in { + "account.login.switch" + } else { + "account.login" + }, + ) + .to_string() + } + + fn to_render(&self) -> markup::DynRender { + markup::new!(@self) + } +} +impl Page for AccountRegister<'_> { + fn title(&self) -> String { + tr(*self.lang, "account.register").to_string() + } + fn to_render(&self) -> markup::DynRender { + markup::new!(@self) + } +} +impl Page for AccountRegisterSuccess<'_> { + fn title(&self) -> String { + tr(*self.lang, "account.register").to_string() + } + fn to_render(&self) -> markup::DynRender { + markup::new!(@self) + } +} +impl Page for AccountLogout<'_> { + fn title(&self) -> String { + tr(*self.lang, "account.logout").to_string() + } + fn to_render(&self) -> markup::DynRender { + markup::new!(@self) + } +} markup::define! { AccountRegister<'a>(lang: &'a Language) { @@ -24,4 +71,36 @@ markup::define! { p { @trs(&lang, "account.register.login") " " a[href=u_account_login()] { @trs(&lang, "account.register.login_here") } } } } + AccountRegisterSuccess<'a>(lang: &'a Language, logged_in: bool) { + h1 { @trs(&lang, if *logged_in { + "account.register.success.switch" + } else { + "account.register.success" + })} + } + AccountLogin<'a>(lang: &'a Language, logged_in: bool) { + form.account[method="POST", action=""] { + h1 { @self.title() } + + label[for="inp-username"] { @trs(&lang, "account.username") } + input[type="text", id="inp-username", name="username"]; br; + label[for="inp-password"] { @trs(&lang, "account.password") } + input[type="password", id="inp-password", name="password"]; br; + + input[type="submit", value=&*tr(**lang, if *logged_in { "account.login.submit.switch" } else { "account.login.submit" })]; + + @if *logged_in { + p { @trs(&lang, "account.login.register.switch") " " a[href=u_account_register()] { @trs(&lang, "account.login.register_here") } } + } else { + p { @trs(&lang, "account.login.cookie_note") } + p { @trs(&lang, "account.login.register") " " a[href=u_account_register()] { @trs(&lang, "account.login.register_here") } } + } + } + } + AccountLogout<'a>(lang: &'a Language) { + form.account[method="POST", action=""] { + h1 { @trs(&lang, "account.logout") } + input[type="submit", value=&*tr(**lang, "account.logout.submit")]; + } + } } diff --git a/ui/src/account/settings.rs b/ui/src/account/settings.rs new file mode 100644 index 0000000..7c5a3b8 --- /dev/null +++ b/ui/src/account/settings.rs @@ -0,0 +1,92 @@ +/* + 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) 2025 metamuffin <metamuffin.org> +*/ +use crate::{ + Page, + locale::{Language, tr, trs}, + scaffold::SessionInfo, +}; +use jellycommon::{ + routes::{u_account_login, u_account_settings}, + user::{PlayerKind, Theme}, +}; +use markup::RenderAttributeValue; + +impl Page for SettingsPage<'_> { + fn title(&self) -> String { + format!("Settings") + } + fn to_render(&self) -> markup::DynRender { + markup::new!(@self) + } +} + +markup::define! { + SettingsPage<'a>(flash: Option<Result<String, String>>, session: &'a SessionInfo, lang: &'a Language) { + h1 { "Settings" } + @if let Some(flash) = &flash { + @match flash { + Ok(mesg) => { section.message { p.success { @mesg } } } + Err(err) => { section.message { p.error { @format!("{err}") } } } + } + } + h2 { @trs(&lang, "account") } + a.switch_account[href=u_account_login()] { "Switch Account" } + form[method="POST", action=u_account_settings()] { + label[for="username"] { @trs(&lang, "account.username") } + input[type="text", id="username", disabled, value=&session.user.name]; + input[type="submit", disabled, value=&*tr(**lang, "settings.immutable")]; + } + form[method="POST", action=u_account_settings()] { + label[for="display_name"] { @trs(lang, "account.display_name") } + input[type="text", id="display_name", name="display_name", value=&session.user.display_name]; + input[type="submit", value=&*tr(**lang, "settings.update")]; + } + form[method="POST", action=u_account_settings()] { + label[for="password"] { @trs(lang, "account.password") } + input[type="password", id="password", name="password"]; + input[type="submit", value=&*tr(**lang, "settings.update")]; + } + h2 { @trs(&lang, "settings.appearance") } + form[method="POST", action=u_account_settings()] { + fieldset { + legend { @trs(&lang, "settings.appearance.theme") } + @for theme in Theme::ALL { + label { input[type="radio", name="theme", value=A(*theme), checked=session.user.theme==*theme]; @trs(lang, &format!("theme.{theme}")) } br; + } + } + input[type="submit", value=&*tr(**lang, "settings.apply")]; + } + form[method="POST", action=u_account_settings()] { + fieldset { + legend { @trs(&lang, "settings.player_preference") } + @for kind in PlayerKind::ALL { + label { input[type="radio", name="player_preference", value=A(*kind), checked=session.user.player_preference==*kind]; @trs(lang, &format!("player_kind.{kind}")) } br; + } + } + input[type="submit", value=&*tr(**lang, "settings.apply")]; + } + form[method="POST", action=u_account_settings()] { + label[for="native_secret"] { "Native Secret" } + input[type="password", id="native_secret", name="native_secret"]; + input[type="submit", value=&*tr(**lang, "settings.update")]; + p { "The secret can be found in " code{"$XDG_CONFIG_HOME/jellynative_secret"} " or by clicking " a.button[href="jellynative://show-secret-v1"] { "Show Secret" } "." } + } + } +} + +struct A<T>(pub T); +impl markup::Render for A<Theme> { + fn render(&self, writer: &mut impl std::fmt::Write) -> std::fmt::Result { + writer.write_str(self.0.to_str()) + } +} +impl markup::Render for A<PlayerKind> { + fn render(&self, writer: &mut impl std::fmt::Write) -> std::fmt::Result { + writer.write_str(self.0.to_str()) + } +} +impl RenderAttributeValue for A<Theme> {} +impl RenderAttributeValue for A<PlayerKind> {} |