[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

@ -95,3 +95,10 @@ func (ir *InteractionRequest) IsAccepted() bool {
func (ir *InteractionRequest) IsRejected() bool {
return !ir.RejectedAt.IsZero()
}
// Interaction abstractly represents
// one interaction with a status, via
// liking, replying to, or boosting it.
type Interaction interface {
GetAccount() *Account
}

View file

@ -32,8 +32,8 @@ type Notification struct {
TargetAccount *Account `bun:"-"` // Account corresponding to TargetAccountID. Can be nil, always check first + select using ID if necessary.
OriginAccountID string `bun:"type:CHAR(26),nullzero,notnull"` // ID of the account that performed the action that created the notification.
OriginAccount *Account `bun:"-"` // Account corresponding to OriginAccountID. Can be nil, always check first + select using ID if necessary.
StatusID string `bun:"type:CHAR(26),nullzero"` // If the notification pertains to a status, what is the database ID of that status?
Status *Status `bun:"-"` // Status corresponding to StatusID. Can be nil, always check first + select using ID if necessary.
StatusOrEditID string `bun:"status_id,type:CHAR(26),nullzero"` // If the notification pertains to a status or a status edit event, what is the database ID of the status or status edit?
Status *Status `bun:"-"` // Status corresponding to StatusOrEditID. Can be nil, always check first + select using ID if necessary.
Read *bool `bun:",nullzero,notnull,default:false"` // Notification has been seen/read
}

View file

@ -89,6 +89,13 @@ func (s *Status) GetAccountID() string {
return s.AccountID
}
// GetAccount returns the account that owns
// this status. May be nil if status not populated.
// Fulfils Interaction interface.
func (s *Status) GetAccount() *Account {
return s.Account
}
// GetBoostOfID implements timeline.Timelineable{}.
func (s *Status) GetBoostOfID() string {
return s.BoostOfID

View file

@ -35,3 +35,10 @@ type StatusFave struct {
PreApproved bool `bun:"-"` // If true, then fave targets a status on our instance, has permission to do the interaction, and an Accept should be sent out for it immediately. Field not stored in the DB.
ApprovedByURI string `bun:",nullzero"` // URI of an Accept Activity that approves this Like.
}
// GetAccount returns the account that owns
// this fave. May be nil if fave not populated.
// Fulfils Interaction interface.
func (f *StatusFave) GetAccount() *Account {
return f.Account
}