summaryrefslogtreecommitdiff
path: root/internal/federation/dereferencing/status.go
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2023-10-25 16:04:53 +0200
committerLibravatar GitHub <noreply@github.com>2023-10-25 15:04:53 +0100
commitc7b6cd7770cad9bfdc23decffa7c4068752dbbbd (patch)
tree0f039fd34fb0287860fce06ff1c30dedd1882136 /internal/federation/dereferencing/status.go
parent[bugfix] allow store smaller PNG image than 261 bytes (#2263) (#2298) (diff)
downloadgotosocial-c7b6cd7770cad9bfdc23decffa7c4068752dbbbd.tar.xz
[feature] Status thread mute/unmute functionality (#2278)
* add db models + functions for keeping track of threads * give em the old linty testy * create, remove, check mutes * swagger * testerino * test mute/unmute via api * add info log about new index creation * thread + allow muting of any remote statuses that mention a local account * IsStatusThreadMutedBy -> IsThreadMutedByAccount * use common processing functions in status processor * set = NULL * favee! * get rekt darlings, darlings get rekt * testrig please, have mercy muy liege
Diffstat (limited to 'internal/federation/dereferencing/status.go')
-rw-r--r--internal/federation/dereferencing/status.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/internal/federation/dereferencing/status.go b/internal/federation/dereferencing/status.go
index bb6a8002c..89b3088c8 100644
--- a/internal/federation/dereferencing/status.go
+++ b/internal/federation/dereferencing/status.go
@@ -24,6 +24,8 @@ import (
"net/url"
"time"
+ "slices"
+
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
@@ -293,6 +295,12 @@ func (d *Dereferencer) enrichStatus(
return nil, nil, gtserror.Newf("error populating mentions for status %s: %w", uri, err)
}
+ // Now that we know who this status replies to (handled by ASStatusToStatus)
+ // and who it mentions, we can add a ThreadID to it if necessary.
+ if err := d.threadStatus(ctx, latestStatus); err != nil {
+ return nil, nil, gtserror.Newf("error checking / creating threadID for status %s: %w", uri, err)
+ }
+
// Ensure the status' tags are populated, (changes are expected / okay).
if err := d.fetchStatusTags(ctx, latestStatus); err != nil {
return nil, nil, gtserror.Newf("error populating tags for status %s: %w", uri, err)
@@ -410,6 +418,57 @@ func (d *Dereferencer) fetchStatusMentions(ctx context.Context, requestUser stri
return nil
}
+func (d *Dereferencer) threadStatus(ctx context.Context, status *gtsmodel.Status) error {
+ if status.InReplyTo != nil {
+ if parentThreadID := status.InReplyTo.ThreadID; parentThreadID != "" {
+ // Simplest case: parent status
+ // is threaded, so inherit threadID.
+ status.ThreadID = parentThreadID
+ return nil
+ }
+ }
+
+ // Parent wasn't threaded. If this
+ // status mentions a local account,
+ // we should thread it so that local
+ // account can mute it if they want.
+ mentionsLocal := slices.ContainsFunc(
+ status.Mentions,
+ func(m *gtsmodel.Mention) bool {
+ // If TargetAccount couldn't
+ // be deref'd, we know it's not
+ // a local account, so only
+ // check for non-nil accounts.
+ return m.TargetAccount != nil &&
+ m.TargetAccount.IsLocal()
+ },
+ )
+
+ if !mentionsLocal {
+ // Status doesn't mention a
+ // local account, so we don't
+ // need to thread it.
+ return nil
+ }
+
+ // Status mentions a local account.
+ // Create a new thread and assign
+ // it to the status.
+ threadID := id.NewULID()
+
+ if err := d.state.DB.PutThread(
+ ctx,
+ &gtsmodel.Thread{
+ ID: threadID,
+ },
+ ); err != nil {
+ return gtserror.Newf("error inserting new thread in db: %w", err)
+ }
+
+ status.ThreadID = threadID
+ return nil
+}
+
func (d *Dereferencer) fetchStatusTags(ctx context.Context, status *gtsmodel.Status) error {
// Allocate new slice to take the yet-to-be determined tag IDs.
status.TagIDs = make([]string, len(status.Tags))