From 56eccb49954dbb561f4360481c3e52de92080f20 Mon Sep 17 00:00:00 2001 From: NorthRealm <155140859+NorthRealm@users.noreply.github.com> Date: Fri, 11 Jul 2025 10:17:52 +0800 Subject: [PATCH] Add Notifications section in User Settings (#35008) Related: #34982 --------- Signed-off-by: NorthRealm <155140859+NorthRealm@users.noreply.github.com> Co-authored-by: wxiaoguang --- routers/web/user/setting/account.go | 31 +---------- routers/web/user/setting/notifications.go | 62 ++++++++++++++++++++++ routers/web/web.go | 6 ++- templates/user/settings/account.tmpl | 27 +--------- templates/user/settings/navbar.tmpl | 7 ++- templates/user/settings/notifications.tmpl | 34 ++++++++++++ 6 files changed, 109 insertions(+), 58 deletions(-) create mode 100644 routers/web/user/setting/notifications.go create mode 100644 templates/user/settings/notifications.tmpl diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index b124d5e1def..6b17da50e5b 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -35,7 +35,7 @@ const ( // Account renders change user's password, user's email and user suicide page func Account(ctx *context.Context) { - if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials, setting.UserFeatureDeletion) && !setting.Service.EnableNotifyMail { + if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials, setting.UserFeatureDeletion) { ctx.NotFound(errors.New("account setting are not allowed to be changed")) return } @@ -43,7 +43,6 @@ func Account(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings.account") ctx.Data["PageIsSettingsAccount"] = true ctx.Data["Email"] = ctx.Doer.Email - ctx.Data["EnableNotifyMail"] = setting.Service.EnableNotifyMail loadAccountData(ctx) @@ -61,7 +60,6 @@ func AccountPost(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true ctx.Data["Email"] = ctx.Doer.Email - ctx.Data["EnableNotifyMail"] = setting.Service.EnableNotifyMail if ctx.HasError() { loadAccountData(ctx) @@ -112,7 +110,6 @@ func EmailPost(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true ctx.Data["Email"] = ctx.Doer.Email - ctx.Data["EnableNotifyMail"] = setting.Service.EnableNotifyMail // Make email address primary. if ctx.FormString("_method") == "PRIMARY" { @@ -172,30 +169,6 @@ func EmailPost(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/user/settings/account") return } - // Set Email Notification Preference - if ctx.FormString("_method") == "NOTIFICATION" { - preference := ctx.FormString("preference") - if !(preference == user_model.EmailNotificationsEnabled || - preference == user_model.EmailNotificationsOnMention || - preference == user_model.EmailNotificationsDisabled || - preference == user_model.EmailNotificationsAndYourOwn) { - log.Error("Email notifications preference change returned unrecognized option %s: %s", preference, ctx.Doer.Name) - ctx.ServerError("SetEmailPreference", errors.New("option unrecognized")) - return - } - opts := &user.UpdateOptions{ - EmailNotificationsPreference: optional.Some(preference), - } - if err := user.UpdateUser(ctx, ctx.Doer, opts); err != nil { - log.Error("Set Email Notifications failed: %v", err) - ctx.ServerError("UpdateUser", err) - return - } - log.Trace("Email notifications preference made %s: %s", preference, ctx.Doer.Name) - ctx.Flash.Success(ctx.Tr("settings.email_preference_set_success")) - ctx.Redirect(setting.AppSubURL + "/user/settings/account") - return - } if ctx.HasError() { loadAccountData(ctx) @@ -267,7 +240,6 @@ func DeleteAccount(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("settings") ctx.Data["PageIsSettingsAccount"] = true ctx.Data["Email"] = ctx.Doer.Email - ctx.Data["EnableNotifyMail"] = setting.Service.EnableNotifyMail if _, _, err := auth.UserSignIn(ctx, ctx.Doer.Name, ctx.FormString("password")); err != nil { switch { @@ -342,7 +314,6 @@ func loadAccountData(ctx *context.Context) { emails[i] = &email } ctx.Data["Emails"] = emails - ctx.Data["EmailNotificationsPreference"] = ctx.Doer.EmailNotificationsPreference ctx.Data["ActivationsPending"] = pendingActivation ctx.Data["CanAddEmails"] = !pendingActivation || !setting.Service.RegisterEmailConfirm ctx.Data["UserDisabledFeatures"] = user_model.DisabledFeaturesWithLoginType(ctx.Doer) diff --git a/routers/web/user/setting/notifications.go b/routers/web/user/setting/notifications.go new file mode 100644 index 00000000000..16e58a0481a --- /dev/null +++ b/routers/web/user/setting/notifications.go @@ -0,0 +1,62 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package setting + +import ( + "errors" + "net/http" + + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/optional" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/user" +) + +const tplSettingsNotifications templates.TplName = "user/settings/notifications" + +// Notifications render user's notifications settings +func Notifications(ctx *context.Context) { + if !setting.Service.EnableNotifyMail { + ctx.NotFound(nil) + return + } + + ctx.Data["Title"] = ctx.Tr("notifications") + ctx.Data["PageIsSettingsNotifications"] = true + ctx.Data["EmailNotificationsPreference"] = ctx.Doer.EmailNotificationsPreference + + ctx.HTML(http.StatusOK, tplSettingsNotifications) +} + +// NotificationsEmailPost set user's email notification preference +func NotificationsEmailPost(ctx *context.Context) { + if !setting.Service.EnableNotifyMail { + ctx.NotFound(nil) + return + } + + preference := ctx.FormString("preference") + if !(preference == user_model.EmailNotificationsEnabled || + preference == user_model.EmailNotificationsOnMention || + preference == user_model.EmailNotificationsDisabled || + preference == user_model.EmailNotificationsAndYourOwn) { + log.Error("Email notifications preference change returned unrecognized option %s: %s", preference, ctx.Doer.Name) + ctx.ServerError("SetEmailPreference", errors.New("option unrecognized")) + return + } + opts := &user.UpdateOptions{ + EmailNotificationsPreference: optional.Some(preference), + } + if err := user.UpdateUser(ctx, ctx.Doer, opts); err != nil { + log.Error("Set Email Notifications failed: %v", err) + ctx.ServerError("UpdateUser", err) + return + } + log.Trace("Email notifications preference made %s: %s", preference, ctx.Doer.Name) + ctx.Flash.Success(ctx.Tr("settings.email_preference_set_success")) + ctx.Redirect(setting.AppSubURL + "/user/settings/notifications") +} diff --git a/routers/web/web.go b/routers/web/web.go index ddea468d17f..b9c7013f639 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -595,6 +595,10 @@ func registerWebRoutes(m *web.Router) { m.Post("/hidden_comments", user_setting.UpdateUserHiddenComments) m.Post("/theme", web.Bind(forms.UpdateThemeForm{}), user_setting.UpdateUIThemePost) }) + m.Group("/notifications", func() { + m.Get("", user_setting.Notifications) + m.Post("/email", user_setting.NotificationsEmailPost) + }) m.Group("/security", func() { m.Get("", security.Security) m.Group("/two_factor", func() { @@ -682,7 +686,7 @@ func registerWebRoutes(m *web.Router) { m.Get("", user_setting.BlockedUsers) m.Post("", web.Bind(forms.BlockUserForm{}), user_setting.BlockedUsersPost) }) - }, reqSignIn, ctxDataSet("PageIsUserSettings", true, "EnablePackages", setting.Packages.Enabled)) + }, reqSignIn, ctxDataSet("PageIsUserSettings", true, "EnablePackages", setting.Packages.Enabled, "EnableNotifyMail", setting.Service.EnableNotifyMail)) m.Group("/user", func() { m.Get("/activate", auth.Activate) diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl index 2c01c88d47c..7dbac0ebd45 100644 --- a/templates/user/settings/account.tmpl +++ b/templates/user/settings/account.tmpl @@ -35,37 +35,12 @@ {{end}} - {{if not (and ($.UserDisabledFeatures.Contains "manage_credentials") (not $.EnableNotifyMail))}} + {{if not ($.UserDisabledFeatures.Contains "manage_credentials")}}

{{ctx.Locale.Tr "settings.manage_emails"}}

- {{if $.EnableNotifyMail}} -
-
- {{$.CsrfTokenHtml}} - -
- - -
-
- -
-
-
- {{end}} {{if not ($.UserDisabledFeatures.Contains "manage_credentials")}} {{range .Emails}}
diff --git a/templates/user/settings/navbar.tmpl b/templates/user/settings/navbar.tmpl index c6c15512abd..34e089a68a9 100644 --- a/templates/user/settings/navbar.tmpl +++ b/templates/user/settings/navbar.tmpl @@ -4,11 +4,16 @@ {{ctx.Locale.Tr "settings.profile"}} - {{if not (and ($.UserDisabledFeatures.Contains "manage_credentials" "deletion") (not $.EnableNotifyMail))}} + {{if not ($.UserDisabledFeatures.Contains "manage_credentials" "deletion")}} {{ctx.Locale.Tr "settings.account"}} {{end}} + {{if $.EnableNotifyMail}} + + {{ctx.Locale.Tr "notifications"}} + + {{end}} {{ctx.Locale.Tr "settings.appearance"}} diff --git a/templates/user/settings/notifications.tmpl b/templates/user/settings/notifications.tmpl new file mode 100644 index 00000000000..4694bbb30a7 --- /dev/null +++ b/templates/user/settings/notifications.tmpl @@ -0,0 +1,34 @@ +{{template "user/settings/layout_head" (dict "ctxData" . "pageClass" "user settings")}} +
+

+ {{ctx.Locale.Tr "notifications"}} +

+
+
+
+
+ {{$.CsrfTokenHtml}} +
+ + +
+
+ +
+
+
+
+
+
+ +{{template "user/settings/layout_footer" .}}