[bugfix] fix poll vote count responses on client and fedi API vote creation (#2343)
* increment poll votes *before* enqueuing vote to client API worker * increment vote counts before federating status update after vote in local poll * improved vote count calculation during backend -> frontend model conversion
This commit is contained in:
parent
e9e5dc5a40
commit
34d0879c16
|
@ -90,6 +90,11 @@ func (p *Processor) PollVote(ctx context.Context, requester *gtsmodel.Account, p
|
||||||
return nil, gtserror.NewErrorInternalError(err)
|
return nil, gtserror.NewErrorInternalError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before enqueuing it, increment the poll
|
||||||
|
// vote counts on the copy attached to the
|
||||||
|
// PollVote (that we also later return).
|
||||||
|
poll.IncrementVotes(choices)
|
||||||
|
|
||||||
// Enqueue worker task to handle side-effects of user poll vote(s).
|
// Enqueue worker task to handle side-effects of user poll vote(s).
|
||||||
p.state.Workers.EnqueueClientAPI(ctx, messages.FromClientAPI{
|
p.state.Workers.EnqueueClientAPI(ctx, messages.FromClientAPI{
|
||||||
APActivityType: ap.ActivityCreate,
|
APActivityType: ap.ActivityCreate,
|
||||||
|
@ -98,11 +103,6 @@ func (p *Processor) PollVote(ctx context.Context, requester *gtsmodel.Account, p
|
||||||
OriginAccount: requester,
|
OriginAccount: requester,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Before returning the converted poll model,
|
|
||||||
// increment the vote counts on our local copy
|
|
||||||
// to get latest, instead of another db query.
|
|
||||||
poll.IncrementVotes(choices)
|
|
||||||
|
|
||||||
// Return converted API model poll.
|
// Return converted API model poll.
|
||||||
return p.toAPIPoll(ctx, requester, poll)
|
return p.toAPIPoll(ctx, requester, poll)
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,6 +233,10 @@ func (p *fediAPI) CreatePollVote(ctx context.Context, fMsg messages.FromFediAPI)
|
||||||
p.surface.invalidateStatusFromTimelines(ctx, vote.Poll.StatusID)
|
p.surface.invalidateStatusFromTimelines(ctx, vote.Poll.StatusID)
|
||||||
|
|
||||||
if *status.Local {
|
if *status.Local {
|
||||||
|
// Before federating it, increment the
|
||||||
|
// poll vote counts on our local copy.
|
||||||
|
status.Poll.IncrementVotes(vote.Choices)
|
||||||
|
|
||||||
// These were poll votes in a local status, we need to
|
// These were poll votes in a local status, we need to
|
||||||
// federate the updated status model with latest vote counts.
|
// federate the updated status model with latest vote counts.
|
||||||
if err := p.federate.UpdateStatus(ctx, status); err != nil {
|
if err := p.federate.UpdateStatus(ctx, status); err != nil {
|
||||||
|
|
|
@ -1310,13 +1310,21 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
options []apimodel.PollOption
|
||||||
totalVotes int
|
totalVotes int
|
||||||
totalVoters int
|
totalVoters int
|
||||||
voteCounts []int
|
|
||||||
ownChoices []int
|
ownChoices []int
|
||||||
isAuthor bool
|
isAuthor bool
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Preallocate a slice of frontend model poll choices.
|
||||||
|
options = make([]apimodel.PollOption, len(poll.Options))
|
||||||
|
|
||||||
|
// Add the titles to all of the options.
|
||||||
|
for i, title := range poll.Options {
|
||||||
|
options[i].Title = title
|
||||||
|
}
|
||||||
|
|
||||||
if requester != nil {
|
if requester != nil {
|
||||||
// Get vote by requester in poll (if any).
|
// Get vote by requester in poll (if any).
|
||||||
vote, err := c.state.DB.GetPollVoteBy(ctx,
|
vote, err := c.state.DB.GetPollVoteBy(ctx,
|
||||||
|
@ -1335,37 +1343,28 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
|
||||||
// case that counts are hidden.
|
// case that counts are hidden.
|
||||||
totalVotes = len(vote.Choices)
|
totalVotes = len(vote.Choices)
|
||||||
totalVoters = 1
|
totalVoters = 1
|
||||||
|
for _, choice := range ownChoices {
|
||||||
|
options[choice].VotesCount++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if requester is author of source status.
|
// Check if requester is author of source status.
|
||||||
isAuthor = (requester.ID == poll.Status.AccountID)
|
isAuthor = (requester.ID == poll.Status.AccountID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preallocate a slice of frontend model poll choices.
|
|
||||||
options := make([]apimodel.PollOption, len(poll.Options))
|
|
||||||
|
|
||||||
// Add the titles to all of the options.
|
|
||||||
for i, title := range poll.Options {
|
|
||||||
options[i].Title = title
|
|
||||||
}
|
|
||||||
|
|
||||||
if isAuthor || !*poll.HideCounts {
|
if isAuthor || !*poll.HideCounts {
|
||||||
// A remote status,
|
// A remote status,
|
||||||
// the simple route!
|
// the simple route!
|
||||||
//
|
//
|
||||||
// Pull cached remote values.
|
// Pull cached remote values.
|
||||||
totalVoters = *poll.Voters
|
totalVoters = (*poll.Voters)
|
||||||
voteCounts = poll.Votes
|
|
||||||
|
|
||||||
// Accumulate total from all counts.
|
|
||||||
for _, count := range poll.Votes {
|
|
||||||
totalVotes += count
|
|
||||||
}
|
|
||||||
|
|
||||||
// When this is status author, or hide counts
|
// When this is status author, or hide counts
|
||||||
// is disabled, set the counts known per vote.
|
// is disabled, set the counts known per vote,
|
||||||
for i, count := range voteCounts {
|
// and accumulate all the vote totals.
|
||||||
|
for i, count := range poll.Votes {
|
||||||
options[i].VotesCount = count
|
options[i].VotesCount = count
|
||||||
|
totalVotes += count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1373,7 +1372,7 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
|
||||||
ID: poll.ID,
|
ID: poll.ID,
|
||||||
ExpiresAt: util.FormatISO8601(poll.ExpiresAt),
|
ExpiresAt: util.FormatISO8601(poll.ExpiresAt),
|
||||||
Expired: poll.Closed(),
|
Expired: poll.Closed(),
|
||||||
Multiple: *poll.Multiple,
|
Multiple: (*poll.Multiple),
|
||||||
VotesCount: totalVotes,
|
VotesCount: totalVotes,
|
||||||
VotersCount: totalVoters,
|
VotersCount: totalVoters,
|
||||||
Voted: (isAuthor || len(ownChoices) > 0),
|
Voted: (isAuthor || len(ownChoices) > 0),
|
||||||
|
|
Loading…
Reference in New Issue