checkpoint:
- BREAKING: user can no longer view a poll directly from the poll ID. - Added more poll details in status view. - Poll now shows the user's vote in status/timeline view.
This commit is contained in:
parent
a0eab3b6ae
commit
caa4341ef2
5 changed files with 75 additions and 120 deletions
|
@ -536,16 +536,7 @@ See [Create a status](#create-a-status).
|
||||||
|
|
||||||
### View a poll
|
### View a poll
|
||||||
|
|
||||||
Prints the poll information to the screen.
|
You can view a poll from a status or timeline.
|
||||||
|
|
||||||
```
|
|
||||||
enbas show --type poll --poll-id 01J0CEEZBZ6E6AYQSJPHCQYBDA
|
|
||||||
```
|
|
||||||
|
|
||||||
| flag | type | required | description | default |
|
|
||||||
|------|------|----------|-------------|---------|
|
|
||||||
| `type` | string | true | The resource you want to view.<br>Here this should be `poll`. | |
|
|
||||||
| `poll-id` | string | true | The ID of the poll that you want to view. | |
|
|
||||||
|
|
||||||
### Vote in a poll
|
### Vote in a poll
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ func (s *ShowExecutor) Execute() error {
|
||||||
resourceLiked: s.showLiked,
|
resourceLiked: s.showLiked,
|
||||||
resourceStarred: s.showLiked,
|
resourceStarred: s.showLiked,
|
||||||
resourceFollowRequest: s.showFollowRequests,
|
resourceFollowRequest: s.showFollowRequests,
|
||||||
resourcePoll: s.showPoll,
|
|
||||||
resourceMutedAccounts: s.showMutedAccounts,
|
resourceMutedAccounts: s.showMutedAccounts,
|
||||||
resourceMedia: s.showMedia,
|
resourceMedia: s.showMedia,
|
||||||
resourceMediaAttachment: s.showMediaAttachment,
|
resourceMediaAttachment: s.showMediaAttachment,
|
||||||
|
@ -372,21 +371,6 @@ func (s *ShowExecutor) showFollowRequests(gtsClient *client.Client) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ShowExecutor) showPoll(gtsClient *client.Client) error {
|
|
||||||
if s.pollID == "" {
|
|
||||||
return FlagNotSetError{flagText: flagPollID}
|
|
||||||
}
|
|
||||||
|
|
||||||
poll, err := gtsClient.GetPoll(s.pollID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to retrieve the poll: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.printer.PrintPoll(poll)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *ShowExecutor) showMutedAccounts(gtsClient *client.Client) error {
|
func (s *ShowExecutor) showMutedAccounts(gtsClient *client.Client) error {
|
||||||
muted, err := gtsClient.GetMutedAccounts(s.limit)
|
muted, err := gtsClient.GetMutedAccounts(s.limit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,91 +1,2 @@
|
||||||
package printer
|
package printer
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p Printer) PrintPoll(poll model.Poll) {
|
|
||||||
var builder strings.Builder
|
|
||||||
|
|
||||||
builder.WriteString("\n" + p.headerFormat("POLL ID:"))
|
|
||||||
builder.WriteString("\n" + poll.ID)
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("OPTIONS:"))
|
|
||||||
builder.WriteString(p.pollOptions(poll))
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("MULTIPLE CHOICES ALLOWED:"))
|
|
||||||
builder.WriteString("\n" + strconv.FormatBool(poll.Multiple))
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("YOU VOTED:"))
|
|
||||||
builder.WriteString("\n" + strconv.FormatBool(poll.Voted))
|
|
||||||
|
|
||||||
if len(poll.OwnVotes) > 0 {
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("YOUR VOTES:"))
|
|
||||||
|
|
||||||
for _, vote := range poll.OwnVotes {
|
|
||||||
builder.WriteString("\n" + "[" + strconv.Itoa(vote) + "] " + poll.Options[vote].Title)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.headerFormat("EXPIRED:"))
|
|
||||||
builder.WriteString("\n" + strconv.FormatBool(poll.Expired))
|
|
||||||
builder.WriteString("\n\n")
|
|
||||||
|
|
||||||
p.print(builder.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Printer) pollOptions(poll model.Poll) string {
|
|
||||||
var builder strings.Builder
|
|
||||||
|
|
||||||
for ind, option := range poll.Options {
|
|
||||||
var (
|
|
||||||
votage float64
|
|
||||||
percentage int
|
|
||||||
)
|
|
||||||
|
|
||||||
if poll.VotesCount == 0 {
|
|
||||||
percentage = 0
|
|
||||||
} else {
|
|
||||||
votage = float64(option.VotesCount) / float64(poll.VotesCount)
|
|
||||||
percentage = int(math.Floor(100 * votage))
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + "[" + strconv.Itoa(ind) + "] " + option.Title)
|
|
||||||
builder.WriteString(p.pollMeter(votage))
|
|
||||||
builder.WriteString("\n" + strconv.Itoa(option.VotesCount) + " votes " + "(" + strconv.Itoa(percentage) + "%)")
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.WriteString("\n\n" + p.fieldFormat("Total votes:") + " " + strconv.Itoa(poll.VotesCount))
|
|
||||||
builder.WriteString("\n" + p.fieldFormat("Poll ID:") + " " + poll.ID)
|
|
||||||
builder.WriteString("\n" + p.fieldFormat("Poll is open until:") + " " + p.formatDateTime(poll.ExpiredAt))
|
|
||||||
|
|
||||||
return builder.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Printer) pollMeter(votage float64) string {
|
|
||||||
numVoteBlocks := int(math.Floor(float64(p.lineWrapCharacterLimit) * votage))
|
|
||||||
numBackgroundBlocks := p.lineWrapCharacterLimit - numVoteBlocks
|
|
||||||
|
|
||||||
voteBlockColor := p.theme.boldgreen
|
|
||||||
backgroundBlockColor := p.theme.grey
|
|
||||||
|
|
||||||
if p.noColor {
|
|
||||||
voteBlockColor = p.theme.reset
|
|
||||||
|
|
||||||
if numVoteBlocks == 0 {
|
|
||||||
numVoteBlocks = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
meter := "\n" + voteBlockColor + strings.Repeat(symbolPollMeter, numVoteBlocks) + p.theme.reset
|
|
||||||
|
|
||||||
if !p.noColor {
|
|
||||||
meter += backgroundBlockColor + strings.Repeat(symbolPollMeter, numBackgroundBlocks) + p.theme.reset
|
|
||||||
}
|
|
||||||
|
|
||||||
return meter
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ const (
|
||||||
noMediaDescription = "This media attachment has no description."
|
noMediaDescription = "This media attachment has no description."
|
||||||
symbolBullet = "\u2022"
|
symbolBullet = "\u2022"
|
||||||
symbolPollMeter = "\u2501"
|
symbolPollMeter = "\u2501"
|
||||||
symbolSuccess = "\u2714"
|
symbolCheckMark = "\u2714"
|
||||||
symbolFailure = "\u2717"
|
symbolFailure = "\u2717"
|
||||||
symbolImage = "\uf03e"
|
symbolImage = "\uf03e"
|
||||||
symbolLiked = "\uf51f"
|
symbolLiked = "\uf51f"
|
||||||
|
@ -78,9 +78,9 @@ func NewPrinter(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Printer) PrintSuccess(text string) {
|
func (p Printer) PrintSuccess(text string) {
|
||||||
success := p.theme.boldgreen + symbolSuccess + p.theme.reset
|
success := p.theme.boldgreen + symbolCheckMark + p.theme.reset
|
||||||
if p.noColor {
|
if p.noColor {
|
||||||
success = symbolSuccess
|
success = symbolCheckMark
|
||||||
}
|
}
|
||||||
|
|
||||||
printToStdout(success + " " + text + "\n")
|
printToStdout(success + " " + text + "\n")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package printer
|
package printer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -41,7 +42,8 @@ func (p Printer) PrintStatus(status model.Status) {
|
||||||
|
|
||||||
// If a poll exists in a status, write the contents to the builder.
|
// If a poll exists in a status, write the contents to the builder.
|
||||||
if status.Poll != nil {
|
if status.Poll != nil {
|
||||||
builder.WriteString(p.pollOptions(*status.Poll))
|
builder.WriteString("\n\n" + p.headerFormat("POLL DETAILS:"))
|
||||||
|
builder.WriteString(p.pollDetails(*status.Poll))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status creation time
|
// Status creation time
|
||||||
|
@ -120,7 +122,7 @@ func (p Printer) statusList(list model.StatusList) string {
|
||||||
builder.WriteString("\n" + p.convertHTMLToText(content, true))
|
builder.WriteString("\n" + p.convertHTMLToText(content, true))
|
||||||
|
|
||||||
if poll != nil {
|
if poll != nil {
|
||||||
builder.WriteString(p.pollOptions(*poll))
|
builder.WriteString(p.pollDetails(*poll))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, media := range mediaAttachments {
|
for _, media := range mediaAttachments {
|
||||||
|
@ -172,3 +174,70 @@ func (p Printer) statusList(list model.StatusList) string {
|
||||||
|
|
||||||
return builder.String()
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p Printer) pollDetails(poll model.Poll) string {
|
||||||
|
var builder strings.Builder
|
||||||
|
|
||||||
|
for ind, option := range poll.Options {
|
||||||
|
var (
|
||||||
|
votage float64
|
||||||
|
percentage int
|
||||||
|
)
|
||||||
|
|
||||||
|
if poll.VotesCount == 0 {
|
||||||
|
percentage = 0
|
||||||
|
} else {
|
||||||
|
votage = float64(option.VotesCount) / float64(poll.VotesCount)
|
||||||
|
percentage = int(math.Floor(100 * votage))
|
||||||
|
}
|
||||||
|
|
||||||
|
optionTitle := "\n\n" + "[" + strconv.Itoa(ind) + "] " + option.Title
|
||||||
|
|
||||||
|
for _, vote := range poll.OwnVotes {
|
||||||
|
if ind == vote {
|
||||||
|
optionTitle += " " + symbolCheckMark
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString(optionTitle)
|
||||||
|
builder.WriteString(p.pollMeter(votage))
|
||||||
|
builder.WriteString("\n" + strconv.Itoa(option.VotesCount) + " votes " + "(" + strconv.Itoa(percentage) + "%)")
|
||||||
|
}
|
||||||
|
|
||||||
|
pollStatusField := "Poll is open until: "
|
||||||
|
if poll.Expired {
|
||||||
|
pollStatusField = "Poll was closed on: "
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString("\n\n" + p.fieldFormat(pollStatusField) + p.formatDateTime(poll.ExpiredAt))
|
||||||
|
builder.WriteString("\n" + p.fieldFormat("Total votes: ") + strconv.Itoa(poll.VotesCount))
|
||||||
|
builder.WriteString("\n" + p.fieldFormat("Multiple choices allowed: ") + strconv.FormatBool(poll.Multiple))
|
||||||
|
|
||||||
|
return builder.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Printer) pollMeter(votage float64) string {
|
||||||
|
numVoteBlocks := int(math.Floor(float64(p.lineWrapCharacterLimit) * votage))
|
||||||
|
numBackgroundBlocks := p.lineWrapCharacterLimit - numVoteBlocks
|
||||||
|
|
||||||
|
voteBlockColour := p.theme.boldgreen
|
||||||
|
backgroundBlockColor := p.theme.grey
|
||||||
|
|
||||||
|
if p.noColor {
|
||||||
|
voteBlockColour = p.theme.reset
|
||||||
|
|
||||||
|
if numVoteBlocks == 0 {
|
||||||
|
numVoteBlocks = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
meter := "\n" + voteBlockColour + strings.Repeat(symbolPollMeter, numVoteBlocks) + p.theme.reset
|
||||||
|
|
||||||
|
if !p.noColor {
|
||||||
|
meter += backgroundBlockColor + strings.Repeat(symbolPollMeter, numBackgroundBlocks) + p.theme.reset
|
||||||
|
}
|
||||||
|
|
||||||
|
return meter
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue