[bugfix/docs] Poll api fixups + swagger docs (#2345)

This commit is contained in:
tobi 2023-11-09 13:06:37 +01:00 committed by GitHub
parent b1c65ed9ac
commit 42a19cf390
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 93 additions and 14 deletions

View file

@ -2020,14 +2020,21 @@ definitions:
type: array type: array
x-go-name: Options x-go-name: Options
own_votes: own_votes:
description: When called with a user token, which options has the authorized user chosen? Contains an array of index values for options. description: |-
When called with a user token, which options has the authorized
user chosen? Contains an array of index values for options.
Omitted when no user token provided.
items: items:
format: int64 format: int64
type: integer type: integer
type: array type: array
x-go-name: OwnVotes x-go-name: OwnVotes
voted: voted:
description: When called with a user token, has the authorized user voted? description: |-
When called with a user token, has the authorized user voted?
Omitted when no user token provided.
type: boolean type: boolean
x-go-name: Voted x-go-name: Voted
voters_count: voters_count:
@ -2059,6 +2066,36 @@ definitions:
type: object type: object
x-go-name: PollOption x-go-name: PollOption
x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model
pollRequest:
properties:
expires_in:
description: |-
Duration the poll should be open, in seconds.
If provided, media_ids cannot be used, and poll[options] must be provided.
format: int64
type: integer
x-go-name: ExpiresIn
hide_totals:
description: Hide vote counts until the poll ends.
type: boolean
x-go-name: HideTotals
multiple:
description: Allow multiple choices on this poll.
type: boolean
x-go-name: Multiple
options:
description: |-
Array of possible answers.
If provided, media_ids cannot be used, and poll[expires_in] must be provided.
name: poll[options]
items:
type: string
type: array
x-go-name: Options
title: PollRequest models a request to create a poll.
type: object
x-go-name: PollRequest
x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model
report: report:
properties: properties:
action_taken: action_taken:
@ -2346,6 +2383,8 @@ definitions:
type: string type: string
type: array type: array
x-go-name: MediaIDs x-go-name: MediaIDs
poll:
$ref: '#/definitions/pollRequest'
scheduled_at: scheduled_at:
description: |- description: |-
ISO 8601 Datetime at which to schedule a status. ISO 8601 Datetime at which to schedule a status.
@ -6028,13 +6067,20 @@ paths:
- polls - polls
/api/v1/polls/{id}/vote: /api/v1/polls/{id}/vote:
post: post:
operationId: poll operationId: pollVote
parameters: parameters:
- description: Target poll ID. - description: Target poll ID.
in: path in: path
name: id name: id
required: true required: true
type: string type: string
- description: Poll choice indices on which to vote.
in: formData
items:
type: integer
name: choices
required: true
type: array
produces: produces:
- application/json - application/json
responses: responses:
@ -6309,6 +6355,11 @@ paths:
name: media_ids name: media_ids
type: array type: array
x-go-name: MediaIDs x-go-name: MediaIDs
- $ref: '#/definitions/pollRequest'
description: Poll to include with this status.
in: formData
name: poll
x-go-name: Poll
- description: ID of the status being replied to, if status is a reply. - description: ID of the status being replied to, if status is a reply.
in: formData in: formData
name: in_reply_to_id name: in_reply_to_id

View file

@ -27,7 +27,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/oauth" "github.com/superseriousbusiness/gotosocial/internal/oauth"
) )
// PollVotePOSTHandler swagger:operation POST /api/v1/polls/{id}/vote poll // PollVotePOSTHandler swagger:operation POST /api/v1/polls/{id}/vote pollVote
// //
// Vote with choices in the given poll. // Vote with choices in the given poll.
// //
@ -45,6 +45,14 @@ import (
// description: Target poll ID. // description: Target poll ID.
// in: path // in: path
// required: true // required: true
// -
// name: choices
// type: array
// items:
// type: integer
// description: Poll choice indices on which to vote.
// in: formData
// required: true
// //
// security: // security:
// - OAuth2 Bearer: // - OAuth2 Bearer:

View file

@ -41,10 +41,15 @@ type Poll struct {
VotersCount int `json:"voters_count"` VotersCount int `json:"voters_count"`
// When called with a user token, has the authorized user voted? // When called with a user token, has the authorized user voted?
Voted bool `json:"voted,omitempty"` //
// Omitted when no user token provided.
Voted *bool `json:"voted,omitempty"`
// When called with a user token, which options has the authorized user chosen? Contains an array of index values for options. // When called with a user token, which options has the authorized
OwnVotes []int `json:"own_votes,omitempty"` // user chosen? Contains an array of index values for options.
//
// Omitted when no user token provided.
OwnVotes *[]int `json:"own_votes,omitempty"`
// Possible answers for the poll. // Possible answers for the poll.
Options []PollOption `json:"options"` Options []PollOption `json:"options"`
@ -66,7 +71,7 @@ type PollOption struct {
// PollRequest models a request to create a poll. // PollRequest models a request to create a poll.
// //
// swagger:parameters createStatus // swagger:model pollRequest
type PollRequest struct { type PollRequest struct {
// Array of possible answers. // Array of possible answers.
// If provided, media_ids cannot be used, and poll[expires_in] must be provided. // If provided, media_ids cannot be used, and poll[expires_in] must be provided.
@ -86,7 +91,7 @@ type PollRequest struct {
// PollVoteRequest models a request to vote in a poll. // PollVoteRequest models a request to vote in a poll.
// //
// swagger:parameters pollVote // swagger:ignore
type PollVoteRequest struct { type PollVoteRequest struct {
// Choices contains poll vote choice indices. Note that form // Choices contains poll vote choice indices. Note that form
// uses a different key than the JSON, i.e. the '[]' suffix. // uses a different key than the JSON, i.e. the '[]' suffix.

View file

@ -155,7 +155,7 @@ type StatusCreateRequest struct {
// in: formData // in: formData
MediaIDs []string `form:"media_ids[]" json:"media_ids" xml:"media_ids"` MediaIDs []string `form:"media_ids[]" json:"media_ids" xml:"media_ids"`
// Poll to include with this status. // Poll to include with this status.
// swagger:ignore // in: formData
Poll *PollRequest `form:"poll" json:"poll" xml:"poll"` Poll *PollRequest `form:"poll" json:"poll" xml:"poll"`
// ID of the status being replied to, if status is a reply. // ID of the status being replied to, if status is a reply.
// in: formData // in: formData

View file

@ -1313,8 +1313,10 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
options []apimodel.PollOption options []apimodel.PollOption
totalVotes int totalVotes int
totalVoters int totalVoters int
ownChoices []int voted *bool
ownChoices *[]int
isAuthor bool isAuthor bool
emojis []apimodel.Emoji
) )
// Preallocate a slice of frontend model poll choices. // Preallocate a slice of frontend model poll choices.
@ -1337,19 +1339,26 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
if vote != nil { if vote != nil {
// Set choices by requester. // Set choices by requester.
ownChoices = vote.Choices ownChoices = &vote.Choices
// Update default totals in the // Update default totals in the
// 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 { for _, choice := range *ownChoices {
options[choice].VotesCount++ options[choice].VotesCount++
} }
} else {
// Requester is defined but hasn't made
// a choice. Init slice to serialize as `[]`.
ownChoices = util.Ptr(make([]int, 0))
} }
// 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)
// Requester is defined so voted should be defined too.
voted = util.Ptr((isAuthor || len(*ownChoices) > 0))
} }
if isAuthor || !*poll.HideCounts { if isAuthor || !*poll.HideCounts {
@ -1368,6 +1377,11 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
} }
} }
// TODO: emojis used in poll options.
// For now init to empty slice to serialize as `[]`.
// In future inherit from parent status.
emojis = make([]apimodel.Emoji, 0)
return &apimodel.Poll{ return &apimodel.Poll{
ID: poll.ID, ID: poll.ID,
ExpiresAt: util.FormatISO8601(poll.ExpiresAt), ExpiresAt: util.FormatISO8601(poll.ExpiresAt),
@ -1375,9 +1389,10 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
Multiple: (*poll.Multiple), Multiple: (*poll.Multiple),
VotesCount: totalVotes, VotesCount: totalVotes,
VotersCount: totalVoters, VotersCount: totalVoters,
Voted: (isAuthor || len(ownChoices) > 0), Voted: voted,
OwnVotes: ownChoices, OwnVotes: ownChoices,
Options: options, Options: options,
Emojis: emojis,
}, nil }, nil
} }