Monorepo for Tangled
0

Configure Feed

Select the types of activity you want to include in your feed.

appview/db: suppress backlog on email prefrence toggle

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.org>

author
Anirudh Oppiliappan
committer
Tangled
date (Jul 22, 2026, 7:08 PM +0300) commit cc86ebc1 parent 578c0c8b change-id lvsrpszw
+43 -2
+43 -2
appview/db/notifications.go
··· 514 514 } 515 515 516 516 func (d *DB) UpdateNotificationPreferences(ctx context.Context, prefs *models.NotificationPreferences) error { 517 + tx, err := d.DB.BeginTx(ctx, nil) 518 + if err != nil { 519 + return fmt.Errorf("failed to begin transaction: %w", err) 520 + } 521 + defer tx.Rollback() 522 + 523 + var prevEmailEnabled bool 524 + var hadPrefs bool 525 + row := tx.QueryRowContext(ctx, 526 + `SELECT email_notifications FROM notification_preferences WHERE user_did = ?`, 527 + prefs.UserDid, 528 + ) 529 + switch err := row.Scan(&prevEmailEnabled); err { 530 + case nil: 531 + hadPrefs = true 532 + case sql.ErrNoRows: 533 + hadPrefs = false 534 + default: 535 + return fmt.Errorf("failed to read existing preferences: %w", err) 536 + } 537 + 517 538 query := ` 518 539 INSERT OR REPLACE INTO notification_preferences 519 540 (user_did, repo_starred, issue_created, issue_commented, pull_created, ··· 522 543 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 523 544 ` 524 545 525 - result, err := d.DB.ExecContext(ctx, query, 546 + result, err := tx.ExecContext(ctx, query, 526 547 prefs.UserDid, 527 548 prefs.RepoStarred, 528 549 prefs.IssueCreated, ··· 539 560 return fmt.Errorf("failed to update notification preferences: %w", err) 540 561 } 541 562 563 + // on enabling email notifications (from disabled or from no prior setting), 564 + // mark existing unemailed notifications as emailed so they aren't dispatched 565 + // as a backlog on the next digest tick. 566 + if prefs.EmailNotifications && (!hadPrefs || !prevEmailEnabled) { 567 + if err := MarkAllNotificationsEmailed(tx, string(prefs.UserDid)); err != nil { 568 + return fmt.Errorf("failed to suppress notification backlog: %w", err) 569 + } 570 + } 571 + 542 572 if prefs.ID == 0 { 543 573 id, err := result.LastInsertId() 544 574 if err != nil { ··· 547 577 prefs.ID = id 548 578 } 549 579 550 - return nil 580 + return tx.Commit() 551 581 } 552 582 553 583 // GetPendingEmailDigestRecipients returns DIDs of users who have email ··· 747 777 strings.Join(placeholders, ", "), 748 778 ) 749 779 _, err := e.Exec(query, args...) 780 + return err 781 + } 782 + 783 + // MarkAllNotificationsEmailed marks every currently-unemailed notification for 784 + // the recipient as emailed=1. Used when a user re-enables email notifications so 785 + // the pre-existing backlog isn't dispatched in one digest. 786 + func MarkAllNotificationsEmailed(e Execer, recipientDid string) error { 787 + _, err := e.Exec( 788 + `UPDATE notifications SET emailed = 1 WHERE recipient_did = ? AND emailed = 0`, 789 + recipientDid, 790 + ) 750 791 return err 751 792 } 752 793