Files
Scylla/src/Scylla/Sync.elm

261 lines
7.0 KiB
Elm
Raw Normal View History

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