1
0
Fork 0

Add support for displaying polls

Doesn't look the prettiest, but it's there!
This commit is contained in:
Ryan Fox 2021-03-06 23:20:53 +00:00
parent a0b3970747
commit 6fc967c05a
Signed by: flewkey
GPG Key ID: 94F56ADFD848851E
4 changed files with 132 additions and 0 deletions

View File

@ -417,6 +417,40 @@ form.search {
width: 100%;
}
/* Polls */
.poll {
font-size: 14px;
margin: 0 0 10px;
}
.poll ul {
padding-left: 0;
}
.poll li {
padding: 4px 0 4px;
}
.poll .poll-percentage {
display: inline-block;
width: 32px;
}
.poll .poll-bar {
display: block;
width: 100%;
height: 6px;
border-radius: 3px;
background-color: #9baec8;
}
.poll .poll-footer {
color: #aaa;
display: block;
padding: 10px 0 0;
}
/* Spoiler */
.spoiled input[type=checkbox] {

View File

@ -21,6 +21,9 @@ module Mastodon.Decoder
, searchResultsDecoder
, statusDecoder
, webSocketEventDecoder
, pollIdDecoder
, pollOptionDecoder
, pollDecoder
)
import Json.Decode as Decode
@ -253,6 +256,28 @@ idDecoder =
]
pollIdDecoder : Decode.Decoder PollId
pollIdDecoder =
idDecoder |> Decode.map PollId
pollOptionDecoder : Decode.Decoder PollOption
pollOptionDecoder =
Pipe.decode PollOption
|> Pipe.required "title" Decode.string
|> Pipe.required "votes_count" Decode.int
pollDecoder : Decode.Decoder Poll
pollDecoder =
Pipe.decode Poll
|> Pipe.required "id" pollIdDecoder
|> Pipe.required "expired" Decode.bool
|> Pipe.required "voted" Decode.bool
|> Pipe.required "votes_count" Decode.int
|> Pipe.required "options" (Decode.list pollOptionDecoder)
statusIdDecoder : Decode.Decoder StatusId
statusIdDecoder =
idDecoder |> Decode.map StatusId
@ -281,6 +306,13 @@ statusDecoder =
|> Pipe.required "uri" Decode.string
|> Pipe.required "url" (Decode.nullable Decode.string)
|> Pipe.required "visibility" Decode.string
|> Pipe.optional "poll" pollDecoder
{ id = PollId("")
, expired = False
, votes_count = -1
, voted = False
, options = []
}
|> Pipe.optional "pinned" Decode.bool False -- Not a real value, used to show pinned indicator

View File

@ -20,6 +20,9 @@ module Mastodon.Model
, Reblog(..)
, Relationship
, Tag
, PollId(..)
, PollOption
, Poll
, SearchResults
, Source
, Status
@ -239,6 +242,25 @@ type alias Hashtag =
}
type PollId
= PollId String
type alias PollOption =
{ title : String
, votes_count : Int
}
type alias Poll =
{ id : PollId
, expired : Bool
, voted : Bool
, votes_count : Int
, options : List PollOption
}
type alias SearchResults =
{ accounts : List Account
, statuses : List Status
@ -277,6 +299,7 @@ type alias Status =
, uri : String
, url : Maybe String
, visibility : String
, poll : Poll
, pinned : Bool -- Not a real value, used to show pinned indicator
}

View File

@ -86,6 +86,47 @@ attachmentListView context { media_attachments, sensitive } =
List.map (keyedEntry attachments) attachments
pollView : Status -> Html Msg
pollView status =
let
pollStatus poll =
if poll.voted then
text "Voted"
else if poll.expired then
text "Expired"
else
text "Not voted"
optionPercentage option =
100*option.votes_count//status.poll.votes_count
optionPercentageText option =
span [ class "poll-percentage" ]
[ text <| (toString (optionPercentage option))++"%"
]
optionBar option =
span
[ class "poll-bar"
, style [("width", toString (optionPercentage option)++"%")]
] []
optionEntry option =
li []
[ optionPercentageText option
, text option.title
, optionBar option
]
in
if status.poll.id == PollId("") then
text ""
else
div [ class "poll" ]
[ ul [] <|
List.map optionEntry status.poll.options
, span [ class "poll-footer" ]
[ text <| (toString status.poll.votes_count)++" votes"
, text " "
, pollStatus status.poll ]
]
statusActionsView : Status -> CurrentUser -> Bool -> Html Msg
statusActionsView status currentUser showApp =
let
@ -156,6 +197,7 @@ statusContentView context status =
"" ->
div [ class "status-text" ]
[ div [] <| formatContent status.content status.mentions
, pollView status
, attachmentListView context status
]
@ -172,6 +214,7 @@ statusContentView context status =
, label [ onClickWithStop NoOp, for statusId ] [ text "Reveal content" ]
, div [ class "spoiled-content" ]
[ div [] <| formatContent status.content status.mentions
, pollView status
, attachmentListView context status
]
]