aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNorthRealm <155140859+NorthRealm@users.noreply.github.com>2025-07-11 10:17:52 +0800
committerGitHub <noreply@github.com>2025-07-11 10:17:52 +0800
commit56eccb49954dbb561f4360481c3e52de92080f20 (patch)
tree27e806baa84caf97b1217d025a61ffb49536f91a
parentb46623f6a5aa8beb3613bd89abde8d77b1e66758 (diff)
downloadgitea-56eccb49954dbb561f4360481c3e52de92080f20.tar.gz
gitea-56eccb49954dbb561f4360481c3e52de92080f20.zip
Add Notifications section in User Settings (#35008)
Related: #34982 --------- Signed-off-by: NorthRealm <155140859+NorthRealm@users.noreply.github.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
-rw-r--r--routers/web/user/setting/account.go31
-rw-r--r--routers/web/user/setting/notifications.go62
-rw-r--r--routers/web/web.go6
-rw-r--r--templates/user/settings/account.tmpl27
-rw-r--r--templates/user/settings/navbar.tmpl7
-rw-r--r--templates/user/settings/notifications.tmpl34
6 files changed, 109 insertions, 58 deletions
diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go
index b124d5e1de..6b17da50e5 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 0000000000..16e58a0481
--- /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 ddea468d17..b9c7013f63 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 2c01c88d47..7dbac0ebd4 100644
--- a/templates/user/settings/account.tmpl
+++ b/templates/user/settings/account.tmpl
@@ -35,37 +35,12 @@
{{end}}
</div>
- {{if not (and ($.UserDisabledFeatures.Contains "manage_credentials") (not $.EnableNotifyMail))}}
+ {{if not ($.UserDisabledFeatures.Contains "manage_credentials")}}
<h4 class="ui top attached header">
{{ctx.Locale.Tr "settings.manage_emails"}}
</h4>
<div class="ui attached segment">
<div class="ui list flex-items-block">
- {{if $.EnableNotifyMail}}
- <div class="item">
- <form class="ui form tw-w-full" action="{{AppSubUrl}}/user/settings/account/email" method="post">
- {{$.CsrfTokenHtml}}
- <input name="_method" type="hidden" value="NOTIFICATION">
- <div class="field">
- <label>{{ctx.Locale.Tr "settings.email_desc"}}</label>
- <div class="ui selection dropdown">
- <input name="preference" type="hidden" value="{{.EmailNotificationsPreference}}">
- {{svg "octicon-triangle-down" 14 "dropdown icon"}}
- <div class="text"></div>
- <div class="menu">
- <div data-value="enabled" class="{{if eq .EmailNotificationsPreference "enabled"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.enable"}}</div>
- <div data-value="andyourown" class="{{if eq .EmailNotificationsPreference "andyourown"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.andyourown"}}</div>
- <div data-value="onmention" class="{{if eq .EmailNotificationsPreference "onmention"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.onmention"}}</div>
- <div data-value="disabled" class="{{if eq .EmailNotificationsPreference "disabled"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.disable"}}</div>
- </div>
- </div>
- </div>
- <div class="field">
- <button class="ui primary button">{{ctx.Locale.Tr "settings.email_notifications.submit"}}</button>
- </div>
- </form>
- </div>
- {{end}}
{{if not ($.UserDisabledFeatures.Contains "manage_credentials")}}
{{range .Emails}}
<div class="item tw-flex-wrap">
diff --git a/templates/user/settings/navbar.tmpl b/templates/user/settings/navbar.tmpl
index c6c15512ab..34e089a68a 100644
--- a/templates/user/settings/navbar.tmpl
+++ b/templates/user/settings/navbar.tmpl
@@ -4,11 +4,16 @@
<a class="{{if .PageIsSettingsProfile}}active {{end}}item" href="{{AppSubUrl}}/user/settings">
{{ctx.Locale.Tr "settings.profile"}}
</a>
- {{if not (and ($.UserDisabledFeatures.Contains "manage_credentials" "deletion") (not $.EnableNotifyMail))}}
+ {{if not ($.UserDisabledFeatures.Contains "manage_credentials" "deletion")}}
<a class="{{if .PageIsSettingsAccount}}active {{end}}item" href="{{AppSubUrl}}/user/settings/account">
{{ctx.Locale.Tr "settings.account"}}
</a>
{{end}}
+ {{if $.EnableNotifyMail}}
+ <a class="{{if .PageIsSettingsNotifications}}active {{end}}item" href="{{AppSubUrl}}/user/settings/notifications">
+ {{ctx.Locale.Tr "notifications"}}
+ </a>
+ {{end}}
<a class="{{if .PageIsSettingsAppearance}}active {{end}}item" href="{{AppSubUrl}}/user/settings/appearance">
{{ctx.Locale.Tr "settings.appearance"}}
</a>
diff --git a/templates/user/settings/notifications.tmpl b/templates/user/settings/notifications.tmpl
new file mode 100644
index 0000000000..4694bbb30a
--- /dev/null
+++ b/templates/user/settings/notifications.tmpl
@@ -0,0 +1,34 @@
+{{template "user/settings/layout_head" (dict "ctxData" . "pageClass" "user settings")}}
+ <div class="user-setting-content">
+ <h4 class="ui top attached header">
+ {{ctx.Locale.Tr "notifications"}}
+ </h4>
+ <div class="ui attached segment">
+ <div class="ui list flex-items-block">
+ <div class="item">
+ <form class="ui form tw-w-full" action="{{AppSubUrl}}/user/settings/notifications/email" method="post">
+ {{$.CsrfTokenHtml}}
+ <div class="field">
+ <label>{{ctx.Locale.Tr "settings.email_desc"}}</label>
+ <div class="ui selection dropdown">
+ <input name="preference" type="hidden" value="{{.EmailNotificationsPreference}}">
+ {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+ <div class="text"></div>
+ <div class="menu">
+ <div data-value="enabled" class="{{if eq .EmailNotificationsPreference "enabled"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.enable"}}</div>
+ <div data-value="andyourown" class="{{if eq .EmailNotificationsPreference "andyourown"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.andyourown"}}</div>
+ <div data-value="onmention" class="{{if eq .EmailNotificationsPreference "onmention"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.onmention"}}</div>
+ <div data-value="disabled" class="{{if eq .EmailNotificationsPreference "disabled"}}active selected {{end}}item">{{ctx.Locale.Tr "settings.email_notifications.disable"}}</div>
+ </div>
+ </div>
+ </div>
+ <div class="field">
+ <button class="ui primary button">{{ctx.Locale.Tr "settings.email_notifications.submit"}}</button>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+
+{{template "user/settings/layout_footer" .}}