diff --git a/models/issue_mail.go b/models/issue_mail.go index 01a12b16d2a8e..f6c293938eb8e 100644 --- a/models/issue_mail.go +++ b/models/issue_mail.go @@ -70,7 +70,7 @@ func mailIssueCommentToParticipants(e Engine, issue *Issue, doer *User, content if err != nil { return fmt.Errorf("GetUserByID [%d]: %v", watchers[i].UserID, err) } - if to.IsOrganization() { + if to.IsOrganization() || !to.EnabledEmailNotifications() { continue } @@ -78,9 +78,9 @@ func mailIssueCommentToParticipants(e Engine, issue *Issue, doer *User, content names = append(names, to.Name) } for i := range participants { - if participants[i].ID == doer.ID { - continue - } else if com.IsSliceContainsStr(names, participants[i].Name) { + if participants[i].ID == doer.ID || + com.IsSliceContainsStr(names, participants[i].Name) || + !participants[i].EnabledEmailNotifications() { continue } diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 9ffcfb4df2005..f324df8325a98 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -240,6 +240,8 @@ var migrations = []Migration{ NewMigration("add index on owner_id of repository and type, review_id of comment", addIndexOnRepositoryAndComment), // v92 -> v93 NewMigration("remove orphaned repository index statuses", removeLingeringIndexStatus), + // v93 -> v94 + NewMigration("add email notification enabled boolean to user", addEmailNotificationEnabledToUser), } // Migrate database to current version diff --git a/models/migrations/v93.go b/models/migrations/v93.go new file mode 100644 index 0000000000000..679b4d0da3727 --- /dev/null +++ b/models/migrations/v93.go @@ -0,0 +1,16 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package migrations + +import "github.com/go-xorm/xorm" + +func addEmailNotificationEnabledToUser(x *xorm.Engine) error { + // Issue see models/user.go + type User struct { + EmailNotificationsEnabled bool `xorm:"NOT NULL DEFAULT true"` + } + + return x.Sync2(new(User)) +} diff --git a/models/user.go b/models/user.go index 2e4f971662ad9..3678ac9e9f152 100644 --- a/models/user.go +++ b/models/user.go @@ -87,10 +87,11 @@ type User struct { Name string `xorm:"UNIQUE NOT NULL"` FullName string // Email is the primary email address (to be used for communication) - Email string `xorm:"NOT NULL"` - KeepEmailPrivate bool - Passwd string `xorm:"NOT NULL"` - PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'pbkdf2'"` + Email string `xorm:"NOT NULL"` + KeepEmailPrivate bool + EmailNotificationsEnabled bool `xorm:"NOT NULL DEFAULT true"` + Passwd string `xorm:"NOT NULL"` + PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'pbkdf2'"` // MustChangePassword is an attribute that determines if a user // is to change his/her password after registration. @@ -719,6 +720,18 @@ func (u *User) IsMailable() bool { return u.IsActive } +// EnabledEmailNotifications checks if the user has +// enabled receiving notifications by email +func (u *User) EnabledEmailNotifications() bool { + return u.EmailNotificationsEnabled +} + +// SetEmailNotifications sets whether the user +// would like to receive notifications by email +func (u *User) SetEmailNotifications(set bool) { + u.EmailNotificationsEnabled = set +} + func isUserExist(e Engine, uid int64, name string) (bool, error) { if len(name) == 0 { return false, nil @@ -1265,7 +1278,7 @@ func getUserEmailsByNames(e Engine, names []string) []string { if err != nil { continue } - if u.IsMailable() { + if u.IsMailable() && u.EnabledEmailNotifications() { mails = append(mails, u.Email) } } diff --git a/routers/user/setting/account.go b/routers/user/setting/account.go index 3fd6a8db5ee0a..4795e0dc2020e 100644 --- a/routers/user/setting/account.go +++ b/routers/user/setting/account.go @@ -81,6 +81,12 @@ func EmailPost(ctx *context.Context, form auth.AddEmailForm) { ctx.Redirect(setting.AppSubURL + "/user/settings/account") return } + // Set Email Notification Preference + if ctx.Query("_method") == "NOTIFICATION" { + ctx.User.SetEmailNotifications(ctx.QueryBool("enable")) + ctx.Redirect(setting.AppSubURL + "/user/settings/account") + return + } if ctx.HasError() { loadAccountData(ctx)