aboutsummaryrefslogtreecommitdiff
path: root/ui/src/account
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-04-29 17:06:23 +0200
committermetamuffin <metamuffin@disroot.org>2025-04-29 17:06:23 +0200
commit212a0f23bc894faf88e159560c113f504349cc05 (patch)
treeee2ff0ff3b185d1874eb0e8fc4b75f1badf659b8 /ui/src/account
parentf73aa32549743b2967160d38c1622199c41524a4 (diff)
downloadjellything-212a0f23bc894faf88e159560c113f504349cc05.tar
jellything-212a0f23bc894faf88e159560c113f504349cc05.tar.bz2
jellything-212a0f23bc894faf88e159560c113f504349cc05.tar.zst
comiles again but still many logic holes
Diffstat (limited to 'ui/src/account')
-rw-r--r--ui/src/account/mod.rs83
-rw-r--r--ui/src/account/settings.rs92
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> {}