2018-12-08 00:50:31 -08:00
|
|
|
module Scylla.Sync exposing (..)
|
2018-12-08 13:49:30 -08:00
|
|
|
import Scylla.Api exposing (..)
|
2018-12-08 00:50:31 -08:00
|
|
|
import Dict exposing (Dict)
|
|
|
|
|
import Json.Decode as Decode exposing (Decoder, int, string, float, list, value, dict, bool)
|
|
|
|
|
import Json.Decode.Pipeline exposing (required, optional)
|
|
|
|
|
|
2018-12-08 13:49:30 -08:00
|
|
|
-- Special Decoding
|
2018-12-08 01:21:53 -08:00
|
|
|
decodeJust : Decoder a -> Decoder (Maybe a)
|
|
|
|
|
decodeJust = Decode.map Just
|
|
|
|
|
|
|
|
|
|
maybeDecode : String -> Decoder a -> Decoder (Maybe a -> b) -> Decoder b
|
|
|
|
|
maybeDecode s d = optional s (decodeJust d) Nothing
|
|
|
|
|
|
2018-12-08 00:50:31 -08:00
|
|
|
-- General Events
|
|
|
|
|
type alias Event =
|
|
|
|
|
{ content : Decode.Value
|
|
|
|
|
, type_ : String
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eventDecoder : Decoder Event
|
|
|
|
|
eventDecoder =
|
|
|
|
|
Decode.succeed Event
|
|
|
|
|
|> required "content" value
|
|
|
|
|
|> required "type" string
|
|
|
|
|
|
|
|
|
|
type alias EventContent =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ avatarUrl : Maybe String
|
|
|
|
|
, displayname : Maybe String
|
2018-12-08 00:50:31 -08:00
|
|
|
, membership : String
|
2018-12-08 01:21:53 -08:00
|
|
|
, isDirect : Maybe Bool
|
2018-12-08 00:50:31 -08:00
|
|
|
-- , thirdPartyInvite : Invite
|
2018-12-08 01:21:53 -08:00
|
|
|
, unsigned : Maybe UnsignedData
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eventContentDecoder : Decoder EventContent
|
|
|
|
|
eventContentDecoder =
|
|
|
|
|
Decode.succeed EventContent
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "avatar_url" string
|
|
|
|
|
|> maybeDecode "displayname" string
|
2018-12-08 00:50:31 -08:00
|
|
|
|> required "membership" string
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "is_direct" bool
|
2018-12-08 00:50:31 -08:00
|
|
|
-- |> required "third_party_invite" inviteDecoder
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "unsigned" unsignedDataDecoder
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
-- Unsigned Data
|
|
|
|
|
type alias UnsignedData =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ age : Maybe Int
|
|
|
|
|
, redactedBecause : Maybe Event
|
|
|
|
|
, transactionId : Maybe String
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsignedDataDecoder : Decoder UnsignedData
|
|
|
|
|
unsignedDataDecoder =
|
|
|
|
|
Decode.succeed UnsignedData
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "age" int
|
|
|
|
|
|> maybeDecode "redacted_because" eventDecoder
|
|
|
|
|
|> maybeDecode "transaction_id" string
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
-- State
|
2018-12-08 01:21:53 -08:00
|
|
|
type alias State =
|
|
|
|
|
{ events : Maybe (List StateEvent)
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-08 00:50:31 -08:00
|
|
|
stateDecoder : Decoder State
|
|
|
|
|
stateDecoder =
|
|
|
|
|
Decode.succeed State
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "events" (list stateEventDecoder)
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
type alias StateEvent =
|
|
|
|
|
{ content : Decode.Value
|
|
|
|
|
, type_ : String
|
|
|
|
|
, eventId : String
|
|
|
|
|
, sender : String
|
|
|
|
|
, originServerTs : Int
|
2018-12-08 01:21:53 -08:00
|
|
|
, unsigned : Maybe UnsignedData
|
|
|
|
|
, prevContent : Maybe EventContent
|
2018-12-08 00:50:31 -08:00
|
|
|
, stateKey : String
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stateEventDecoder : Decoder StateEvent
|
|
|
|
|
stateEventDecoder =
|
|
|
|
|
Decode.succeed StateEvent
|
2018-12-08 17:15:35 -08:00
|
|
|
|> required "content" value
|
2018-12-08 00:50:31 -08:00
|
|
|
|> required "type" string
|
|
|
|
|
|> required "event_id" string
|
|
|
|
|
|> required "sender" string
|
|
|
|
|
|> required "origin_server_ts" int
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "unsigned" unsignedDataDecoder
|
|
|
|
|
|> maybeDecode "prev_content" eventContentDecoder
|
2018-12-08 17:15:35 -08:00
|
|
|
|> required "state_key" string
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
-- Rooms
|
|
|
|
|
type alias Rooms =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ join : Maybe (Dict String JoinedRoom)
|
|
|
|
|
, invite : Maybe (Dict String InvitedRoom)
|
|
|
|
|
, leave : Maybe (Dict String LeftRoom)
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
roomsDecoder : Decoder Rooms
|
|
|
|
|
roomsDecoder =
|
|
|
|
|
Decode.succeed Rooms
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "join" (dict joinedRoomDecoder)
|
|
|
|
|
|> maybeDecode "invite" (dict invitedRoomDecoder)
|
|
|
|
|
|> maybeDecode "leave" (dict leftRoomDecoder)
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
type alias JoinedRoom =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ state : Maybe State
|
|
|
|
|
, timeline : Maybe Timeline
|
|
|
|
|
, ephemeral : Maybe Ephemeral
|
|
|
|
|
, accountData : Maybe AccountData
|
|
|
|
|
, unreadNotifications : Maybe UnreadNotificationCounts
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
joinedRoomDecoder : Decoder JoinedRoom
|
|
|
|
|
joinedRoomDecoder =
|
|
|
|
|
Decode.succeed JoinedRoom
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "state" stateDecoder
|
|
|
|
|
|> maybeDecode "timeline" timelineDecoder
|
|
|
|
|
|> maybeDecode "ephemeral" ephemeralDecoder
|
|
|
|
|
|> maybeDecode "account_data" accountDataDecoder
|
|
|
|
|
|> maybeDecode "unread_notifications" unreadNotificationCountsDecoder
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Joined Room Data
|
|
|
|
|
type alias Timeline =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ events : Maybe (List RoomEvent)
|
|
|
|
|
, limited : Maybe Bool
|
|
|
|
|
, prevBatch : Maybe String
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timelineDecoder =
|
|
|
|
|
Decode.succeed Timeline
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "events" (list roomEventDecoder)
|
|
|
|
|
|> maybeDecode "limited" bool
|
|
|
|
|
|> maybeDecode "prev_batch" string
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
type alias RoomEvent =
|
|
|
|
|
{ content : Decode.Value
|
|
|
|
|
, type_ : String
|
|
|
|
|
, eventId : String
|
|
|
|
|
, sender : String
|
|
|
|
|
, originServerTs : Int
|
2018-12-08 01:21:53 -08:00
|
|
|
, unsigned : Maybe UnsignedData
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
roomEventDecoder : Decoder RoomEvent
|
|
|
|
|
roomEventDecoder =
|
|
|
|
|
Decode.succeed RoomEvent
|
|
|
|
|
|> required "content" value
|
|
|
|
|
|> required "type" string
|
|
|
|
|
|> required "event_id" string
|
|
|
|
|
|> required "sender" string
|
|
|
|
|
|> required "origin_server_ts" int
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "unsigned" unsignedDataDecoder
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
type alias Ephemeral =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ events : Maybe (List Event)
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ephemeralDecoder : Decoder Ephemeral
|
|
|
|
|
ephemeralDecoder =
|
|
|
|
|
Decode.succeed Ephemeral
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "events" (list eventDecoder)
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
type alias AccountData =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ events : Maybe (List Event)
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
accountDataDecoder : Decoder AccountData
|
|
|
|
|
accountDataDecoder =
|
|
|
|
|
Decode.succeed AccountData
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "events" (list eventDecoder)
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
type alias UnreadNotificationCounts =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ highlightCount : Maybe Int
|
|
|
|
|
, notificationCount : Maybe Int
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unreadNotificationCountsDecoder : Decoder UnreadNotificationCounts
|
|
|
|
|
unreadNotificationCountsDecoder =
|
|
|
|
|
Decode.succeed UnreadNotificationCounts
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "highlight_count" int
|
|
|
|
|
|> maybeDecode "notification_count" int
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
-- Invited Room Data
|
|
|
|
|
type alias InvitedRoom =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ inviteState : Maybe InviteState
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
invitedRoomDecoder : Decoder InvitedRoom
|
|
|
|
|
invitedRoomDecoder =
|
|
|
|
|
Decode.succeed InvitedRoom
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "invite_state" inviteStateDecoder
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
type alias InviteState =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ events : Maybe (List StrippedState)
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inviteStateDecoder : Decoder InviteState
|
|
|
|
|
inviteStateDecoder =
|
|
|
|
|
Decode.succeed InviteState
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "events" (list strippedStateDecoder)
|
2018-12-08 00:50:31 -08:00
|
|
|
|
|
|
|
|
type alias StrippedState =
|
|
|
|
|
{ content : EventContent
|
|
|
|
|
, stateKey : String
|
|
|
|
|
, type_ : String
|
|
|
|
|
, sender : String
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
strippedStateDecoder : Decoder StrippedState
|
|
|
|
|
strippedStateDecoder =
|
|
|
|
|
Decode.succeed StrippedState
|
|
|
|
|
|> required "content" eventContentDecoder
|
|
|
|
|
|> required "state_key" string
|
|
|
|
|
|> required "type" string
|
|
|
|
|
|> required "sender" string
|
|
|
|
|
|
|
|
|
|
-- Left Room Data
|
|
|
|
|
type alias LeftRoom =
|
2018-12-08 01:21:53 -08:00
|
|
|
{ state : Maybe State
|
|
|
|
|
, timeline : Maybe Timeline
|
|
|
|
|
, accountData : Maybe AccountData
|
2018-12-08 00:50:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
leftRoomDecoder : Decoder LeftRoom
|
|
|
|
|
leftRoomDecoder =
|
|
|
|
|
Decode.succeed LeftRoom
|
2018-12-08 01:21:53 -08:00
|
|
|
|> maybeDecode "state" stateDecoder
|
|
|
|
|
|> maybeDecode "timeline" timelineDecoder
|
|
|
|
|
|> maybeDecode "account_data" accountDataDecoder
|
2018-12-08 13:49:30 -08:00
|
|
|
|
|
|
|
|
-- General Sync Response
|
|
|
|
|
type alias SyncResponse =
|
|
|
|
|
{ nextBatch : String
|
|
|
|
|
, rooms : Maybe Rooms
|
|
|
|
|
, presence : Maybe Presence
|
|
|
|
|
, accountData : Maybe AccountData
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
syncResponseDecoder : Decoder SyncResponse
|
|
|
|
|
syncResponseDecoder =
|
|
|
|
|
Decode.succeed SyncResponse
|
|
|
|
|
|> required "next_batch" string
|
|
|
|
|
|> maybeDecode "rooms" roomsDecoder
|
|
|
|
|
|> maybeDecode "presence" presenceDecoder
|
|
|
|
|
|> maybeDecode "account_data" accountDataDecoder
|
|
|
|
|
|
|
|
|
|
type alias Presence =
|
|
|
|
|
{ events : Maybe (List Event)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
presenceDecoder : Decoder Presence
|
|
|
|
|
presenceDecoder =
|
|
|
|
|
Decode.succeed Presence
|
|
|
|
|
|> maybeDecode "events" (list eventDecoder)
|
2018-12-08 17:15:35 -08:00
|
|
|
|
|
|
|
|
-- Business Logic
|
|
|
|
|
mergeSyncResponse : SyncResponse -> SyncResponse -> SyncResponse
|
|
|
|
|
mergeSyncResponse l r = r
|