diff options
author | 2025-02-20 10:13:07 +0000 | |
---|---|---|
committer | 2025-02-20 11:13:07 +0100 | |
commit | a03a35a5d6c86ef85d66bae501daaa1cd8c47c2e (patch) | |
tree | 78d745437a15d4db3ea37965fa6a40f5156eb482 /internal/processing | |
parent | [chore] Step minio down to 7.0.85 (#3808) (diff) | |
download | gotosocial-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.go | 2 | ||||
-rw-r--r-- | internal/processing/workers/fromfediapi.go | 52 |
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 } |