[feature] Notify accounts when a status they've interacted with has been edited (#4157)

This pull request adds sending notifications to local accounts that have interacted with a status, if we receive or create a new edit for that status.

closes https://codeberg.org/superseriousbusiness/gotosocial/issues/3991
Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4157
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Co-committed-by: tobi <tobi.smethurst@protonmail.com>
This commit is contained in:
tobi 2025-05-11 13:38:13 +00:00 committed by kim
commit 8480a75808
19 changed files with 375 additions and 81 deletions

View file

@ -732,3 +732,105 @@ func (s *statusDB) GetDirectStatusIDsBatch(ctx context.Context, minID string, ma
}
return statusIDs, nil
}
func (s *statusDB) GetStatusInteractions(
ctx context.Context,
statusID string,
localOnly bool,
) ([]gtsmodel.Interaction, error) {
// Prepare to get interactions.
interactions := []gtsmodel.Interaction{}
// Gather faves.
faves, err := s.state.DB.GetStatusFaves(ctx, statusID)
if err != nil && !errors.Is(err, db.ErrNoEntries) {
return nil, err
}
for _, fave := range faves {
// Get account at least.
if fave.Account == nil {
fave.Account, err = s.state.DB.GetAccountByID(ctx, fave.AccountID)
if err != nil {
log.Errorf(ctx, "error getting account for fave: %v", err)
continue
}
}
if localOnly && !fave.Account.IsLocal() {
// Skip not local.
continue
}
interactions = append(interactions, fave)
}
// Gather replies.
replies, err := s.state.DB.GetStatusReplies(ctx, statusID)
if err != nil && !errors.Is(err, db.ErrNoEntries) {
return nil, err
}
for _, reply := range replies {
// Get account at least.
if reply.Account == nil {
reply.Account, err = s.state.DB.GetAccountByID(ctx, reply.AccountID)
if err != nil {
log.Errorf(ctx, "error getting account for reply: %v", err)
continue
}
}
if localOnly && !reply.Account.IsLocal() {
// Skip not local.
continue
}
interactions = append(interactions, reply)
}
// Gather boosts.
boosts, err := s.state.DB.GetStatusBoosts(ctx, statusID)
if err != nil && !errors.Is(err, db.ErrNoEntries) {
return nil, err
}
for _, boost := range boosts {
// Get account at least.
if boost.Account == nil {
boost.Account, err = s.state.DB.GetAccountByID(ctx, boost.AccountID)
if err != nil {
log.Errorf(ctx, "error getting account for boost: %v", err)
continue
}
}
if localOnly && !boost.Account.IsLocal() {
// Skip not local.
continue
}
interactions = append(interactions, boost)
}
if len(interactions) == 0 {
return nil, db.ErrNoEntries
}
return interactions, nil
}
func (s *statusDB) GetStatusByEditID(
ctx context.Context,
editID string,
) (*gtsmodel.Status, error) {
edit, err := s.state.DB.GetStatusEditByID(
gtscontext.SetBarebones(ctx),
editID,
)
if err != nil {
return nil, err
}
return s.GetStatusByID(ctx, edit.StatusID)
}