mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Added email notification option to receive all own messages (#20179)
Sometimes users want to receive email notifications of messages they create or reply to, Added an option to personal preferences to allow users to choose Closes #20149
This commit is contained in:
		@@ -64,12 +64,14 @@ var AvailableHashAlgorithms = []string{
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	// EmailNotificationsEnabled indicates that the user would like to receive all email notifications
 | 
						// EmailNotificationsEnabled indicates that the user would like to receive all email notifications except your own
 | 
				
			||||||
	EmailNotificationsEnabled = "enabled"
 | 
						EmailNotificationsEnabled = "enabled"
 | 
				
			||||||
	// EmailNotificationsOnMention indicates that the user would like to be notified via email when mentioned.
 | 
						// EmailNotificationsOnMention indicates that the user would like to be notified via email when mentioned.
 | 
				
			||||||
	EmailNotificationsOnMention = "onmention"
 | 
						EmailNotificationsOnMention = "onmention"
 | 
				
			||||||
	// EmailNotificationsDisabled indicates that the user would not like to be notified via email.
 | 
						// EmailNotificationsDisabled indicates that the user would not like to be notified via email.
 | 
				
			||||||
	EmailNotificationsDisabled = "disabled"
 | 
						EmailNotificationsDisabled = "disabled"
 | 
				
			||||||
 | 
						// EmailNotificationsEnabled indicates that the user would like to receive all email notifications and your own
 | 
				
			||||||
 | 
						EmailNotificationsAndYourOwn = "andyourown"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// User represents the object of individual and member of organization.
 | 
					// User represents the object of individual and member of organization.
 | 
				
			||||||
@@ -1045,7 +1047,7 @@ func GetMaileableUsersByIDs(ids []int64, isMention bool) ([]*User, error) {
 | 
				
			|||||||
			Where("`type` = ?", UserTypeIndividual).
 | 
								Where("`type` = ?", UserTypeIndividual).
 | 
				
			||||||
			And("`prohibit_login` = ?", false).
 | 
								And("`prohibit_login` = ?", false).
 | 
				
			||||||
			And("`is_active` = ?", true).
 | 
								And("`is_active` = ?", true).
 | 
				
			||||||
			And("`email_notifications_preference` IN ( ?, ?)", EmailNotificationsEnabled, EmailNotificationsOnMention).
 | 
								In("`email_notifications_preference`", EmailNotificationsEnabled, EmailNotificationsOnMention, EmailNotificationsAndYourOwn).
 | 
				
			||||||
			Find(&ous)
 | 
								Find(&ous)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1053,7 +1055,7 @@ func GetMaileableUsersByIDs(ids []int64, isMention bool) ([]*User, error) {
 | 
				
			|||||||
		Where("`type` = ?", UserTypeIndividual).
 | 
							Where("`type` = ?", UserTypeIndividual).
 | 
				
			||||||
		And("`prohibit_login` = ?", false).
 | 
							And("`prohibit_login` = ?", false).
 | 
				
			||||||
		And("`is_active` = ?", true).
 | 
							And("`is_active` = ?", true).
 | 
				
			||||||
		And("`email_notifications_preference` = ?", EmailNotificationsEnabled).
 | 
							In("`email_notifications_preference`", EmailNotificationsEnabled, EmailNotificationsAndYourOwn).
 | 
				
			||||||
		Find(&ous)
 | 
							Find(&ous)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -153,6 +153,9 @@ func TestEmailNotificationPreferences(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		assert.NoError(t, user_model.SetEmailNotifications(user, user_model.EmailNotificationsDisabled))
 | 
							assert.NoError(t, user_model.SetEmailNotifications(user, user_model.EmailNotificationsDisabled))
 | 
				
			||||||
		assert.Equal(t, user_model.EmailNotificationsDisabled, user.EmailNotifications())
 | 
							assert.Equal(t, user_model.EmailNotificationsDisabled, user.EmailNotifications())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							assert.NoError(t, user_model.SetEmailNotifications(user, user_model.EmailNotificationsAndYourOwn))
 | 
				
			||||||
 | 
							assert.Equal(t, user_model.EmailNotificationsAndYourOwn, user.EmailNotifications())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -126,7 +126,7 @@ func (m *mailNotifier) NotifyPullRequestCodeComment(pr *issues_model.PullRequest
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
 | 
					func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *issues_model.Issue, assignee *user_model.User, removed bool, comment *issues_model.Comment) {
 | 
				
			||||||
	// mail only sent to added assignees and not self-assignee
 | 
						// mail only sent to added assignees and not self-assignee
 | 
				
			||||||
	if !removed && doer.ID != assignee.ID && (assignee.EmailNotifications() == user_model.EmailNotificationsEnabled || assignee.EmailNotifications() == user_model.EmailNotificationsOnMention) {
 | 
						if !removed && doer.ID != assignee.ID && assignee.EmailNotifications() != user_model.EmailNotificationsDisabled {
 | 
				
			||||||
		ct := fmt.Sprintf("Assigned #%d.", issue.Index)
 | 
							ct := fmt.Sprintf("Assigned #%d.", issue.Index)
 | 
				
			||||||
		if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{assignee}); err != nil {
 | 
							if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{assignee}); err != nil {
 | 
				
			||||||
			log.Error("Error in SendIssueAssignedMail for issue[%d] to assignee[%d]: %v", issue.ID, assignee.ID, err)
 | 
								log.Error("Error in SendIssueAssignedMail for issue[%d] to assignee[%d]: %v", issue.ID, assignee.ID, err)
 | 
				
			||||||
@@ -135,7 +135,7 @@ func (m *mailNotifier) NotifyIssueChangeAssignee(doer *user_model.User, issue *i
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
 | 
					func (m *mailNotifier) NotifyPullReviewRequest(doer *user_model.User, issue *issues_model.Issue, reviewer *user_model.User, isRequest bool, comment *issues_model.Comment) {
 | 
				
			||||||
	if isRequest && doer.ID != reviewer.ID && (reviewer.EmailNotifications() == user_model.EmailNotificationsEnabled || reviewer.EmailNotifications() == user_model.EmailNotificationsOnMention) {
 | 
						if isRequest && doer.ID != reviewer.ID && reviewer.EmailNotifications() != user_model.EmailNotificationsDisabled {
 | 
				
			||||||
		ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL())
 | 
							ct := fmt.Sprintf("Requested to review %s.", issue.HTMLURL())
 | 
				
			||||||
		if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil {
 | 
							if err := mailer.SendIssueAssignedMail(issue, doer, ct, comment, []*user_model.User{reviewer}); err != nil {
 | 
				
			||||||
			log.Error("Error in SendIssueAssignedMail for issue[%d] to reviewer[%d]: %v", issue.ID, reviewer.ID, err)
 | 
								log.Error("Error in SendIssueAssignedMail for issue[%d] to reviewer[%d]: %v", issue.ID, reviewer.ID, err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1787,6 +1787,7 @@ settings.mirror_sync_in_progress = Mirror synchronization is in progress. Check
 | 
				
			|||||||
settings.email_notifications.enable = Enable Email Notifications
 | 
					settings.email_notifications.enable = Enable Email Notifications
 | 
				
			||||||
settings.email_notifications.onmention = Only Email on Mention
 | 
					settings.email_notifications.onmention = Only Email on Mention
 | 
				
			||||||
settings.email_notifications.disable = Disable Email Notifications
 | 
					settings.email_notifications.disable = Disable Email Notifications
 | 
				
			||||||
 | 
					settings.email_notifications.andyourown = And Your Own Email Notifications
 | 
				
			||||||
settings.email_notifications.submit = Set Email Preference
 | 
					settings.email_notifications.submit = Set Email Preference
 | 
				
			||||||
settings.site = Website
 | 
					settings.site = Website
 | 
				
			||||||
settings.update_settings = Update Settings
 | 
					settings.update_settings = Update Settings
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -156,7 +156,8 @@ func EmailPost(ctx *context.Context) {
 | 
				
			|||||||
		preference := ctx.FormString("preference")
 | 
							preference := ctx.FormString("preference")
 | 
				
			||||||
		if !(preference == user_model.EmailNotificationsEnabled ||
 | 
							if !(preference == user_model.EmailNotificationsEnabled ||
 | 
				
			||||||
			preference == user_model.EmailNotificationsOnMention ||
 | 
								preference == user_model.EmailNotificationsOnMention ||
 | 
				
			||||||
			preference == user_model.EmailNotificationsDisabled) {
 | 
								preference == user_model.EmailNotificationsDisabled ||
 | 
				
			||||||
 | 
								preference == user_model.EmailNotificationsAndYourOwn) {
 | 
				
			||||||
			log.Error("Email notifications preference change returned unrecognized option %s: %s", preference, ctx.Doer.Name)
 | 
								log.Error("Email notifications preference change returned unrecognized option %s: %s", preference, ctx.Doer.Name)
 | 
				
			||||||
			ctx.ServerError("SetEmailPreference", errors.New("option unrecognized"))
 | 
								ctx.ServerError("SetEmailPreference", errors.New("option unrecognized"))
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -91,7 +91,9 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []*user_mo
 | 
				
			|||||||
	visited := make(map[int64]bool, len(unfiltered)+len(mentions)+1)
 | 
						visited := make(map[int64]bool, len(unfiltered)+len(mentions)+1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Avoid mailing the doer
 | 
						// Avoid mailing the doer
 | 
				
			||||||
 | 
						if ctx.Doer.EmailNotificationsPreference != user_model.EmailNotificationsAndYourOwn {
 | 
				
			||||||
		visited[ctx.Doer.ID] = true
 | 
							visited[ctx.Doer.ID] = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// =========== Mentions ===========
 | 
						// =========== Mentions ===========
 | 
				
			||||||
	if err = mailIssueCommentBatch(ctx, mentions, visited, true); err != nil {
 | 
						if err = mailIssueCommentBatch(ctx, mentions, visited, true); err != nil {
 | 
				
			||||||
@@ -133,6 +135,7 @@ func mailIssueCommentBatch(ctx *mailCommentContext, users []*user_model.User, vi
 | 
				
			|||||||
		// At this point we exclude:
 | 
							// At this point we exclude:
 | 
				
			||||||
		// user that don't have all mails enabled or users only get mail on mention and this is one ...
 | 
							// user that don't have all mails enabled or users only get mail on mention and this is one ...
 | 
				
			||||||
		if !(user.EmailNotificationsPreference == user_model.EmailNotificationsEnabled ||
 | 
							if !(user.EmailNotificationsPreference == user_model.EmailNotificationsEnabled ||
 | 
				
			||||||
 | 
								user.EmailNotificationsPreference == user_model.EmailNotificationsAndYourOwn ||
 | 
				
			||||||
			fromMention && user.EmailNotificationsPreference == user_model.EmailNotificationsOnMention) {
 | 
								fromMention && user.EmailNotificationsPreference == user_model.EmailNotificationsOnMention) {
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,6 +62,7 @@
 | 
				
			|||||||
									<div class="text">{{$.locale.Tr "settings.email_notifications"}}</div>
 | 
														<div class="text">{{$.locale.Tr "settings.email_notifications"}}</div>
 | 
				
			||||||
									<div class="menu">
 | 
														<div class="menu">
 | 
				
			||||||
										<div data-value="enabled" class="{{if eq .EmailNotificationsPreference "enabled"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.enable"}}</div>
 | 
															<div data-value="enabled" class="{{if eq .EmailNotificationsPreference "enabled"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.enable"}}</div>
 | 
				
			||||||
 | 
															<div data-value="andyourown" class="{{if eq .EmailNotificationsPreference "andyourown"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.andyourown"}}</div>
 | 
				
			||||||
										<div data-value="onmention" class="{{if eq .EmailNotificationsPreference "onmention"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.onmention"}}</div>
 | 
															<div data-value="onmention" class="{{if eq .EmailNotificationsPreference "onmention"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.onmention"}}</div>
 | 
				
			||||||
										<div data-value="disabled" class="{{if eq .EmailNotificationsPreference "disabled"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.disable"}}</div>
 | 
															<div data-value="disabled" class="{{if eq .EmailNotificationsPreference "disabled"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.disable"}}</div>
 | 
				
			||||||
									</div>
 | 
														</div>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user