summaryrefslogtreecommitdiff
path: root/internal/processing/workers/surfacenotify.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/processing/workers/surfacenotify.go')
-rw-r--r--internal/processing/workers/surfacenotify.go222
1 files changed, 190 insertions, 32 deletions
diff --git a/internal/processing/workers/surfacenotify.go b/internal/processing/workers/surfacenotify.go
index edeb4b57e..872ccca65 100644
--- a/internal/processing/workers/surfacenotify.go
+++ b/internal/processing/workers/surfacenotify.go
@@ -32,6 +32,62 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/util"
)
+// notifyPendingReply notifies the account replied-to
+// by the given status that they have a new reply,
+// and that approval is pending.
+func (s *Surface) notifyPendingReply(
+ ctx context.Context,
+ status *gtsmodel.Status,
+) error {
+ // Beforehand, ensure the passed status is fully populated.
+ if err := s.State.DB.PopulateStatus(ctx, status); err != nil {
+ return gtserror.Newf("error populating status %s: %w", status.ID, err)
+ }
+
+ if status.InReplyToAccount.IsRemote() {
+ // Don't notify
+ // remote accounts.
+ return nil
+ }
+
+ if status.AccountID == status.InReplyToAccountID {
+ // Don't notify
+ // self-replies.
+ return nil
+ }
+
+ // Ensure thread not muted
+ // by replied-to account.
+ muted, err := s.State.DB.IsThreadMutedByAccount(
+ ctx,
+ status.ThreadID,
+ status.InReplyToAccountID,
+ )
+ if err != nil {
+ return gtserror.Newf("error checking status thread mute %s: %w", status.ThreadID, err)
+ }
+
+ if muted {
+ // The replied-to account
+ // has muted the thread.
+ // Don't pester them.
+ return nil
+ }
+
+ // notify mentioned
+ // by status author.
+ if err := s.Notify(ctx,
+ gtsmodel.NotificationPendingReply,
+ status.InReplyToAccount,
+ status.Account,
+ status.ID,
+ ); err != nil {
+ return gtserror.Newf("error notifying replied-to account %s: %w", status.InReplyToAccountID, err)
+ }
+
+ return nil
+}
+
// notifyMentions iterates through mentions on the
// given status, and notifies each mentioned account
// that they have a new mention.
@@ -181,20 +237,82 @@ func (s *Surface) notifyFave(
ctx context.Context,
fave *gtsmodel.StatusFave,
) error {
+ notifyable, err := s.notifyableFave(ctx, fave)
+ if err != nil {
+ return err
+ }
+
+ if !notifyable {
+ // Nothing to do.
+ return nil
+ }
+
+ // notify status author
+ // of fave by account.
+ if err := s.Notify(ctx,
+ gtsmodel.NotificationFave,
+ fave.TargetAccount,
+ fave.Account,
+ fave.StatusID,
+ ); err != nil {
+ return gtserror.Newf("error notifying status author %s: %w", fave.TargetAccountID, err)
+ }
+
+ return nil
+}
+
+// notifyPendingFave notifies the target of the
+// given fave that their status has been faved
+// and that approval is required.
+func (s *Surface) notifyPendingFave(
+ ctx context.Context,
+ fave *gtsmodel.StatusFave,
+) error {
+ notifyable, err := s.notifyableFave(ctx, fave)
+ if err != nil {
+ return err
+ }
+
+ if !notifyable {
+ // Nothing to do.
+ return nil
+ }
+
+ // notify status author
+ // of fave by account.
+ if err := s.Notify(ctx,
+ gtsmodel.NotificationPendingFave,
+ fave.TargetAccount,
+ fave.Account,
+ fave.StatusID,
+ ); err != nil {
+ return gtserror.Newf("error notifying status author %s: %w", fave.TargetAccountID, err)
+ }
+
+ return nil
+}
+
+// notifyableFave checks that the given
+// fave should be notified, taking account
+// of localness of receiving account, and mutes.
+func (s *Surface) notifyableFave(
+ ctx context.Context,
+ fave *gtsmodel.StatusFave,
+) (bool, error) {
if fave.TargetAccountID == fave.AccountID {
// Self-fave, nothing to do.
- return nil
+ return false, nil
}
// Beforehand, ensure the passed status fave is fully populated.
if err := s.State.DB.PopulateStatusFave(ctx, fave); err != nil {
- return gtserror.Newf("error populating fave %s: %w", fave.ID, err)
+ return false, gtserror.Newf("error populating fave %s: %w", fave.ID, err)
}
if fave.TargetAccount.IsRemote() {
// no need to notify
// remote accounts.
- return nil
+ return false, nil
}
// Ensure favee hasn't
@@ -205,54 +323,105 @@ func (s *Surface) notifyFave(
fave.TargetAccountID,
)
if err != nil {
- return gtserror.Newf("error checking status thread mute %s: %w", fave.StatusID, err)
+ return false, gtserror.Newf("error checking status thread mute %s: %w", fave.StatusID, err)
}
if muted {
// Favee doesn't want
// notifs for this thread.
+ return false, nil
+ }
+
+ return true, nil
+}
+
+// notifyAnnounce notifies the status boost target
+// account that their status has been boosted.
+func (s *Surface) notifyAnnounce(
+ ctx context.Context,
+ boost *gtsmodel.Status,
+) error {
+ notifyable, err := s.notifyableAnnounce(ctx, boost)
+ if err != nil {
+ return err
+ }
+
+ if !notifyable {
+ // Nothing to do.
return nil
}
// notify status author
- // of fave by account.
+ // of boost by account.
if err := s.Notify(ctx,
- gtsmodel.NotificationFave,
- fave.TargetAccount,
- fave.Account,
- fave.StatusID,
+ gtsmodel.NotificationReblog,
+ boost.BoostOfAccount,
+ boost.Account,
+ boost.ID,
); err != nil {
- return gtserror.Newf("error notifying status author %s: %w", fave.TargetAccountID, err)
+ return gtserror.Newf("error notifying boost target %s: %w", boost.BoostOfAccountID, err)
}
return nil
}
-// notifyAnnounce notifies the status boost target
-// account that their status has been boosted.
-func (s *Surface) notifyAnnounce(
+// notifyPendingAnnounce notifies the status boost
+// target account that their status has been boosted,
+// and that the boost requires approval.
+func (s *Surface) notifyPendingAnnounce(
ctx context.Context,
- status *gtsmodel.Status,
+ boost *gtsmodel.Status,
) error {
+ notifyable, err := s.notifyableAnnounce(ctx, boost)
+ if err != nil {
+ return err
+ }
+
+ if !notifyable {
+ // Nothing to do.
+ return nil
+ }
+
+ // notify status author
+ // of boost by account.
+ if err := s.Notify(ctx,
+ gtsmodel.NotificationPendingReblog,
+ boost.BoostOfAccount,
+ boost.Account,
+ boost.ID,
+ ); err != nil {
+ return gtserror.Newf("error notifying boost target %s: %w", boost.BoostOfAccountID, err)
+ }
+
+ return nil
+}
+
+// notifyableAnnounce checks that the given
+// announce should be notified, taking account
+// of localness of receiving account, and mutes.
+func (s *Surface) notifyableAnnounce(
+ ctx context.Context,
+ status *gtsmodel.Status,
+) (bool, error) {
if status.BoostOfID == "" {
// Not a boost, nothing to do.
- return nil
+ return false, nil
}
if status.BoostOfAccountID == status.AccountID {
// Self-boost, nothing to do.
- return nil
+ return false, nil
}
// Beforehand, ensure the passed status is fully populated.
if err := s.State.DB.PopulateStatus(ctx, status); err != nil {
- return gtserror.Newf("error populating status %s: %w", status.ID, err)
+ return false, gtserror.Newf("error populating status %s: %w", status.ID, err)
}
if status.BoostOfAccount.IsRemote() {
// no need to notify
// remote accounts.
- return nil
+ return false, nil
}
// Ensure boostee hasn't
@@ -264,27 +433,16 @@ func (s *Surface) notifyAnnounce(
)
if err != nil {
- return gtserror.Newf("error checking status thread mute %s: %w", status.BoostOfID, err)
+ return false, gtserror.Newf("error checking status thread mute %s: %w", status.BoostOfID, err)
}
if muted {
// Boostee doesn't want
// notifs for this thread.
- return nil
+ return false, nil
}
- // notify status author
- // of boost by account.
- if err := s.Notify(ctx,
- gtsmodel.NotificationReblog,
- status.BoostOfAccount,
- status.Account,
- status.ID,
- ); err != nil {
- return gtserror.Newf("error notifying status author %s: %w", status.BoostOfAccountID, err)
- }
-
- return nil
+ return true, nil
}
func (s *Surface) notifyPollClose(ctx context.Context, status *gtsmodel.Status) error {