summaryrefslogtreecommitdiff
path: root/internal/processing
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2025-02-20 10:13:07 +0000
committerLibravatar GitHub <noreply@github.com>2025-02-20 11:13:07 +0100
commita03a35a5d6c86ef85d66bae501daaa1cd8c47c2e (patch)
tree78d745437a15d4db3ea37965fa6a40f5156eb482 /internal/processing
parent[chore] Step minio down to 7.0.85 (#3808) (diff)
downloadgotosocial-a03a35a5d6c86ef85d66bae501daaa1cd8c47c2e.tar.xz
[bugfix] update fedi api to support multiple separate votes in same multiple choice poll (#3809)
Diffstat (limited to 'internal/processing')
-rw-r--r--internal/processing/polls/vote.go2
-rw-r--r--internal/processing/workers/fromfediapi.go52
2 files changed, 47 insertions, 7 deletions
diff --git a/internal/processing/polls/vote.go b/internal/processing/polls/vote.go
index c970fe106..6585793cd 100644
--- a/internal/processing/polls/vote.go
+++ b/internal/processing/polls/vote.go
@@ -93,7 +93,7 @@ func (p *Processor) PollVote(ctx context.Context, requester *gtsmodel.Account, p
// Before enqueuing it, increment the poll
// vote counts on the copy attached to the
// PollVote (that we also later return).
- poll.IncrementVotes(choices)
+ poll.IncrementVotes(choices, true)
// Enqueue worker task to handle side-effects of user poll vote(s).
p.state.Workers.Client.Queue.Push(&messages.FromClientAPI{
diff --git a/internal/processing/workers/fromfediapi.go b/internal/processing/workers/fromfediapi.go
index ce5b8b5d1..2e513449b 100644
--- a/internal/processing/workers/fromfediapi.go
+++ b/internal/processing/workers/fromfediapi.go
@@ -124,6 +124,10 @@ func (p *Processor) ProcessFromFediAPI(ctx context.Context, fMsg *messages.FromF
// UPDATE ACCOUNT
case ap.ActorPerson:
return p.fediAPI.UpdateAccount(ctx, fMsg)
+
+ // UPDATE QUESTION
+ case ap.ActivityQuestion:
+ return p.fediAPI.UpdatePollVote(ctx, fMsg)
}
// ACCEPT SOMETHING
@@ -355,7 +359,8 @@ func (p *fediAPI) CreatePollVote(ctx context.Context, fMsg *messages.FromFediAPI
return gtserror.Newf("cannot cast %T -> *gtsmodel.PollVote", fMsg.GTSModel)
}
- // Insert the new poll vote in the database.
+ // Insert the new poll vote in the database, note this
+ // will handle updating votes on the poll model itself.
if err := p.state.DB.PutPollVote(ctx, vote); err != nil {
return gtserror.Newf("error inserting poll vote in db: %w", err)
}
@@ -376,10 +381,45 @@ func (p *fediAPI) CreatePollVote(ctx context.Context, fMsg *messages.FromFediAPI
status.Poll = vote.Poll
if *status.Local {
- // Before federating it, increment the
- // poll vote counts on our local copy.
- status.Poll.IncrementVotes(vote.Choices)
+ // Before federating it, increment the poll vote
+ // and voter counts, *only on our local copy*.
+ status.Poll.IncrementVotes(vote.Choices, true)
+
+ // These were poll votes in a local status, we need to
+ // federate the updated status model with latest vote counts.
+ if err := p.federate.UpdateStatus(ctx, status); err != nil {
+ log.Errorf(ctx, "error federating status update: %v", err)
+ }
+ }
+
+ // Interaction counts changed, uncache from timelines.
+ p.surface.invalidateStatusFromTimelines(ctx, status.ID)
+
+ return nil
+}
+func (p *fediAPI) UpdatePollVote(ctx context.Context, fMsg *messages.FromFediAPI) error {
+ // Cast poll vote type from the worker message.
+ vote, ok := fMsg.GTSModel.(*gtsmodel.PollVote)
+ if !ok {
+ return gtserror.Newf("cannot cast %T -> *gtsmodel.PollVote", fMsg.GTSModel)
+ }
+
+ // Update poll vote model (specifically only choices) in the database.
+ if err := p.state.DB.UpdatePollVote(ctx, vote, "choices"); err != nil {
+ return gtserror.Newf("error updating poll vote in db: %w", err)
+ }
+
+ // Update the vote counts on the poll model itself. These will have
+ // been updated by message pusher as we can't know which were new.
+ if err := p.state.DB.UpdatePoll(ctx, vote.Poll, "votes"); err != nil {
+ return gtserror.Newf("error updating poll in db: %w", err)
+ }
+
+ // Get the origin status.
+ status := vote.Poll.Status
+
+ if *status.Local {
// These were poll votes in a local status, we need to
// federate the updated status model with latest vote counts.
if err := p.federate.UpdateStatus(ctx, status); err != nil {
@@ -387,8 +427,8 @@ func (p *fediAPI) CreatePollVote(ctx context.Context, fMsg *messages.FromFediAPI
}
}
- // Interaction counts changed on the source status, uncache from timelines.
- p.surface.invalidateStatusFromTimelines(ctx, vote.Poll.StatusID)
+ // Interaction counts changed, uncache from timelines.
+ p.surface.invalidateStatusFromTimelines(ctx, status.ID)
return nil
}