mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 12:12:25 -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) | 		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…
	
	Add table
		Add a link
		
	
		Reference in a new issue