Add support for displaying polls
Doesn't look the prettiest, but it's there!
This commit is contained in:
parent
a0b3970747
commit
6fc967c05a
@ -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] {
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
]
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user