mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-30 20:12:26 -05:00 
			
		
		
		
	[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
					
				
			
		
					 3 changed files with 27 additions and 24 deletions
				
			
		|  | @ -90,6 +90,11 @@ func (p *Processor) PollVote(ctx context.Context, requester *gtsmodel.Account, p | |||
| 		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). | ||||
| 	p.state.Workers.EnqueueClientAPI(ctx, messages.FromClientAPI{ | ||||
| 		APActivityType: ap.ActivityCreate, | ||||
|  | @ -98,11 +103,6 @@ func (p *Processor) PollVote(ctx context.Context, requester *gtsmodel.Account, p | |||
| 		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 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) | ||||
| 
 | ||||
| 	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 | ||||
| 		// federate the updated status model with latest vote counts. | ||||
| 		if err := p.federate.UpdateStatus(ctx, status); err != nil { | ||||
|  |  | |||
|  | @ -1310,13 +1310,21 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou | |||
| 	} | ||||
| 
 | ||||
| 	var ( | ||||
| 		options     []apimodel.PollOption | ||||
| 		totalVotes  int | ||||
| 		totalVoters int | ||||
| 		voteCounts  []int | ||||
| 		ownChoices  []int | ||||
| 		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 { | ||||
| 		// Get vote by requester in poll (if any). | ||||
| 		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. | ||||
| 			totalVotes = len(vote.Choices) | ||||
| 			totalVoters = 1 | ||||
| 			for _, choice := range ownChoices { | ||||
| 				options[choice].VotesCount++ | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// Check if requester is author of source status. | ||||
| 		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 { | ||||
| 		// A remote status, | ||||
| 		// the simple route! | ||||
| 		// | ||||
| 		// Pull cached remote values. | ||||
| 		totalVoters = *poll.Voters | ||||
| 		voteCounts = poll.Votes | ||||
| 
 | ||||
| 		// Accumulate total from all counts. | ||||
| 		for _, count := range poll.Votes { | ||||
| 			totalVotes += count | ||||
| 		} | ||||
| 		totalVoters = (*poll.Voters) | ||||
| 
 | ||||
| 		// When this is status author, or hide counts | ||||
| 		// is disabled, set the counts known per vote. | ||||
| 		for i, count := range voteCounts { | ||||
| 		// is disabled, set the counts known per vote, | ||||
| 		// and accumulate all the vote totals. | ||||
| 		for i, count := range poll.Votes { | ||||
| 			options[i].VotesCount = count | ||||
| 			totalVotes += count | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1373,7 +1372,7 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou | |||
| 		ID:          poll.ID, | ||||
| 		ExpiresAt:   util.FormatISO8601(poll.ExpiresAt), | ||||
| 		Expired:     poll.Closed(), | ||||
| 		Multiple:    *poll.Multiple, | ||||
| 		Multiple:    (*poll.Multiple), | ||||
| 		VotesCount:  totalVotes, | ||||
| 		VotersCount: totalVoters, | ||||
| 		Voted:       (isAuthor || len(ownChoices) > 0), | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue