|
|
|
@ -6,6 +6,7 @@ module Mastodon.Decoder
|
|
|
|
|
, attachmentDecoder
|
|
|
|
|
, contextDecoder
|
|
|
|
|
, decodeWebSocketMessage
|
|
|
|
|
, decodeClients
|
|
|
|
|
, mastodonErrorDecoder
|
|
|
|
|
, mentionDecoder
|
|
|
|
|
, notificationDecoder
|
|
|
|
@ -14,7 +15,6 @@ module Mastodon.Decoder
|
|
|
|
|
, relationshipDecoder
|
|
|
|
|
, searchResultsDecoder
|
|
|
|
|
, statusDecoder
|
|
|
|
|
, webSocketPayloadDecoder
|
|
|
|
|
, webSocketEventDecoder
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
@ -31,7 +31,7 @@ appRegistrationDecoder server scope =
|
|
|
|
|
|> Pipe.hardcoded scope
|
|
|
|
|
|> Pipe.required "client_id" Decode.string
|
|
|
|
|
|> Pipe.required "client_secret" Decode.string
|
|
|
|
|
|> Pipe.required "id" Decode.int
|
|
|
|
|
|> Pipe.required "id" idDecoder
|
|
|
|
|
|> Pipe.required "redirect_uri" Decode.string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -52,7 +52,7 @@ accountDecoder =
|
|
|
|
|
|> Pipe.required "followers_count" Decode.int
|
|
|
|
|
|> Pipe.required "following_count" Decode.int
|
|
|
|
|
|> Pipe.required "header" Decode.string
|
|
|
|
|
|> Pipe.required "id" Decode.int
|
|
|
|
|
|> Pipe.required "id" idDecoder
|
|
|
|
|
|> Pipe.required "locked" Decode.bool
|
|
|
|
|
|> Pipe.required "note" Decode.string
|
|
|
|
|
|> Pipe.required "statuses_count" Decode.int
|
|
|
|
@ -70,7 +70,7 @@ applicationDecoder =
|
|
|
|
|
attachmentDecoder : Decode.Decoder Attachment
|
|
|
|
|
attachmentDecoder =
|
|
|
|
|
Pipe.decode Attachment
|
|
|
|
|
|> Pipe.required "id" Decode.int
|
|
|
|
|
|> Pipe.required "id" idDecoder
|
|
|
|
|
|> Pipe.required "type" Decode.string
|
|
|
|
|
|> Pipe.required "url" Decode.string
|
|
|
|
|
|> Pipe.optional "remote_url" Decode.string ""
|
|
|
|
@ -85,6 +85,19 @@ contextDecoder =
|
|
|
|
|
|> Pipe.required "descendants" (Decode.list statusDecoder)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
clientDecoder : Decode.Decoder Client
|
|
|
|
|
clientDecoder =
|
|
|
|
|
Pipe.decode Client
|
|
|
|
|
|> Pipe.required "server" Decode.string
|
|
|
|
|
|> Pipe.required "token" Decode.string
|
|
|
|
|
|> Pipe.required "account" (Decode.maybe accountDecoder)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
decodeClients : String -> Result String (List Client)
|
|
|
|
|
decodeClients json =
|
|
|
|
|
Decode.decodeString (Decode.list clientDecoder) json
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mastodonErrorDecoder : Decode.Decoder String
|
|
|
|
|
mastodonErrorDecoder =
|
|
|
|
|
Decode.field "error" Decode.string
|
|
|
|
@ -93,7 +106,7 @@ mastodonErrorDecoder =
|
|
|
|
|
mentionDecoder : Decode.Decoder Mention
|
|
|
|
|
mentionDecoder =
|
|
|
|
|
Pipe.decode Mention
|
|
|
|
|
|> Pipe.required "id" Decode.int
|
|
|
|
|
|> Pipe.required "id" idDecoder
|
|
|
|
|
|> Pipe.required "url" Decode.string
|
|
|
|
|
|> Pipe.required "username" Decode.string
|
|
|
|
|
|> Pipe.required "acct" Decode.string
|
|
|
|
@ -102,7 +115,7 @@ mentionDecoder =
|
|
|
|
|
notificationDecoder : Decode.Decoder Notification
|
|
|
|
|
notificationDecoder =
|
|
|
|
|
Pipe.decode Notification
|
|
|
|
|
|> Pipe.required "id" Decode.int
|
|
|
|
|
|> Pipe.required "id" idDecoder
|
|
|
|
|
|> Pipe.required "type" Decode.string
|
|
|
|
|
|> Pipe.required "created_at" Decode.string
|
|
|
|
|
|> Pipe.required "account" accountDecoder
|
|
|
|
@ -112,7 +125,7 @@ notificationDecoder =
|
|
|
|
|
relationshipDecoder : Decode.Decoder Relationship
|
|
|
|
|
relationshipDecoder =
|
|
|
|
|
Pipe.decode Relationship
|
|
|
|
|
|> Pipe.required "id" Decode.int
|
|
|
|
|
|> Pipe.required "id" idDecoder
|
|
|
|
|
|> Pipe.required "blocking" Decode.bool
|
|
|
|
|
|> Pipe.required "followed_by" Decode.bool
|
|
|
|
|
|> Pipe.required "following" Decode.bool
|
|
|
|
@ -140,6 +153,21 @@ searchResultsDecoder =
|
|
|
|
|
|> Pipe.required "hashtags" (Decode.list Decode.string)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
idDecoder : Decode.Decoder String
|
|
|
|
|
idDecoder =
|
|
|
|
|
-- Note: since v2.0.0 of the Mastodon API, ids are treated as strings, so we
|
|
|
|
|
-- treat all ids as strings.
|
|
|
|
|
Decode.oneOf
|
|
|
|
|
[ Decode.string
|
|
|
|
|
, Decode.int |> Decode.map toString
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
statusIdDecoder : Decode.Decoder StatusId
|
|
|
|
|
statusIdDecoder =
|
|
|
|
|
idDecoder |> Decode.map StatusId
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
statusDecoder : Decode.Decoder Status
|
|
|
|
|
statusDecoder =
|
|
|
|
|
Pipe.decode Status
|
|
|
|
@ -149,9 +177,9 @@ statusDecoder =
|
|
|
|
|
|> Pipe.required "created_at" Decode.string
|
|
|
|
|
|> Pipe.optional "favourited" (Decode.nullable Decode.bool) Nothing
|
|
|
|
|
|> Pipe.required "favourites_count" Decode.int
|
|
|
|
|
|> Pipe.required "id" Decode.int
|
|
|
|
|
|> Pipe.required "in_reply_to_account_id" (Decode.nullable Decode.int)
|
|
|
|
|
|> Pipe.required "in_reply_to_id" (Decode.nullable Decode.int)
|
|
|
|
|
|> Pipe.required "id" statusIdDecoder
|
|
|
|
|
|> Pipe.required "in_reply_to_account_id" (Decode.nullable idDecoder)
|
|
|
|
|
|> Pipe.required "in_reply_to_id" (Decode.nullable statusIdDecoder)
|
|
|
|
|
|> Pipe.required "media_attachments" (Decode.list attachmentDecoder)
|
|
|
|
|
|> Pipe.required "mentions" (Decode.list mentionDecoder)
|
|
|
|
|
|> Pipe.optional "reblog" (Decode.lazy (\_ -> Decode.nullable reblogDecoder)) Nothing
|
|
|
|
@ -165,49 +193,34 @@ statusDecoder =
|
|
|
|
|
|> Pipe.required "visibility" Decode.string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
webSocketPayloadDecoder : Decode.Decoder WebSocketPayload
|
|
|
|
|
webSocketPayloadDecoder =
|
|
|
|
|
Decode.oneOf
|
|
|
|
|
[ Decode.map StringPayload Decode.string
|
|
|
|
|
, Decode.map IntPayload Decode.int
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
webSocketEventDecoder : Decode.Decoder WebSocketMessage
|
|
|
|
|
webSocketEventDecoder =
|
|
|
|
|
Pipe.decode WebSocketMessage
|
|
|
|
|
|> Pipe.required "event" Decode.string
|
|
|
|
|
|> Pipe.required "payload" webSocketPayloadDecoder
|
|
|
|
|
|> Pipe.required "payload"
|
|
|
|
|
-- NOTE: as of the Mastodon API v2.0.0, ids may be either ints or
|
|
|
|
|
-- strings. If we receive an int (most likely for the delete event),
|
|
|
|
|
-- we cast it to a string.
|
|
|
|
|
(Decode.oneOf
|
|
|
|
|
[ Decode.string
|
|
|
|
|
, Decode.int |> Decode.map toString
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
decodeWebSocketMessage : String -> WebSocketEvent
|
|
|
|
|
decodeWebSocketMessage message =
|
|
|
|
|
case (Decode.decodeString webSocketEventDecoder message) of
|
|
|
|
|
Ok message ->
|
|
|
|
|
case message.event of
|
|
|
|
|
Ok { event, payload } ->
|
|
|
|
|
case event of
|
|
|
|
|
"update" ->
|
|
|
|
|
case message.payload of
|
|
|
|
|
StringPayload payload ->
|
|
|
|
|
StatusUpdateEvent (Decode.decodeString statusDecoder payload)
|
|
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
|
ErrorEvent "WS status update event payload must be a string"
|
|
|
|
|
StatusUpdateEvent (Decode.decodeString statusDecoder payload)
|
|
|
|
|
|
|
|
|
|
"delete" ->
|
|
|
|
|
case message.payload of
|
|
|
|
|
IntPayload payload ->
|
|
|
|
|
StatusDeleteEvent <| Ok payload
|
|
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
|
ErrorEvent "WS status delete event payload must be an int"
|
|
|
|
|
StatusDeleteEvent (StatusId payload)
|
|
|
|
|
|
|
|
|
|
"notification" ->
|
|
|
|
|
case message.payload of
|
|
|
|
|
StringPayload payload ->
|
|
|
|
|
NotificationEvent (Decode.decodeString notificationDecoder payload)
|
|
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
|
ErrorEvent "WS notification event payload must be an string"
|
|
|
|
|
NotificationEvent (Decode.decodeString notificationDecoder payload)
|
|
|
|
|
|
|
|
|
|
event ->
|
|
|
|
|
ErrorEvent <| "Unknown WS event " ++ event
|
|
|
|
|