Skip to content

Commit

Permalink
[bugfix/docs] Poll api fixups + swagger docs (#2345)
Browse files Browse the repository at this point in the history
  • Loading branch information
tsmethurst committed Nov 9, 2023
1 parent b1c65ed commit 42a19cf
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 14 deletions.
57 changes: 54 additions & 3 deletions docs/api/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2020,14 +2020,21 @@ definitions:
type: array
x-go-name: Options
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:
format: int64
type: integer
type: array
x-go-name: OwnVotes
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
x-go-name: Voted
voters_count:
Expand Down Expand Up @@ -2059,6 +2066,36 @@ definitions:
type: object
x-go-name: PollOption
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:
properties:
action_taken:
Expand Down Expand Up @@ -2346,6 +2383,8 @@ definitions:
type: string
type: array
x-go-name: MediaIDs
poll:
$ref: '#/definitions/pollRequest'
scheduled_at:
description: |-
ISO 8601 Datetime at which to schedule a status.
Expand Down Expand Up @@ -6028,13 +6067,20 @@ paths:
- polls
/api/v1/polls/{id}/vote:
post:
operationId: poll
operationId: pollVote
parameters:
- description: Target poll ID.
in: path
name: id
required: true
type: string
- description: Poll choice indices on which to vote.
in: formData
items:
type: integer
name: choices
required: true
type: array
produces:
- application/json
responses:
Expand Down Expand Up @@ -6309,6 +6355,11 @@ paths:
name: media_ids
type: array
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.
in: formData
name: in_reply_to_id
Expand Down
10 changes: 9 additions & 1 deletion internal/api/client/polls/polls_vote.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
"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.
//
Expand All @@ -45,6 +45,14 @@ import (
// description: Target poll ID.
// in: path
// required: true
// -
// name: choices
// type: array
// items:
// type: integer
// description: Poll choice indices on which to vote.
// in: formData
// required: true
//
// security:
// - OAuth2 Bearer:
Expand Down
15 changes: 10 additions & 5 deletions internal/api/model/poll.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,15 @@ type Poll struct {
VotersCount int `json:"voters_count"`

// 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.
OwnVotes []int `json:"own_votes,omitempty"`
// 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.
OwnVotes *[]int `json:"own_votes,omitempty"`

// Possible answers for the poll.
Options []PollOption `json:"options"`
Expand All @@ -66,7 +71,7 @@ type PollOption struct {

// PollRequest models a request to create a poll.
//
// swagger:parameters createStatus
// swagger:model pollRequest
type PollRequest struct {
// Array of possible answers.
// If provided, media_ids cannot be used, and poll[expires_in] must be provided.
Expand All @@ -86,7 +91,7 @@ type PollRequest struct {

// PollVoteRequest models a request to vote in a poll.
//
// swagger:parameters pollVote
// swagger:ignore
type PollVoteRequest struct {
// Choices contains poll vote choice indices. Note that form
// uses a different key than the JSON, i.e. the '[]' suffix.
Expand Down
2 changes: 1 addition & 1 deletion internal/api/model/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ type StatusCreateRequest struct {
// in: formData
MediaIDs []string `form:"media_ids[]" json:"media_ids" xml:"media_ids"`
// Poll to include with this status.
// swagger:ignore
// in: formData
Poll *PollRequest `form:"poll" json:"poll" xml:"poll"`
// ID of the status being replied to, if status is a reply.
// in: formData
Expand Down
23 changes: 19 additions & 4 deletions internal/typeutils/internaltofrontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -1313,8 +1313,10 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou
options []apimodel.PollOption
totalVotes int
totalVoters int
ownChoices []int
voted *bool
ownChoices *[]int
isAuthor bool
emojis []apimodel.Emoji
)

// Preallocate a slice of frontend model poll choices.
Expand All @@ -1337,19 +1339,26 @@ func (c *Converter) PollToAPIPoll(ctx context.Context, requester *gtsmodel.Accou

if vote != nil {
// Set choices by requester.
ownChoices = vote.Choices
ownChoices = &vote.Choices

// Update default totals in the
// case that counts are hidden.
totalVotes = len(vote.Choices)
totalVoters = 1
for _, choice := range ownChoices {
for _, choice := range *ownChoices {
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.
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 {
Expand All @@ -1368,16 +1377,22 @@ 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{
ID: poll.ID,
ExpiresAt: util.FormatISO8601(poll.ExpiresAt),
Expired: poll.Closed(),
Multiple: (*poll.Multiple),
VotesCount: totalVotes,
VotersCount: totalVoters,
Voted: (isAuthor || len(ownChoices) > 0),
Voted: voted,
OwnVotes: ownChoices,
Options: options,
Emojis: emojis,
}, nil
}

Expand Down

0 comments on commit 42a19cf

Please sign in to comment.