Refactor Sync endpoint
parent
a0f19a3fdc
commit
eaa7bc3444
|
@ -1,9 +1,10 @@
|
|||
module Internal.Api.Sync.Api exposing (..)
|
||||
|
||||
import Internal.Api.Request as R
|
||||
import Internal.Api.Sync.V1.SpecObjects as SO1
|
||||
import Internal.Api.Sync.V2.SpecObjects as SO2
|
||||
import Internal.Tools.Exceptions as X
|
||||
import Internal.Tools.SpecEnums as Enums
|
||||
import Json.Decode as D
|
||||
import Task exposing (Task)
|
||||
|
||||
|
||||
|
@ -18,8 +19,15 @@ type alias SyncInputV1 =
|
|||
}
|
||||
|
||||
|
||||
syncV1 : D.Decoder a -> (a -> b) -> SyncInputV1 -> Task X.Error b
|
||||
syncV1 decoder mapping data =
|
||||
type alias SyncOutputV1 =
|
||||
Task X.Error SO1.Sync
|
||||
|
||||
type alias SyncOutputV2 =
|
||||
Task X.Error SO2.Sync
|
||||
|
||||
|
||||
syncV1 : SyncInputV1 -> SyncOutputV1
|
||||
syncV1 data =
|
||||
R.rawApiCall
|
||||
{ headers = R.WithAccessToken data.accessToken
|
||||
, method = "GET"
|
||||
|
@ -38,5 +46,29 @@ syncV1 decoder mapping data =
|
|||
data.timeout
|
||||
|> Maybe.map ((+) 10000)
|
||||
|> Maybe.map toFloat
|
||||
, decoder = \_ -> D.map mapping decoder
|
||||
, decoder = \_ -> SO1.syncDecoder
|
||||
}
|
||||
|
||||
|
||||
syncV2 : SyncInputV1 -> SyncOutputV2
|
||||
syncV2 data =
|
||||
R.rawApiCall
|
||||
{ headers = R.WithAccessToken data.accessToken
|
||||
, method = "GET"
|
||||
, baseUrl = data.baseUrl
|
||||
, path = "/_matrix/client/v3/sync"
|
||||
, pathParams = []
|
||||
, queryParams =
|
||||
[ R.OpQueryParamString "filter" data.filter
|
||||
, R.OpQueryParamBool "full_state" data.fullState
|
||||
, R.OpQueryParamString "set_presence" (Maybe.map Enums.fromUserPresence data.setPresence)
|
||||
, R.OpQueryParamString "since" data.since
|
||||
, R.OpQueryParamInt "timeout" data.timeout
|
||||
]
|
||||
, bodyParams = []
|
||||
, timeout =
|
||||
data.timeout
|
||||
|> Maybe.map ((+) 10000)
|
||||
|> Maybe.map toFloat
|
||||
, decoder = \_ -> SO2.syncDecoder
|
||||
}
|
||||
|
|
|
@ -1,23 +1,26 @@
|
|||
module Internal.Api.Sync.Main exposing (..)
|
||||
|
||||
import Internal.Api.Sync.Api as Api
|
||||
import Internal.Api.Sync.V1_2.Api as V1_2
|
||||
import Internal.Api.Sync.V1_3.Api as V1_3
|
||||
import Internal.Api.Sync.V1_4.Api as V1_4
|
||||
import Internal.Api.Sync.V1_5.Api as V1_5
|
||||
import Internal.Api.Sync.V1_5.Objects as O
|
||||
import Internal.Api.VersionControl as V
|
||||
import Internal.Tools.Exceptions as X
|
||||
import Task exposing (Task)
|
||||
import Internal.Api.Sync.V2.Upcast as U2
|
||||
import Internal.Tools.VersionControl as VC
|
||||
import Task
|
||||
|
||||
|
||||
sync : List String -> SyncInput -> SyncOutput
|
||||
sync =
|
||||
V.firstVersion V1_2.packet
|
||||
|> V.updateWith V1_3.packet
|
||||
|> V.updateWith V1_4.packet
|
||||
|> V.updateWith V1_5.packet
|
||||
|> V.toFunction
|
||||
sync : List String -> Maybe (SyncInput -> SyncOutput)
|
||||
sync versions =
|
||||
VC.withBottomLayer
|
||||
{ current = Api.syncV1
|
||||
, version = "v1.2"
|
||||
}
|
||||
|> VC.sameForVersion "v1.3"
|
||||
|> VC.addMiddleLayer
|
||||
{ current = Api.syncV2
|
||||
, downcast = identity
|
||||
, upcast = Task.map U2.upcastSync
|
||||
, version = "v1.4"
|
||||
}
|
||||
|> VC.sameForVersion "v1.5"
|
||||
|> VC.mostRecentFromVersionList versions
|
||||
|
||||
|
||||
type alias SyncInput =
|
||||
|
@ -25,4 +28,4 @@ type alias SyncInput =
|
|||
|
||||
|
||||
type alias SyncOutput =
|
||||
Task X.Error O.Sync
|
||||
Api.SyncOutputV2
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module Internal.Api.Sync.V1_2.SpecObjects exposing
|
||||
module Internal.Api.Sync.V1.SpecObjects exposing
|
||||
( AccountData
|
||||
, ClientEventWithoutRoomId
|
||||
, Ephemeral
|
||||
|
@ -60,7 +60,7 @@ module Internal.Api.Sync.V1_2.SpecObjects exposing
|
|||
|
||||
{-| Automatically generated 'SpecObjects'
|
||||
|
||||
Last generated at Unix time 1673279712
|
||||
Last generated at Unix time 1676625734
|
||||
|
||||
-}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
version: v1.2
|
||||
version: v1
|
||||
name: SpecObjects
|
||||
objects:
|
||||
Sync:
|
|
@ -1,17 +0,0 @@
|
|||
module Internal.Api.Sync.V1_2.Api exposing (..)
|
||||
|
||||
import Internal.Api.Sync.Api as Api
|
||||
import Internal.Api.Sync.V1_2.Convert as C
|
||||
import Internal.Api.Sync.V1_2.Objects as O
|
||||
import Internal.Api.Sync.V1_2.SpecObjects as SO
|
||||
import Internal.Api.Sync.V1_2.Upcast as U
|
||||
import Internal.Api.VersionControl as V
|
||||
|
||||
|
||||
packet : V.SingleVersion () () Api.SyncInputV1 O.Sync
|
||||
packet =
|
||||
{ version = "v1.2"
|
||||
, downcast = \_ -> ()
|
||||
, current = Api.syncV1 SO.syncDecoder C.convert
|
||||
, upcast = U.upcast
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
module Internal.Api.Sync.V1_2.Convert exposing (..)
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Sync.V1_2.Objects as O
|
||||
import Internal.Api.Sync.V1_2.SpecObjects as SO
|
||||
|
||||
|
||||
convert : SO.Sync -> O.Sync
|
||||
convert sync =
|
||||
{ accountData = convertEventHolder sync.accountData
|
||||
, nextBatch = sync.nextBatch
|
||||
, presence = convertEventHolder sync.presence
|
||||
, rooms = Maybe.map convertRooms sync.rooms
|
||||
}
|
||||
|
||||
|
||||
convertEventHolder : Maybe { a | events : List b } -> List b
|
||||
convertEventHolder =
|
||||
Maybe.map .events >> Maybe.withDefault []
|
||||
|
||||
|
||||
convertRooms : SO.Rooms -> O.Rooms
|
||||
convertRooms rooms =
|
||||
{ invite =
|
||||
Dict.map
|
||||
(\_ -> .inviteState >> Maybe.map .events >> Maybe.withDefault [])
|
||||
rooms.invite
|
||||
, join = Dict.map (\_ -> convertJoinedRoom) rooms.join
|
||||
, knock =
|
||||
Dict.map
|
||||
(\_ -> .knockState >> Maybe.map .events >> Maybe.withDefault [])
|
||||
rooms.knock
|
||||
, leave = Dict.map (\_ -> convertLeftRoom) rooms.leave
|
||||
}
|
||||
|
||||
|
||||
convertJoinedRoom : SO.JoinedRoom -> O.JoinedRoom
|
||||
convertJoinedRoom room =
|
||||
{ accountData = convertEventHolder room.accountData
|
||||
, ephemeral = convertEventHolder room.ephemeral
|
||||
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
|
||||
, summary = room.summary
|
||||
, timeline = Maybe.map convertTimeline room.timeline
|
||||
, unreadNotifications = room.unreadNotifications
|
||||
}
|
||||
|
||||
|
||||
convertClientEventWithoutRoomId : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
|
||||
convertClientEventWithoutRoomId event =
|
||||
{ content = event.content
|
||||
, eventId = event.eventId
|
||||
, originServerTs = event.originServerTs
|
||||
, sender = event.sender
|
||||
, stateKey = event.stateKey
|
||||
, contentType = event.contentType
|
||||
, unsigned = Maybe.map convertUnsigned event.unsigned
|
||||
}
|
||||
|
||||
|
||||
convertUnsigned : SO.UnsignedData -> O.UnsignedData
|
||||
convertUnsigned (SO.UnsignedData data) =
|
||||
O.UnsignedData
|
||||
{ age = data.age
|
||||
, prevContent = data.prevContent
|
||||
, redactedBecause = Maybe.map convertClientEventWithoutRoomId data.redactedBecause
|
||||
, transactionId = data.transactionId
|
||||
}
|
||||
|
||||
|
||||
convertTimeline : SO.Timeline -> O.Timeline
|
||||
convertTimeline timeline =
|
||||
{ events = List.map convertClientEventWithoutRoomId timeline.events
|
||||
, limited = timeline.limited
|
||||
, prevBatch = timeline.prevBatch
|
||||
}
|
||||
|
||||
|
||||
convertLeftRoom : SO.LeftRoom -> O.LeftRoom
|
||||
convertLeftRoom room =
|
||||
{ accountData = convertEventHolder room.accountData
|
||||
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
|
||||
, timeline = Maybe.map convertTimeline room.timeline
|
||||
}
|
|
@ -1,395 +0,0 @@
|
|||
module Internal.Api.Sync.V1_2.Objects exposing
|
||||
( BlindEvent
|
||||
, ClientEventWithoutRoomId
|
||||
, JoinedRoom
|
||||
, LeftRoom
|
||||
, RoomSummary
|
||||
, Rooms
|
||||
, StrippedStateEvent
|
||||
, Sync
|
||||
, Timeline
|
||||
, UnreadNotificationCounts
|
||||
, UnsignedData(..)
|
||||
, blindEventDecoder
|
||||
, clientEventWithoutRoomIdDecoder
|
||||
, encodeBlindEvent
|
||||
, encodeClientEventWithoutRoomId
|
||||
, encodeJoinedRoom
|
||||
, encodeLeftRoom
|
||||
, encodeRoomSummary
|
||||
, encodeRooms
|
||||
, encodeStrippedStateEvent
|
||||
, encodeSync
|
||||
, encodeTimeline
|
||||
, encodeUnreadNotificationCounts
|
||||
, encodeUnsignedData
|
||||
, joinedRoomDecoder
|
||||
, leftRoomDecoder
|
||||
, roomSummaryDecoder
|
||||
, roomsDecoder
|
||||
, strippedStateEventDecoder
|
||||
, syncDecoder
|
||||
, timelineDecoder
|
||||
, unreadNotificationCountsDecoder
|
||||
, unsignedDataDecoder
|
||||
)
|
||||
|
||||
{-| Automatically generated 'Objects'
|
||||
|
||||
Last generated at Unix time 1673279712
|
||||
|
||||
-}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
|
||||
import Internal.Tools.EncodeExtra exposing (maybeObject)
|
||||
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
{-| A blind event that does not give context about itself.
|
||||
-}
|
||||
type alias BlindEvent =
|
||||
{ content : E.Value
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeBlindEvent : BlindEvent -> E.Value
|
||||
encodeBlindEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
blindEventDecoder : D.Decoder BlindEvent
|
||||
blindEventDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ content = a, contentType = b }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| Client event that has all data except the room id.
|
||||
-}
|
||||
type alias ClientEventWithoutRoomId =
|
||||
{ content : E.Value
|
||||
, eventId : String
|
||||
, originServerTs : Timestamp
|
||||
, sender : String
|
||||
, stateKey : Maybe String
|
||||
, contentType : String
|
||||
, unsigned : Maybe UnsignedData
|
||||
}
|
||||
|
||||
|
||||
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
|
||||
encodeClientEventWithoutRoomId data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "event_id", Just <| E.string data.eventId )
|
||||
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Maybe.map E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
|
||||
]
|
||||
|
||||
|
||||
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
|
||||
clientEventWithoutRoomIdDecoder =
|
||||
D.map7
|
||||
(\a b c d e f g ->
|
||||
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "event_id" D.string)
|
||||
(D.field "origin_server_ts" timestampDecoder)
|
||||
(D.field "sender" D.string)
|
||||
(opField "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
|
||||
|
||||
|
||||
{-| Room that the user has joined.
|
||||
-}
|
||||
type alias JoinedRoom =
|
||||
{ accountData : List BlindEvent
|
||||
, ephemeral : List BlindEvent
|
||||
, state : List ClientEventWithoutRoomId
|
||||
, summary : Maybe RoomSummary
|
||||
, timeline : Maybe Timeline
|
||||
, unreadNotifications : Maybe UnreadNotificationCounts
|
||||
}
|
||||
|
||||
|
||||
encodeJoinedRoom : JoinedRoom -> E.Value
|
||||
encodeJoinedRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "ephemeral", Just <| E.list encodeBlindEvent data.ephemeral )
|
||||
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
|
||||
, ( "summary", Maybe.map encodeRoomSummary data.summary )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
|
||||
]
|
||||
|
||||
|
||||
joinedRoomDecoder : D.Decoder JoinedRoom
|
||||
joinedRoomDecoder =
|
||||
D.map6
|
||||
(\a b c d e f ->
|
||||
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "ephemeral" (D.list blindEventDecoder))
|
||||
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opField "summary" roomSummaryDecoder)
|
||||
(opField "timeline" timelineDecoder)
|
||||
(opField "unread_notifications" unreadNotificationCountsDecoder)
|
||||
|
||||
|
||||
{-| Room that the user has left.
|
||||
-}
|
||||
type alias LeftRoom =
|
||||
{ accountData : List BlindEvent
|
||||
, state : List ClientEventWithoutRoomId
|
||||
, timeline : Maybe Timeline
|
||||
}
|
||||
|
||||
|
||||
encodeLeftRoom : LeftRoom -> E.Value
|
||||
encodeLeftRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
]
|
||||
|
||||
|
||||
leftRoomDecoder : D.Decoder LeftRoom
|
||||
leftRoomDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ accountData = a, state = b, timeline = c }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opField "timeline" timelineDecoder)
|
||||
|
||||
|
||||
{-| Updates to rooms.
|
||||
-}
|
||||
type alias Rooms =
|
||||
{ invite : Dict String (List StrippedStateEvent)
|
||||
, join : Dict String JoinedRoom
|
||||
, knock : Dict String (List StrippedStateEvent)
|
||||
, leave : Dict String LeftRoom
|
||||
}
|
||||
|
||||
|
||||
encodeRooms : Rooms -> E.Value
|
||||
encodeRooms data =
|
||||
maybeObject
|
||||
[ ( "invite", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.invite )
|
||||
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
|
||||
, ( "knock", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.knock )
|
||||
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
|
||||
]
|
||||
|
||||
|
||||
roomsDecoder : D.Decoder Rooms
|
||||
roomsDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ invite = a, join = b, knock = c, leave = d }
|
||||
)
|
||||
(opFieldWithDefault "invite" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
|
||||
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
|
||||
(opFieldWithDefault "knock" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
|
||||
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
|
||||
|
||||
|
||||
{-| Information about a room which clients may need to correctly render it to users.
|
||||
-}
|
||||
type alias RoomSummary =
|
||||
{ mHeroes : Maybe (List String)
|
||||
, mInvitedMemberCount : Maybe Int
|
||||
, mJoinedMemberCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeRoomSummary : RoomSummary -> E.Value
|
||||
encodeRoomSummary data =
|
||||
maybeObject
|
||||
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
|
||||
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
|
||||
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
|
||||
]
|
||||
|
||||
|
||||
roomSummaryDecoder : D.Decoder RoomSummary
|
||||
roomSummaryDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
|
||||
)
|
||||
(opField "m.heroes" (D.list D.string))
|
||||
(opField "m.invited_member_count" D.int)
|
||||
(opField "m.joined_member_count" D.int)
|
||||
|
||||
|
||||
{-| Stripped state events of a room that the user has limited access to.
|
||||
-}
|
||||
type alias StrippedStateEvent =
|
||||
{ content : E.Value
|
||||
, sender : String
|
||||
, stateKey : String
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
|
||||
encodeStrippedStateEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Just <| E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
strippedStateEventDecoder : D.Decoder StrippedStateEvent
|
||||
strippedStateEventDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ content = a, sender = b, stateKey = c, contentType = d }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "sender" D.string)
|
||||
(D.field "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| The sync response the homeserver sends to the user.
|
||||
-}
|
||||
type alias Sync =
|
||||
{ accountData : List BlindEvent
|
||||
, nextBatch : String
|
||||
, presence : List BlindEvent
|
||||
, rooms : Maybe Rooms
|
||||
}
|
||||
|
||||
|
||||
encodeSync : Sync -> E.Value
|
||||
encodeSync data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "next_batch", Just <| E.string data.nextBatch )
|
||||
, ( "presence", Just <| E.list encodeBlindEvent data.presence )
|
||||
, ( "rooms", Maybe.map encodeRooms data.rooms )
|
||||
]
|
||||
|
||||
|
||||
syncDecoder : D.Decoder Sync
|
||||
syncDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ accountData = a, nextBatch = b, presence = c, rooms = d }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "next_batch" D.string)
|
||||
(D.field "presence" (D.list blindEventDecoder))
|
||||
(opField "rooms" roomsDecoder)
|
||||
|
||||
|
||||
{-| The timeline of messages and state changes in a room.
|
||||
-}
|
||||
type alias Timeline =
|
||||
{ events : List ClientEventWithoutRoomId
|
||||
, limited : Bool
|
||||
, prevBatch : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeTimeline : Timeline -> E.Value
|
||||
encodeTimeline data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
|
||||
, ( "limited", Just <| E.bool data.limited )
|
||||
, ( "prev_batch", Maybe.map E.string data.prevBatch )
|
||||
]
|
||||
|
||||
|
||||
timelineDecoder : D.Decoder Timeline
|
||||
timelineDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ events = a, limited = b, prevBatch = c }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opFieldWithDefault "limited" False D.bool)
|
||||
(opField "prev_batch" D.string)
|
||||
|
||||
|
||||
{-| Counts of unread notifications for this room.
|
||||
-}
|
||||
type alias UnreadNotificationCounts =
|
||||
{ highlightCount : Maybe Int
|
||||
, notificationCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
|
||||
encodeUnreadNotificationCounts data =
|
||||
maybeObject
|
||||
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
|
||||
, ( "notification_count", Maybe.map E.int data.notificationCount )
|
||||
]
|
||||
|
||||
|
||||
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
|
||||
unreadNotificationCountsDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ highlightCount = a, notificationCount = b }
|
||||
)
|
||||
(opField "highlight_count" D.int)
|
||||
(opField "notification_count" D.int)
|
||||
|
||||
|
||||
{-| Data that isn't getting signed for Canonical JSON.
|
||||
-}
|
||||
type UnsignedData
|
||||
= UnsignedData
|
||||
{ age : Maybe Int
|
||||
, prevContent : Maybe E.Value
|
||||
, redactedBecause : Maybe ClientEventWithoutRoomId
|
||||
, transactionId : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeUnsignedData : UnsignedData -> E.Value
|
||||
encodeUnsignedData (UnsignedData data) =
|
||||
maybeObject
|
||||
[ ( "age", Maybe.map E.int data.age )
|
||||
, ( "prev_content", data.prevContent )
|
||||
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
|
||||
, ( "transaction_id", Maybe.map E.string data.transactionId )
|
||||
]
|
||||
|
||||
|
||||
unsignedDataDecoder : D.Decoder UnsignedData
|
||||
unsignedDataDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
|
||||
)
|
||||
(opField "age" D.int)
|
||||
(opField "prev_content" D.value)
|
||||
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
|
||||
(opField "transaction_id" D.string)
|
|
@ -1,152 +0,0 @@
|
|||
version: v1.2
|
||||
name: Objects
|
||||
objects:
|
||||
Sync:
|
||||
description: The sync response the homeserver sends to the user.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
next_batch:
|
||||
type: string
|
||||
required: true
|
||||
presence:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
rooms:
|
||||
type: Rooms
|
||||
BlindEvent:
|
||||
description: A blind event that does not give context about itself.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
Rooms:
|
||||
description: Updates to rooms.
|
||||
fields:
|
||||
invite:
|
||||
type: "{[StrippedStateEvent]}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
join:
|
||||
type: "{JoinedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
knock:
|
||||
type: "{[StrippedStateEvent]}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
leave:
|
||||
type: "{LeftRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
StrippedStateEvent:
|
||||
description: Stripped state events of a room that the user has limited access to.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
JoinedRoom:
|
||||
description: Room that the user has joined.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
ephemeral:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
state:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: true
|
||||
summary:
|
||||
type: RoomSummary
|
||||
timeline:
|
||||
type: Timeline
|
||||
unread_notifications:
|
||||
type: UnreadNotificationCounts
|
||||
ClientEventWithoutRoomId:
|
||||
description: Client event that has all data except the room id.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
event_id:
|
||||
type: string
|
||||
required: true
|
||||
origin_server_ts:
|
||||
type: timestamp
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
unsigned:
|
||||
type: UnsignedData
|
||||
UnsignedData:
|
||||
anti_recursion: true
|
||||
description: Data that isn't getting signed for Canonical JSON.
|
||||
fields:
|
||||
age:
|
||||
type: int
|
||||
prev_content:
|
||||
type: value
|
||||
redacted_because:
|
||||
type: ClientEventWithoutRoomId
|
||||
transaction_id:
|
||||
type: string
|
||||
RoomSummary:
|
||||
description: Information about a room which clients may need to correctly render it to users.
|
||||
fields:
|
||||
m.heroes:
|
||||
type: "[string]"
|
||||
m.invited_member_count:
|
||||
type: int
|
||||
m.joined_member_count:
|
||||
type: int
|
||||
Timeline:
|
||||
description: The timeline of messages and state changes in a room.
|
||||
fields:
|
||||
events:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: false
|
||||
default: "[]"
|
||||
limited:
|
||||
type: bool
|
||||
required: false
|
||||
default: "False"
|
||||
prev_batch:
|
||||
type: string
|
||||
UnreadNotificationCounts:
|
||||
description: Counts of unread notifications for this room.
|
||||
fields:
|
||||
highlight_count:
|
||||
type: int
|
||||
notification_count:
|
||||
type: int
|
||||
LeftRoom:
|
||||
description: Room that the user has left.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
state:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: true
|
||||
timeline:
|
||||
type: Timeline
|
|
@ -1,13 +0,0 @@
|
|||
module Internal.Api.Sync.V1_2.Upcast exposing (..)
|
||||
|
||||
import Internal.Api.Sync.V1_2.Objects as O
|
||||
import Internal.Config.Leaking as L
|
||||
|
||||
|
||||
upcast : () -> O.Sync
|
||||
upcast _ =
|
||||
{ accountData = []
|
||||
, nextBatch = L.nextBatch
|
||||
, presence = []
|
||||
, rooms = Nothing
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
module Internal.Api.Sync.V1_3.Api exposing (..)
|
||||
|
||||
import Internal.Api.Sync.Api as Api
|
||||
import Internal.Api.Sync.V1_2.Objects as PO
|
||||
import Internal.Api.Sync.V1_3.Convert as C
|
||||
import Internal.Api.Sync.V1_3.Objects as O
|
||||
import Internal.Api.Sync.V1_3.SpecObjects as SO
|
||||
import Internal.Api.Sync.V1_3.Upcast as U
|
||||
import Internal.Api.VersionControl as V
|
||||
|
||||
|
||||
packet : V.SingleVersion Api.SyncInputV1 PO.Sync Api.SyncInputV1 O.Sync
|
||||
packet =
|
||||
{ version = "v1.3"
|
||||
, downcast = identity
|
||||
, current = Api.syncV1 SO.syncDecoder C.convert
|
||||
, upcast = U.upcast
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
module Internal.Api.Sync.V1_3.Convert exposing (..)
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Sync.V1_3.Objects as O
|
||||
import Internal.Api.Sync.V1_3.SpecObjects as SO
|
||||
|
||||
|
||||
convert : SO.Sync -> O.Sync
|
||||
convert sync =
|
||||
{ accountData = convertEventHolder sync.accountData
|
||||
, nextBatch = sync.nextBatch
|
||||
, presence = convertEventHolder sync.presence
|
||||
, rooms = Maybe.map convertRooms sync.rooms
|
||||
}
|
||||
|
||||
|
||||
convertEventHolder : Maybe { a | events : List b } -> List b
|
||||
convertEventHolder =
|
||||
Maybe.map .events >> Maybe.withDefault []
|
||||
|
||||
|
||||
convertRooms : SO.Rooms -> O.Rooms
|
||||
convertRooms rooms =
|
||||
{ invite =
|
||||
Dict.map
|
||||
(\_ -> .inviteState >> Maybe.map .events >> Maybe.withDefault [])
|
||||
rooms.invite
|
||||
, join = Dict.map (\_ -> convertJoinedRoom) rooms.join
|
||||
, knock =
|
||||
Dict.map
|
||||
(\_ -> .knockState >> Maybe.map .events >> Maybe.withDefault [])
|
||||
rooms.knock
|
||||
, leave = Dict.map (\_ -> convertLeftRoom) rooms.leave
|
||||
}
|
||||
|
||||
|
||||
convertJoinedRoom : SO.JoinedRoom -> O.JoinedRoom
|
||||
convertJoinedRoom room =
|
||||
{ accountData = convertEventHolder room.accountData
|
||||
, ephemeral = convertEventHolder room.ephemeral
|
||||
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
|
||||
, summary = room.summary
|
||||
, timeline = Maybe.map convertTimeline room.timeline
|
||||
, unreadNotifications = room.unreadNotifications
|
||||
}
|
||||
|
||||
|
||||
convertClientEventWithoutRoomId : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
|
||||
convertClientEventWithoutRoomId event =
|
||||
{ content = event.content
|
||||
, eventId = event.eventId
|
||||
, originServerTs = event.originServerTs
|
||||
, sender = event.sender
|
||||
, stateKey = event.stateKey
|
||||
, contentType = event.contentType
|
||||
, unsigned = Maybe.map convertUnsigned event.unsigned
|
||||
}
|
||||
|
||||
|
||||
convertUnsigned : SO.UnsignedData -> O.UnsignedData
|
||||
convertUnsigned (SO.UnsignedData data) =
|
||||
O.UnsignedData
|
||||
{ age = data.age
|
||||
, prevContent = data.prevContent
|
||||
, redactedBecause = Maybe.map convertToOldBlindEvent data.redactedBecause
|
||||
, transactionId = data.transactionId
|
||||
}
|
||||
|
||||
|
||||
convertToOldBlindEvent : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
|
||||
convertToOldBlindEvent event =
|
||||
{ content = event.content
|
||||
, eventId = event.eventId
|
||||
, originServerTs = event.originServerTs
|
||||
, sender = event.sender
|
||||
, stateKey = event.stateKey
|
||||
, contentType = event.contentType
|
||||
, unsigned = Maybe.map convertUnsigned event.unsigned
|
||||
}
|
||||
|
||||
|
||||
convertTimeline : SO.Timeline -> O.Timeline
|
||||
convertTimeline timeline =
|
||||
{ events = List.map convertClientEventWithoutRoomId timeline.events
|
||||
, limited = timeline.limited
|
||||
, prevBatch = timeline.prevBatch
|
||||
}
|
||||
|
||||
|
||||
convertLeftRoom : SO.LeftRoom -> O.LeftRoom
|
||||
convertLeftRoom room =
|
||||
{ accountData = convertEventHolder room.accountData
|
||||
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
|
||||
, timeline = Maybe.map convertTimeline room.timeline
|
||||
}
|
|
@ -1,395 +0,0 @@
|
|||
module Internal.Api.Sync.V1_3.Objects exposing
|
||||
( BlindEvent
|
||||
, ClientEventWithoutRoomId
|
||||
, JoinedRoom
|
||||
, LeftRoom
|
||||
, RoomSummary
|
||||
, Rooms
|
||||
, StrippedStateEvent
|
||||
, Sync
|
||||
, Timeline
|
||||
, UnreadNotificationCounts
|
||||
, UnsignedData(..)
|
||||
, blindEventDecoder
|
||||
, clientEventWithoutRoomIdDecoder
|
||||
, encodeBlindEvent
|
||||
, encodeClientEventWithoutRoomId
|
||||
, encodeJoinedRoom
|
||||
, encodeLeftRoom
|
||||
, encodeRoomSummary
|
||||
, encodeRooms
|
||||
, encodeStrippedStateEvent
|
||||
, encodeSync
|
||||
, encodeTimeline
|
||||
, encodeUnreadNotificationCounts
|
||||
, encodeUnsignedData
|
||||
, joinedRoomDecoder
|
||||
, leftRoomDecoder
|
||||
, roomSummaryDecoder
|
||||
, roomsDecoder
|
||||
, strippedStateEventDecoder
|
||||
, syncDecoder
|
||||
, timelineDecoder
|
||||
, unreadNotificationCountsDecoder
|
||||
, unsignedDataDecoder
|
||||
)
|
||||
|
||||
{-| Automatically generated 'Objects'
|
||||
|
||||
Last generated at Unix time 1673279712
|
||||
|
||||
-}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
|
||||
import Internal.Tools.EncodeExtra exposing (maybeObject)
|
||||
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
{-| A blind event that does not give context about itself.
|
||||
-}
|
||||
type alias BlindEvent =
|
||||
{ content : E.Value
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeBlindEvent : BlindEvent -> E.Value
|
||||
encodeBlindEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
blindEventDecoder : D.Decoder BlindEvent
|
||||
blindEventDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ content = a, contentType = b }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| Client event that has all data except the room id.
|
||||
-}
|
||||
type alias ClientEventWithoutRoomId =
|
||||
{ content : E.Value
|
||||
, eventId : String
|
||||
, originServerTs : Timestamp
|
||||
, sender : String
|
||||
, stateKey : Maybe String
|
||||
, contentType : String
|
||||
, unsigned : Maybe UnsignedData
|
||||
}
|
||||
|
||||
|
||||
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
|
||||
encodeClientEventWithoutRoomId data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "event_id", Just <| E.string data.eventId )
|
||||
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Maybe.map E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
|
||||
]
|
||||
|
||||
|
||||
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
|
||||
clientEventWithoutRoomIdDecoder =
|
||||
D.map7
|
||||
(\a b c d e f g ->
|
||||
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "event_id" D.string)
|
||||
(D.field "origin_server_ts" timestampDecoder)
|
||||
(D.field "sender" D.string)
|
||||
(opField "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
|
||||
|
||||
|
||||
{-| Room that the user has joined.
|
||||
-}
|
||||
type alias JoinedRoom =
|
||||
{ accountData : List BlindEvent
|
||||
, ephemeral : List BlindEvent
|
||||
, state : List ClientEventWithoutRoomId
|
||||
, summary : Maybe RoomSummary
|
||||
, timeline : Maybe Timeline
|
||||
, unreadNotifications : Maybe UnreadNotificationCounts
|
||||
}
|
||||
|
||||
|
||||
encodeJoinedRoom : JoinedRoom -> E.Value
|
||||
encodeJoinedRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "ephemeral", Just <| E.list encodeBlindEvent data.ephemeral )
|
||||
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
|
||||
, ( "summary", Maybe.map encodeRoomSummary data.summary )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
|
||||
]
|
||||
|
||||
|
||||
joinedRoomDecoder : D.Decoder JoinedRoom
|
||||
joinedRoomDecoder =
|
||||
D.map6
|
||||
(\a b c d e f ->
|
||||
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "ephemeral" (D.list blindEventDecoder))
|
||||
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opField "summary" roomSummaryDecoder)
|
||||
(opField "timeline" timelineDecoder)
|
||||
(opField "unread_notifications" unreadNotificationCountsDecoder)
|
||||
|
||||
|
||||
{-| Room that the user has left.
|
||||
-}
|
||||
type alias LeftRoom =
|
||||
{ accountData : List BlindEvent
|
||||
, state : List ClientEventWithoutRoomId
|
||||
, timeline : Maybe Timeline
|
||||
}
|
||||
|
||||
|
||||
encodeLeftRoom : LeftRoom -> E.Value
|
||||
encodeLeftRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
]
|
||||
|
||||
|
||||
leftRoomDecoder : D.Decoder LeftRoom
|
||||
leftRoomDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ accountData = a, state = b, timeline = c }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opField "timeline" timelineDecoder)
|
||||
|
||||
|
||||
{-| Updates to rooms.
|
||||
-}
|
||||
type alias Rooms =
|
||||
{ invite : Dict String (List StrippedStateEvent)
|
||||
, join : Dict String JoinedRoom
|
||||
, knock : Dict String (List StrippedStateEvent)
|
||||
, leave : Dict String LeftRoom
|
||||
}
|
||||
|
||||
|
||||
encodeRooms : Rooms -> E.Value
|
||||
encodeRooms data =
|
||||
maybeObject
|
||||
[ ( "invite", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.invite )
|
||||
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
|
||||
, ( "knock", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.knock )
|
||||
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
|
||||
]
|
||||
|
||||
|
||||
roomsDecoder : D.Decoder Rooms
|
||||
roomsDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ invite = a, join = b, knock = c, leave = d }
|
||||
)
|
||||
(opFieldWithDefault "invite" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
|
||||
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
|
||||
(opFieldWithDefault "knock" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
|
||||
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
|
||||
|
||||
|
||||
{-| Information about a room which clients may need to correctly render it to users.
|
||||
-}
|
||||
type alias RoomSummary =
|
||||
{ mHeroes : Maybe (List String)
|
||||
, mInvitedMemberCount : Maybe Int
|
||||
, mJoinedMemberCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeRoomSummary : RoomSummary -> E.Value
|
||||
encodeRoomSummary data =
|
||||
maybeObject
|
||||
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
|
||||
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
|
||||
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
|
||||
]
|
||||
|
||||
|
||||
roomSummaryDecoder : D.Decoder RoomSummary
|
||||
roomSummaryDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
|
||||
)
|
||||
(opField "m.heroes" (D.list D.string))
|
||||
(opField "m.invited_member_count" D.int)
|
||||
(opField "m.joined_member_count" D.int)
|
||||
|
||||
|
||||
{-| Stripped state events of a room that the user has limited access to.
|
||||
-}
|
||||
type alias StrippedStateEvent =
|
||||
{ content : E.Value
|
||||
, sender : String
|
||||
, stateKey : String
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
|
||||
encodeStrippedStateEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Just <| E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
strippedStateEventDecoder : D.Decoder StrippedStateEvent
|
||||
strippedStateEventDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ content = a, sender = b, stateKey = c, contentType = d }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "sender" D.string)
|
||||
(D.field "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| The sync response the homeserver sends to the user.
|
||||
-}
|
||||
type alias Sync =
|
||||
{ accountData : List BlindEvent
|
||||
, nextBatch : String
|
||||
, presence : List BlindEvent
|
||||
, rooms : Maybe Rooms
|
||||
}
|
||||
|
||||
|
||||
encodeSync : Sync -> E.Value
|
||||
encodeSync data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "next_batch", Just <| E.string data.nextBatch )
|
||||
, ( "presence", Just <| E.list encodeBlindEvent data.presence )
|
||||
, ( "rooms", Maybe.map encodeRooms data.rooms )
|
||||
]
|
||||
|
||||
|
||||
syncDecoder : D.Decoder Sync
|
||||
syncDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ accountData = a, nextBatch = b, presence = c, rooms = d }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "next_batch" D.string)
|
||||
(D.field "presence" (D.list blindEventDecoder))
|
||||
(opField "rooms" roomsDecoder)
|
||||
|
||||
|
||||
{-| The timeline of messages and state changes in a room.
|
||||
-}
|
||||
type alias Timeline =
|
||||
{ events : List ClientEventWithoutRoomId
|
||||
, limited : Bool
|
||||
, prevBatch : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeTimeline : Timeline -> E.Value
|
||||
encodeTimeline data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
|
||||
, ( "limited", Just <| E.bool data.limited )
|
||||
, ( "prev_batch", Maybe.map E.string data.prevBatch )
|
||||
]
|
||||
|
||||
|
||||
timelineDecoder : D.Decoder Timeline
|
||||
timelineDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ events = a, limited = b, prevBatch = c }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opFieldWithDefault "limited" False D.bool)
|
||||
(opField "prev_batch" D.string)
|
||||
|
||||
|
||||
{-| Counts of unread notifications for this room.
|
||||
-}
|
||||
type alias UnreadNotificationCounts =
|
||||
{ highlightCount : Maybe Int
|
||||
, notificationCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
|
||||
encodeUnreadNotificationCounts data =
|
||||
maybeObject
|
||||
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
|
||||
, ( "notification_count", Maybe.map E.int data.notificationCount )
|
||||
]
|
||||
|
||||
|
||||
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
|
||||
unreadNotificationCountsDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ highlightCount = a, notificationCount = b }
|
||||
)
|
||||
(opField "highlight_count" D.int)
|
||||
(opField "notification_count" D.int)
|
||||
|
||||
|
||||
{-| Data that isn't getting signed for Canonical JSON.
|
||||
-}
|
||||
type UnsignedData
|
||||
= UnsignedData
|
||||
{ age : Maybe Int
|
||||
, prevContent : Maybe E.Value
|
||||
, redactedBecause : Maybe ClientEventWithoutRoomId
|
||||
, transactionId : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeUnsignedData : UnsignedData -> E.Value
|
||||
encodeUnsignedData (UnsignedData data) =
|
||||
maybeObject
|
||||
[ ( "age", Maybe.map E.int data.age )
|
||||
, ( "prev_content", data.prevContent )
|
||||
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
|
||||
, ( "transaction_id", Maybe.map E.string data.transactionId )
|
||||
]
|
||||
|
||||
|
||||
unsignedDataDecoder : D.Decoder UnsignedData
|
||||
unsignedDataDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
|
||||
)
|
||||
(opField "age" D.int)
|
||||
(opField "prev_content" D.value)
|
||||
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
|
||||
(opField "transaction_id" D.string)
|
|
@ -1,152 +0,0 @@
|
|||
version: v1.3
|
||||
name: Objects
|
||||
objects:
|
||||
Sync:
|
||||
description: The sync response the homeserver sends to the user.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
next_batch:
|
||||
type: string
|
||||
required: true
|
||||
presence:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
rooms:
|
||||
type: Rooms
|
||||
BlindEvent:
|
||||
description: A blind event that does not give context about itself.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
Rooms:
|
||||
description: Updates to rooms.
|
||||
fields:
|
||||
invite:
|
||||
type: "{[StrippedStateEvent]}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
join:
|
||||
type: "{JoinedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
knock:
|
||||
type: "{[StrippedStateEvent]}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
leave:
|
||||
type: "{LeftRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
StrippedStateEvent:
|
||||
description: Stripped state events of a room that the user has limited access to.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
JoinedRoom:
|
||||
description: Room that the user has joined.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
ephemeral:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
state:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: true
|
||||
summary:
|
||||
type: RoomSummary
|
||||
timeline:
|
||||
type: Timeline
|
||||
unread_notifications:
|
||||
type: UnreadNotificationCounts
|
||||
ClientEventWithoutRoomId:
|
||||
description: Client event that has all data except the room id.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
event_id:
|
||||
type: string
|
||||
required: true
|
||||
origin_server_ts:
|
||||
type: timestamp
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
unsigned:
|
||||
type: UnsignedData
|
||||
UnsignedData:
|
||||
anti_recursion: true
|
||||
description: Data that isn't getting signed for Canonical JSON.
|
||||
fields:
|
||||
age:
|
||||
type: int
|
||||
prev_content:
|
||||
type: value
|
||||
redacted_because:
|
||||
type: ClientEventWithoutRoomId
|
||||
transaction_id:
|
||||
type: string
|
||||
RoomSummary:
|
||||
description: Information about a room which clients may need to correctly render it to users.
|
||||
fields:
|
||||
m.heroes:
|
||||
type: "[string]"
|
||||
m.invited_member_count:
|
||||
type: int
|
||||
m.joined_member_count:
|
||||
type: int
|
||||
Timeline:
|
||||
description: The timeline of messages and state changes in a room.
|
||||
fields:
|
||||
events:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: false
|
||||
default: "[]"
|
||||
limited:
|
||||
type: bool
|
||||
required: false
|
||||
default: "False"
|
||||
prev_batch:
|
||||
type: string
|
||||
UnreadNotificationCounts:
|
||||
description: Counts of unread notifications for this room.
|
||||
fields:
|
||||
highlight_count:
|
||||
type: int
|
||||
notification_count:
|
||||
type: int
|
||||
LeftRoom:
|
||||
description: Room that the user has left.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
state:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: true
|
||||
timeline:
|
||||
type: Timeline
|
|
@ -1,603 +0,0 @@
|
|||
module Internal.Api.Sync.V1_3.SpecObjects exposing
|
||||
( AccountData
|
||||
, ClientEventWithoutRoomId
|
||||
, Ephemeral
|
||||
, Event
|
||||
, InviteState
|
||||
, InvitedRoom
|
||||
, JoinedRoom
|
||||
, KnockState
|
||||
, KnockedRoom
|
||||
, LeftRoom
|
||||
, Presence
|
||||
, RoomSummary
|
||||
, Rooms
|
||||
, State
|
||||
, StrippedStateEvent
|
||||
, Sync
|
||||
, Timeline
|
||||
, UnreadNotificationCounts
|
||||
, UnsignedData(..)
|
||||
, accountDataDecoder
|
||||
, clientEventWithoutRoomIdDecoder
|
||||
, encodeAccountData
|
||||
, encodeClientEventWithoutRoomId
|
||||
, encodeEphemeral
|
||||
, encodeEvent
|
||||
, encodeInviteState
|
||||
, encodeInvitedRoom
|
||||
, encodeJoinedRoom
|
||||
, encodeKnockState
|
||||
, encodeKnockedRoom
|
||||
, encodeLeftRoom
|
||||
, encodePresence
|
||||
, encodeRoomSummary
|
||||
, encodeRooms
|
||||
, encodeState
|
||||
, encodeStrippedStateEvent
|
||||
, encodeSync
|
||||
, encodeTimeline
|
||||
, encodeUnreadNotificationCounts
|
||||
, encodeUnsignedData
|
||||
, ephemeralDecoder
|
||||
, eventDecoder
|
||||
, inviteStateDecoder
|
||||
, invitedRoomDecoder
|
||||
, joinedRoomDecoder
|
||||
, knockStateDecoder
|
||||
, knockedRoomDecoder
|
||||
, leftRoomDecoder
|
||||
, presenceDecoder
|
||||
, roomSummaryDecoder
|
||||
, roomsDecoder
|
||||
, stateDecoder
|
||||
, strippedStateEventDecoder
|
||||
, syncDecoder
|
||||
, timelineDecoder
|
||||
, unreadNotificationCountsDecoder
|
||||
, unsignedDataDecoder
|
||||
)
|
||||
|
||||
{-| Automatically generated 'SpecObjects'
|
||||
|
||||
Last generated at Unix time 1673279712
|
||||
|
||||
-}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
|
||||
import Internal.Tools.EncodeExtra exposing (maybeObject)
|
||||
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
{-| The private data created by this user in a given context.
|
||||
-}
|
||||
type alias AccountData =
|
||||
{ events : List Event
|
||||
}
|
||||
|
||||
|
||||
encodeAccountData : AccountData -> E.Value
|
||||
encodeAccountData data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
accountDataDecoder : D.Decoder AccountData
|
||||
accountDataDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list eventDecoder))
|
||||
|
||||
|
||||
{-| Client event that has all data except the room id.
|
||||
-}
|
||||
type alias ClientEventWithoutRoomId =
|
||||
{ content : E.Value
|
||||
, eventId : String
|
||||
, originServerTs : Timestamp
|
||||
, sender : String
|
||||
, stateKey : Maybe String
|
||||
, contentType : String
|
||||
, unsigned : Maybe UnsignedData
|
||||
}
|
||||
|
||||
|
||||
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
|
||||
encodeClientEventWithoutRoomId data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "event_id", Just <| E.string data.eventId )
|
||||
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Maybe.map E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
|
||||
]
|
||||
|
||||
|
||||
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
|
||||
clientEventWithoutRoomIdDecoder =
|
||||
D.map7
|
||||
(\a b c d e f g ->
|
||||
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "event_id" D.string)
|
||||
(D.field "origin_server_ts" timestampDecoder)
|
||||
(D.field "sender" D.string)
|
||||
(opField "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
|
||||
|
||||
|
||||
{-| Ephemeral events in a room that aren't recorded in the timeline or the room state.
|
||||
-}
|
||||
type alias Ephemeral =
|
||||
{ events : List Event
|
||||
}
|
||||
|
||||
|
||||
encodeEphemeral : Ephemeral -> E.Value
|
||||
encodeEphemeral data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
ephemeralDecoder : D.Decoder Ephemeral
|
||||
ephemeralDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list eventDecoder))
|
||||
|
||||
|
||||
{-| A blind event that does not give context about itself.
|
||||
-}
|
||||
type alias Event =
|
||||
{ content : E.Value
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeEvent : Event -> E.Value
|
||||
encodeEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
eventDecoder : D.Decoder Event
|
||||
eventDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ content = a, contentType = b }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| Room that the user has been invited to.
|
||||
-}
|
||||
type alias InvitedRoom =
|
||||
{ inviteState : Maybe InviteState
|
||||
}
|
||||
|
||||
|
||||
encodeInvitedRoom : InvitedRoom -> E.Value
|
||||
encodeInvitedRoom data =
|
||||
maybeObject
|
||||
[ ( "invite_state", Maybe.map encodeInviteState data.inviteState )
|
||||
]
|
||||
|
||||
|
||||
invitedRoomDecoder : D.Decoder InvitedRoom
|
||||
invitedRoomDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ inviteState = a }
|
||||
)
|
||||
(opField "invite_state" inviteStateDecoder)
|
||||
|
||||
|
||||
{-| The state of a room that the user has been invited to.
|
||||
-}
|
||||
type alias InviteState =
|
||||
{ events : List StrippedStateEvent
|
||||
}
|
||||
|
||||
|
||||
encodeInviteState : InviteState -> E.Value
|
||||
encodeInviteState data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeStrippedStateEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
inviteStateDecoder : D.Decoder InviteState
|
||||
inviteStateDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list strippedStateEventDecoder))
|
||||
|
||||
|
||||
{-| Room that the user has joined.
|
||||
-}
|
||||
type alias JoinedRoom =
|
||||
{ accountData : Maybe AccountData
|
||||
, ephemeral : Maybe Ephemeral
|
||||
, state : Maybe State
|
||||
, summary : Maybe RoomSummary
|
||||
, timeline : Maybe Timeline
|
||||
, unreadNotifications : Maybe UnreadNotificationCounts
|
||||
}
|
||||
|
||||
|
||||
encodeJoinedRoom : JoinedRoom -> E.Value
|
||||
encodeJoinedRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
|
||||
, ( "ephemeral", Maybe.map encodeEphemeral data.ephemeral )
|
||||
, ( "state", Maybe.map encodeState data.state )
|
||||
, ( "summary", Maybe.map encodeRoomSummary data.summary )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
|
||||
]
|
||||
|
||||
|
||||
joinedRoomDecoder : D.Decoder JoinedRoom
|
||||
joinedRoomDecoder =
|
||||
D.map6
|
||||
(\a b c d e f ->
|
||||
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f }
|
||||
)
|
||||
(opField "account_data" accountDataDecoder)
|
||||
(opField "ephemeral" ephemeralDecoder)
|
||||
(opField "state" stateDecoder)
|
||||
(opField "summary" roomSummaryDecoder)
|
||||
(opField "timeline" timelineDecoder)
|
||||
(opField "unread_notifications" unreadNotificationCountsDecoder)
|
||||
|
||||
|
||||
{-| Room that the user has knocked upon.
|
||||
-}
|
||||
type alias KnockedRoom =
|
||||
{ knockState : Maybe KnockState
|
||||
}
|
||||
|
||||
|
||||
encodeKnockedRoom : KnockedRoom -> E.Value
|
||||
encodeKnockedRoom data =
|
||||
maybeObject
|
||||
[ ( "knock_state", Maybe.map encodeKnockState data.knockState )
|
||||
]
|
||||
|
||||
|
||||
knockedRoomDecoder : D.Decoder KnockedRoom
|
||||
knockedRoomDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ knockState = a }
|
||||
)
|
||||
(opField "knock_state" knockStateDecoder)
|
||||
|
||||
|
||||
{-| The state of a room that the user has knocked upon.
|
||||
-}
|
||||
type alias KnockState =
|
||||
{ events : List StrippedStateEvent
|
||||
}
|
||||
|
||||
|
||||
encodeKnockState : KnockState -> E.Value
|
||||
encodeKnockState data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeStrippedStateEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
knockStateDecoder : D.Decoder KnockState
|
||||
knockStateDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list strippedStateEventDecoder))
|
||||
|
||||
|
||||
{-| Room that the user has left.
|
||||
-}
|
||||
type alias LeftRoom =
|
||||
{ accountData : Maybe AccountData
|
||||
, state : Maybe State
|
||||
, timeline : Maybe Timeline
|
||||
}
|
||||
|
||||
|
||||
encodeLeftRoom : LeftRoom -> E.Value
|
||||
encodeLeftRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
|
||||
, ( "state", Maybe.map encodeState data.state )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
]
|
||||
|
||||
|
||||
leftRoomDecoder : D.Decoder LeftRoom
|
||||
leftRoomDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ accountData = a, state = b, timeline = c }
|
||||
)
|
||||
(opField "account_data" accountDataDecoder)
|
||||
(opField "state" stateDecoder)
|
||||
(opField "timeline" timelineDecoder)
|
||||
|
||||
|
||||
{-| The updates to the presence status of other users.
|
||||
-}
|
||||
type alias Presence =
|
||||
{ events : List Event
|
||||
}
|
||||
|
||||
|
||||
encodePresence : Presence -> E.Value
|
||||
encodePresence data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
presenceDecoder : D.Decoder Presence
|
||||
presenceDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list eventDecoder))
|
||||
|
||||
|
||||
{-| Updates to rooms.
|
||||
-}
|
||||
type alias Rooms =
|
||||
{ invite : Dict String InvitedRoom
|
||||
, join : Dict String JoinedRoom
|
||||
, knock : Dict String KnockedRoom
|
||||
, leave : Dict String LeftRoom
|
||||
}
|
||||
|
||||
|
||||
encodeRooms : Rooms -> E.Value
|
||||
encodeRooms data =
|
||||
maybeObject
|
||||
[ ( "invite", Just <| E.dict identity encodeInvitedRoom data.invite )
|
||||
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
|
||||
, ( "knock", Just <| E.dict identity encodeKnockedRoom data.knock )
|
||||
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
|
||||
]
|
||||
|
||||
|
||||
roomsDecoder : D.Decoder Rooms
|
||||
roomsDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ invite = a, join = b, knock = c, leave = d }
|
||||
)
|
||||
(opFieldWithDefault "invite" Dict.empty (D.dict invitedRoomDecoder))
|
||||
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
|
||||
(opFieldWithDefault "knock" Dict.empty (D.dict knockedRoomDecoder))
|
||||
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
|
||||
|
||||
|
||||
{-| Information about a room which clients may need to correctly render it to users.
|
||||
-}
|
||||
type alias RoomSummary =
|
||||
{ mHeroes : Maybe (List String)
|
||||
, mInvitedMemberCount : Maybe Int
|
||||
, mJoinedMemberCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeRoomSummary : RoomSummary -> E.Value
|
||||
encodeRoomSummary data =
|
||||
maybeObject
|
||||
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
|
||||
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
|
||||
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
|
||||
]
|
||||
|
||||
|
||||
roomSummaryDecoder : D.Decoder RoomSummary
|
||||
roomSummaryDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
|
||||
)
|
||||
(opField "m.heroes" (D.list D.string))
|
||||
(opField "m.invited_member_count" D.int)
|
||||
(opField "m.joined_member_count" D.int)
|
||||
|
||||
|
||||
{-| Updates to the state of a room.
|
||||
-}
|
||||
type alias State =
|
||||
{ events : List ClientEventWithoutRoomId
|
||||
}
|
||||
|
||||
|
||||
encodeState : State -> E.Value
|
||||
encodeState data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
|
||||
]
|
||||
|
||||
|
||||
stateDecoder : D.Decoder State
|
||||
stateDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
|
||||
|
||||
|
||||
{-| Stripped state events of a room that the user has limited access to.
|
||||
-}
|
||||
type alias StrippedStateEvent =
|
||||
{ content : E.Value
|
||||
, sender : String
|
||||
, stateKey : String
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
|
||||
encodeStrippedStateEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Just <| E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
strippedStateEventDecoder : D.Decoder StrippedStateEvent
|
||||
strippedStateEventDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ content = a, sender = b, stateKey = c, contentType = d }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "sender" D.string)
|
||||
(D.field "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| The sync response the homeserver sends to the user.
|
||||
-}
|
||||
type alias Sync =
|
||||
{ accountData : Maybe AccountData
|
||||
, nextBatch : String
|
||||
, presence : Maybe Presence
|
||||
, rooms : Maybe Rooms
|
||||
}
|
||||
|
||||
|
||||
encodeSync : Sync -> E.Value
|
||||
encodeSync data =
|
||||
maybeObject
|
||||
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
|
||||
, ( "next_batch", Just <| E.string data.nextBatch )
|
||||
, ( "presence", Maybe.map encodePresence data.presence )
|
||||
, ( "rooms", Maybe.map encodeRooms data.rooms )
|
||||
]
|
||||
|
||||
|
||||
syncDecoder : D.Decoder Sync
|
||||
syncDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ accountData = a, nextBatch = b, presence = c, rooms = d }
|
||||
)
|
||||
(opField "account_data" accountDataDecoder)
|
||||
(D.field "next_batch" D.string)
|
||||
(opField "presence" presenceDecoder)
|
||||
(opField "rooms" roomsDecoder)
|
||||
|
||||
|
||||
{-| The timeline of messages and state changes in a room.
|
||||
-}
|
||||
type alias Timeline =
|
||||
{ events : List ClientEventWithoutRoomId
|
||||
, limited : Bool
|
||||
, prevBatch : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeTimeline : Timeline -> E.Value
|
||||
encodeTimeline data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
|
||||
, ( "limited", Just <| E.bool data.limited )
|
||||
, ( "prev_batch", Maybe.map E.string data.prevBatch )
|
||||
]
|
||||
|
||||
|
||||
timelineDecoder : D.Decoder Timeline
|
||||
timelineDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ events = a, limited = b, prevBatch = c }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opFieldWithDefault "limited" False D.bool)
|
||||
(opField "prev_batch" D.string)
|
||||
|
||||
|
||||
{-| Counts of unread notifications for this room.
|
||||
-}
|
||||
type alias UnreadNotificationCounts =
|
||||
{ highlightCount : Maybe Int
|
||||
, notificationCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
|
||||
encodeUnreadNotificationCounts data =
|
||||
maybeObject
|
||||
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
|
||||
, ( "notification_count", Maybe.map E.int data.notificationCount )
|
||||
]
|
||||
|
||||
|
||||
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
|
||||
unreadNotificationCountsDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ highlightCount = a, notificationCount = b }
|
||||
)
|
||||
(opField "highlight_count" D.int)
|
||||
(opField "notification_count" D.int)
|
||||
|
||||
|
||||
{-| Data that isn't getting signed for Canonical JSON.
|
||||
-}
|
||||
type UnsignedData
|
||||
= UnsignedData
|
||||
{ age : Maybe Int
|
||||
, prevContent : Maybe E.Value
|
||||
, redactedBecause : Maybe ClientEventWithoutRoomId
|
||||
, transactionId : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeUnsignedData : UnsignedData -> E.Value
|
||||
encodeUnsignedData (UnsignedData data) =
|
||||
maybeObject
|
||||
[ ( "age", Maybe.map E.int data.age )
|
||||
, ( "prev_content", data.prevContent )
|
||||
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
|
||||
, ( "transaction_id", Maybe.map E.string data.transactionId )
|
||||
]
|
||||
|
||||
|
||||
unsignedDataDecoder : D.Decoder UnsignedData
|
||||
unsignedDataDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
|
||||
)
|
||||
(opField "age" D.int)
|
||||
(opField "prev_content" D.value)
|
||||
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
|
||||
(opField "transaction_id" D.string)
|
|
@ -1,197 +0,0 @@
|
|||
version: v1.3
|
||||
name: SpecObjects
|
||||
objects:
|
||||
Sync:
|
||||
description: The sync response the homeserver sends to the user.
|
||||
fields:
|
||||
account_data:
|
||||
type: AccountData
|
||||
next_batch:
|
||||
type: string
|
||||
required: true
|
||||
presence:
|
||||
type: Presence
|
||||
rooms:
|
||||
type: Rooms
|
||||
AccountData:
|
||||
description: The private data created by this user in a given context.
|
||||
fields:
|
||||
events:
|
||||
type: "[Event]"
|
||||
required: false
|
||||
default: "[]"
|
||||
Event:
|
||||
description: A blind event that does not give context about itself.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
Presence:
|
||||
description: The updates to the presence status of other users.
|
||||
fields:
|
||||
events:
|
||||
type: "[Event]"
|
||||
required: false
|
||||
default: "[]"
|
||||
Rooms:
|
||||
description: Updates to rooms.
|
||||
fields:
|
||||
invite:
|
||||
type: "{InvitedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
join:
|
||||
type: "{JoinedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
knock:
|
||||
type: "{KnockedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
leave:
|
||||
type: "{LeftRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
InvitedRoom:
|
||||
description: Room that the user has been invited to.
|
||||
fields:
|
||||
invite_state:
|
||||
type: InviteState
|
||||
InviteState:
|
||||
description: The state of a room that the user has been invited to.
|
||||
fields:
|
||||
events:
|
||||
type: "[StrippedStateEvent]"
|
||||
required: false
|
||||
default: "[]"
|
||||
StrippedStateEvent:
|
||||
description: Stripped state events of a room that the user has limited access to.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
JoinedRoom:
|
||||
description: Room that the user has joined.
|
||||
fields:
|
||||
account_data:
|
||||
type: AccountData
|
||||
ephemeral:
|
||||
type: Ephemeral
|
||||
state:
|
||||
type: State
|
||||
summary:
|
||||
type: RoomSummary
|
||||
timeline:
|
||||
type: Timeline
|
||||
unread_notifications:
|
||||
type: UnreadNotificationCounts
|
||||
Ephemeral:
|
||||
description: Ephemeral events in a room that aren't recorded in the timeline or the room state.
|
||||
fields:
|
||||
events:
|
||||
type: "[Event]"
|
||||
required: false
|
||||
default: "[]"
|
||||
State:
|
||||
description: Updates to the state of a room.
|
||||
fields:
|
||||
events:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: false
|
||||
default: "[]"
|
||||
ClientEventWithoutRoomId:
|
||||
description: Client event that has all data except the room id.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
event_id:
|
||||
type: string
|
||||
required: true
|
||||
origin_server_ts:
|
||||
type: timestamp
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
unsigned:
|
||||
type: UnsignedData
|
||||
UnsignedData:
|
||||
anti_recursion: true
|
||||
description: Data that isn't getting signed for Canonical JSON.
|
||||
fields:
|
||||
age:
|
||||
type: int
|
||||
prev_content:
|
||||
type: value
|
||||
redacted_because:
|
||||
type: ClientEventWithoutRoomId
|
||||
transaction_id:
|
||||
type: string
|
||||
RoomSummary:
|
||||
description: Information about a room which clients may need to correctly render it to users.
|
||||
fields:
|
||||
m.heroes:
|
||||
type: "[string]"
|
||||
m.invited_member_count:
|
||||
type: int
|
||||
m.joined_member_count:
|
||||
type: int
|
||||
Timeline:
|
||||
description: The timeline of messages and state changes in a room.
|
||||
fields:
|
||||
events:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: false
|
||||
default: "[]"
|
||||
limited:
|
||||
type: bool
|
||||
required: false
|
||||
default: "False"
|
||||
prev_batch:
|
||||
type: string
|
||||
UnreadNotificationCounts:
|
||||
description: Counts of unread notifications for this room.
|
||||
fields:
|
||||
highlight_count:
|
||||
type: int
|
||||
notification_count:
|
||||
type: int
|
||||
KnockedRoom:
|
||||
description: Room that the user has knocked upon.
|
||||
fields:
|
||||
knock_state:
|
||||
type: KnockState
|
||||
KnockState:
|
||||
description: The state of a room that the user has knocked upon.
|
||||
fields:
|
||||
events:
|
||||
type: "[StrippedStateEvent]"
|
||||
required: false
|
||||
default: "[]"
|
||||
LeftRoom:
|
||||
description: Room that the user has left.
|
||||
fields:
|
||||
account_data:
|
||||
type: AccountData
|
||||
state:
|
||||
type: State
|
||||
timeline:
|
||||
type: Timeline
|
|
@ -1,72 +0,0 @@
|
|||
module Internal.Api.Sync.V1_3.Upcast exposing (..)
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Sync.V1_2.Objects as PO
|
||||
import Internal.Api.Sync.V1_3.Objects as O
|
||||
|
||||
|
||||
upcast : PO.Sync -> O.Sync
|
||||
upcast sync =
|
||||
{ accountData = sync.accountData
|
||||
, nextBatch = sync.nextBatch
|
||||
, presence = sync.presence
|
||||
, rooms = Maybe.map upcastRooms sync.rooms
|
||||
}
|
||||
|
||||
|
||||
upcastRooms : PO.Rooms -> O.Rooms
|
||||
upcastRooms rooms =
|
||||
{ invite = rooms.invite
|
||||
, join = Dict.map (\_ -> upcastJoinedRoom) rooms.join
|
||||
, knock = rooms.knock
|
||||
, leave = Dict.map (\_ -> upcastLeftRoom) rooms.leave
|
||||
}
|
||||
|
||||
|
||||
upcastJoinedRoom : PO.JoinedRoom -> O.JoinedRoom
|
||||
upcastJoinedRoom room =
|
||||
{ accountData = room.accountData
|
||||
, ephemeral = room.ephemeral
|
||||
, state = List.map upcastClientEventWithoutRoomId room.state
|
||||
, summary = room.summary
|
||||
, timeline = Maybe.map upcastTimeline room.timeline
|
||||
, unreadNotifications = room.unreadNotifications
|
||||
}
|
||||
|
||||
|
||||
upcastClientEventWithoutRoomId : PO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
|
||||
upcastClientEventWithoutRoomId event =
|
||||
{ content = event.content
|
||||
, eventId = event.eventId
|
||||
, originServerTs = event.originServerTs
|
||||
, sender = event.sender
|
||||
, stateKey = event.stateKey
|
||||
, contentType = event.contentType
|
||||
, unsigned = Maybe.map upcastUnsigned event.unsigned
|
||||
}
|
||||
|
||||
|
||||
upcastUnsigned : PO.UnsignedData -> O.UnsignedData
|
||||
upcastUnsigned (PO.UnsignedData data) =
|
||||
O.UnsignedData
|
||||
{ age = data.age
|
||||
, prevContent = data.prevContent
|
||||
, redactedBecause = Maybe.map upcastClientEventWithoutRoomId data.redactedBecause
|
||||
, transactionId = data.transactionId
|
||||
}
|
||||
|
||||
|
||||
upcastTimeline : PO.Timeline -> O.Timeline
|
||||
upcastTimeline timeline =
|
||||
{ events = List.map upcastClientEventWithoutRoomId timeline.events
|
||||
, limited = timeline.limited
|
||||
, prevBatch = timeline.prevBatch
|
||||
}
|
||||
|
||||
|
||||
upcastLeftRoom : PO.LeftRoom -> O.LeftRoom
|
||||
upcastLeftRoom room =
|
||||
{ accountData = room.accountData
|
||||
, state = List.map upcastClientEventWithoutRoomId room.state
|
||||
, timeline = Maybe.map upcastTimeline room.timeline
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
module Internal.Api.Sync.V1_4.Api exposing (..)
|
||||
|
||||
import Internal.Api.Sync.Api as Api
|
||||
import Internal.Api.Sync.V1_3.Objects as PO
|
||||
import Internal.Api.Sync.V1_4.Convert as C
|
||||
import Internal.Api.Sync.V1_4.Objects as O
|
||||
import Internal.Api.Sync.V1_4.SpecObjects as SO
|
||||
import Internal.Api.Sync.V1_4.Upcast as U
|
||||
import Internal.Api.VersionControl as V
|
||||
|
||||
|
||||
packet : V.SingleVersion Api.SyncInputV1 PO.Sync Api.SyncInputV1 O.Sync
|
||||
packet =
|
||||
{ version = "v1.4"
|
||||
, downcast = identity
|
||||
, current = Api.syncV1 SO.syncDecoder C.convert
|
||||
, upcast = U.upcast
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
module Internal.Api.Sync.V1_4.Convert exposing (..)
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Sync.V1_4.Objects as O
|
||||
import Internal.Api.Sync.V1_4.SpecObjects as SO
|
||||
|
||||
|
||||
convert : SO.Sync -> O.Sync
|
||||
convert sync =
|
||||
{ accountData = convertEventHolder sync.accountData
|
||||
, nextBatch = sync.nextBatch
|
||||
, presence = convertEventHolder sync.presence
|
||||
, rooms = Maybe.map convertRooms sync.rooms
|
||||
}
|
||||
|
||||
|
||||
convertEventHolder : Maybe { a | events : List b } -> List b
|
||||
convertEventHolder =
|
||||
Maybe.map .events >> Maybe.withDefault []
|
||||
|
||||
|
||||
convertRooms : SO.Rooms -> O.Rooms
|
||||
convertRooms rooms =
|
||||
{ invite =
|
||||
Dict.map
|
||||
(\_ -> .inviteState >> Maybe.map .events >> Maybe.withDefault [])
|
||||
rooms.invite
|
||||
, join = Dict.map (\_ -> convertJoinedRoom) rooms.join
|
||||
, knock =
|
||||
Dict.map
|
||||
(\_ -> .knockState >> Maybe.map .events >> Maybe.withDefault [])
|
||||
rooms.knock
|
||||
, leave = Dict.map (\_ -> convertLeftRoom) rooms.leave
|
||||
}
|
||||
|
||||
|
||||
convertJoinedRoom : SO.JoinedRoom -> O.JoinedRoom
|
||||
convertJoinedRoom room =
|
||||
{ accountData = convertEventHolder room.accountData
|
||||
, ephemeral = convertEventHolder room.ephemeral
|
||||
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
|
||||
, summary = room.summary
|
||||
, timeline = Maybe.map convertTimeline room.timeline
|
||||
, unreadNotifications = room.unreadNotifications
|
||||
, unreadThreadNotifications = room.unreadThreadNotifications
|
||||
}
|
||||
|
||||
|
||||
convertClientEventWithoutRoomId : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
|
||||
convertClientEventWithoutRoomId event =
|
||||
{ content = event.content
|
||||
, eventId = event.eventId
|
||||
, originServerTs = event.originServerTs
|
||||
, sender = event.sender
|
||||
, stateKey = event.stateKey
|
||||
, contentType = event.contentType
|
||||
, unsigned = Maybe.map convertUnsigned event.unsigned
|
||||
}
|
||||
|
||||
|
||||
convertUnsigned : SO.UnsignedData -> O.UnsignedData
|
||||
convertUnsigned (SO.UnsignedData data) =
|
||||
O.UnsignedData
|
||||
{ age = data.age
|
||||
, prevContent = data.prevContent
|
||||
, redactedBecause = Maybe.map convertClientEventWithoutRoomId data.redactedBecause
|
||||
, transactionId = data.transactionId
|
||||
}
|
||||
|
||||
|
||||
convertTimeline : SO.Timeline -> O.Timeline
|
||||
convertTimeline timeline =
|
||||
{ events = List.map convertClientEventWithoutRoomId timeline.events
|
||||
, limited = timeline.limited
|
||||
, prevBatch = timeline.prevBatch
|
||||
}
|
||||
|
||||
|
||||
convertLeftRoom : SO.LeftRoom -> O.LeftRoom
|
||||
convertLeftRoom room =
|
||||
{ accountData = convertEventHolder room.accountData
|
||||
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
|
||||
, timeline = Maybe.map convertTimeline room.timeline
|
||||
}
|
|
@ -1,398 +0,0 @@
|
|||
module Internal.Api.Sync.V1_4.Objects exposing
|
||||
( BlindEvent
|
||||
, ClientEventWithoutRoomId
|
||||
, JoinedRoom
|
||||
, LeftRoom
|
||||
, RoomSummary
|
||||
, Rooms
|
||||
, StrippedStateEvent
|
||||
, Sync
|
||||
, Timeline
|
||||
, UnreadNotificationCounts
|
||||
, UnsignedData(..)
|
||||
, blindEventDecoder
|
||||
, clientEventWithoutRoomIdDecoder
|
||||
, encodeBlindEvent
|
||||
, encodeClientEventWithoutRoomId
|
||||
, encodeJoinedRoom
|
||||
, encodeLeftRoom
|
||||
, encodeRoomSummary
|
||||
, encodeRooms
|
||||
, encodeStrippedStateEvent
|
||||
, encodeSync
|
||||
, encodeTimeline
|
||||
, encodeUnreadNotificationCounts
|
||||
, encodeUnsignedData
|
||||
, joinedRoomDecoder
|
||||
, leftRoomDecoder
|
||||
, roomSummaryDecoder
|
||||
, roomsDecoder
|
||||
, strippedStateEventDecoder
|
||||
, syncDecoder
|
||||
, timelineDecoder
|
||||
, unreadNotificationCountsDecoder
|
||||
, unsignedDataDecoder
|
||||
)
|
||||
|
||||
{-| Automatically generated 'Objects'
|
||||
|
||||
Last generated at Unix time 1673279712
|
||||
|
||||
-}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
|
||||
import Internal.Tools.EncodeExtra exposing (maybeObject)
|
||||
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
{-| A blind event that does not give context about itself.
|
||||
-}
|
||||
type alias BlindEvent =
|
||||
{ content : E.Value
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeBlindEvent : BlindEvent -> E.Value
|
||||
encodeBlindEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
blindEventDecoder : D.Decoder BlindEvent
|
||||
blindEventDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ content = a, contentType = b }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| Client event that has all data except the room id.
|
||||
-}
|
||||
type alias ClientEventWithoutRoomId =
|
||||
{ content : E.Value
|
||||
, eventId : String
|
||||
, originServerTs : Timestamp
|
||||
, sender : String
|
||||
, stateKey : Maybe String
|
||||
, contentType : String
|
||||
, unsigned : Maybe UnsignedData
|
||||
}
|
||||
|
||||
|
||||
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
|
||||
encodeClientEventWithoutRoomId data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "event_id", Just <| E.string data.eventId )
|
||||
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Maybe.map E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
|
||||
]
|
||||
|
||||
|
||||
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
|
||||
clientEventWithoutRoomIdDecoder =
|
||||
D.map7
|
||||
(\a b c d e f g ->
|
||||
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "event_id" D.string)
|
||||
(D.field "origin_server_ts" timestampDecoder)
|
||||
(D.field "sender" D.string)
|
||||
(opField "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
|
||||
|
||||
|
||||
{-| Room that the user has joined.
|
||||
-}
|
||||
type alias JoinedRoom =
|
||||
{ accountData : List BlindEvent
|
||||
, ephemeral : List BlindEvent
|
||||
, state : List ClientEventWithoutRoomId
|
||||
, summary : Maybe RoomSummary
|
||||
, timeline : Maybe Timeline
|
||||
, unreadNotifications : Maybe UnreadNotificationCounts
|
||||
, unreadThreadNotifications : Dict String UnreadNotificationCounts
|
||||
}
|
||||
|
||||
|
||||
encodeJoinedRoom : JoinedRoom -> E.Value
|
||||
encodeJoinedRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "ephemeral", Just <| E.list encodeBlindEvent data.ephemeral )
|
||||
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
|
||||
, ( "summary", Maybe.map encodeRoomSummary data.summary )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
|
||||
, ( "unread_thread_notifications", Just <| E.dict identity encodeUnreadNotificationCounts data.unreadThreadNotifications )
|
||||
]
|
||||
|
||||
|
||||
joinedRoomDecoder : D.Decoder JoinedRoom
|
||||
joinedRoomDecoder =
|
||||
D.map7
|
||||
(\a b c d e f g ->
|
||||
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f, unreadThreadNotifications = g }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "ephemeral" (D.list blindEventDecoder))
|
||||
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opField "summary" roomSummaryDecoder)
|
||||
(opField "timeline" timelineDecoder)
|
||||
(opField "unread_notifications" unreadNotificationCountsDecoder)
|
||||
(D.field "unread_thread_notifications" (D.dict unreadNotificationCountsDecoder))
|
||||
|
||||
|
||||
{-| Room that the user has left.
|
||||
-}
|
||||
type alias LeftRoom =
|
||||
{ accountData : List BlindEvent
|
||||
, state : List ClientEventWithoutRoomId
|
||||
, timeline : Maybe Timeline
|
||||
}
|
||||
|
||||
|
||||
encodeLeftRoom : LeftRoom -> E.Value
|
||||
encodeLeftRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
]
|
||||
|
||||
|
||||
leftRoomDecoder : D.Decoder LeftRoom
|
||||
leftRoomDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ accountData = a, state = b, timeline = c }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opField "timeline" timelineDecoder)
|
||||
|
||||
|
||||
{-| Updates to rooms.
|
||||
-}
|
||||
type alias Rooms =
|
||||
{ invite : Dict String (List StrippedStateEvent)
|
||||
, join : Dict String JoinedRoom
|
||||
, knock : Dict String (List StrippedStateEvent)
|
||||
, leave : Dict String LeftRoom
|
||||
}
|
||||
|
||||
|
||||
encodeRooms : Rooms -> E.Value
|
||||
encodeRooms data =
|
||||
maybeObject
|
||||
[ ( "invite", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.invite )
|
||||
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
|
||||
, ( "knock", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.knock )
|
||||
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
|
||||
]
|
||||
|
||||
|
||||
roomsDecoder : D.Decoder Rooms
|
||||
roomsDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ invite = a, join = b, knock = c, leave = d }
|
||||
)
|
||||
(opFieldWithDefault "invite" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
|
||||
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
|
||||
(opFieldWithDefault "knock" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
|
||||
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
|
||||
|
||||
|
||||
{-| Information about a room which clients may need to correctly render it to users.
|
||||
-}
|
||||
type alias RoomSummary =
|
||||
{ mHeroes : Maybe (List String)
|
||||
, mInvitedMemberCount : Maybe Int
|
||||
, mJoinedMemberCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeRoomSummary : RoomSummary -> E.Value
|
||||
encodeRoomSummary data =
|
||||
maybeObject
|
||||
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
|
||||
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
|
||||
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
|
||||
]
|
||||
|
||||
|
||||
roomSummaryDecoder : D.Decoder RoomSummary
|
||||
roomSummaryDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
|
||||
)
|
||||
(opField "m.heroes" (D.list D.string))
|
||||
(opField "m.invited_member_count" D.int)
|
||||
(opField "m.joined_member_count" D.int)
|
||||
|
||||
|
||||
{-| Stripped state events of a room that the user has limited access to.
|
||||
-}
|
||||
type alias StrippedStateEvent =
|
||||
{ content : E.Value
|
||||
, sender : String
|
||||
, stateKey : String
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
|
||||
encodeStrippedStateEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Just <| E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
strippedStateEventDecoder : D.Decoder StrippedStateEvent
|
||||
strippedStateEventDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ content = a, sender = b, stateKey = c, contentType = d }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "sender" D.string)
|
||||
(D.field "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| The sync response the homeserver sends to the user.
|
||||
-}
|
||||
type alias Sync =
|
||||
{ accountData : List BlindEvent
|
||||
, nextBatch : String
|
||||
, presence : List BlindEvent
|
||||
, rooms : Maybe Rooms
|
||||
}
|
||||
|
||||
|
||||
encodeSync : Sync -> E.Value
|
||||
encodeSync data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "next_batch", Just <| E.string data.nextBatch )
|
||||
, ( "presence", Just <| E.list encodeBlindEvent data.presence )
|
||||
, ( "rooms", Maybe.map encodeRooms data.rooms )
|
||||
]
|
||||
|
||||
|
||||
syncDecoder : D.Decoder Sync
|
||||
syncDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ accountData = a, nextBatch = b, presence = c, rooms = d }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "next_batch" D.string)
|
||||
(D.field "presence" (D.list blindEventDecoder))
|
||||
(opField "rooms" roomsDecoder)
|
||||
|
||||
|
||||
{-| The timeline of messages and state changes in a room.
|
||||
-}
|
||||
type alias Timeline =
|
||||
{ events : List ClientEventWithoutRoomId
|
||||
, limited : Bool
|
||||
, prevBatch : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeTimeline : Timeline -> E.Value
|
||||
encodeTimeline data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
|
||||
, ( "limited", Just <| E.bool data.limited )
|
||||
, ( "prev_batch", Maybe.map E.string data.prevBatch )
|
||||
]
|
||||
|
||||
|
||||
timelineDecoder : D.Decoder Timeline
|
||||
timelineDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ events = a, limited = b, prevBatch = c }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opFieldWithDefault "limited" False D.bool)
|
||||
(opField "prev_batch" D.string)
|
||||
|
||||
|
||||
{-| Counts of unread notifications for this room.
|
||||
-}
|
||||
type alias UnreadNotificationCounts =
|
||||
{ highlightCount : Maybe Int
|
||||
, notificationCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
|
||||
encodeUnreadNotificationCounts data =
|
||||
maybeObject
|
||||
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
|
||||
, ( "notification_count", Maybe.map E.int data.notificationCount )
|
||||
]
|
||||
|
||||
|
||||
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
|
||||
unreadNotificationCountsDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ highlightCount = a, notificationCount = b }
|
||||
)
|
||||
(opField "highlight_count" D.int)
|
||||
(opField "notification_count" D.int)
|
||||
|
||||
|
||||
{-| Data that isn't getting signed for Canonical JSON.
|
||||
-}
|
||||
type UnsignedData
|
||||
= UnsignedData
|
||||
{ age : Maybe Int
|
||||
, prevContent : Maybe E.Value
|
||||
, redactedBecause : Maybe ClientEventWithoutRoomId
|
||||
, transactionId : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeUnsignedData : UnsignedData -> E.Value
|
||||
encodeUnsignedData (UnsignedData data) =
|
||||
maybeObject
|
||||
[ ( "age", Maybe.map E.int data.age )
|
||||
, ( "prev_content", data.prevContent )
|
||||
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
|
||||
, ( "transaction_id", Maybe.map E.string data.transactionId )
|
||||
]
|
||||
|
||||
|
||||
unsignedDataDecoder : D.Decoder UnsignedData
|
||||
unsignedDataDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
|
||||
)
|
||||
(opField "age" D.int)
|
||||
(opField "prev_content" D.value)
|
||||
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
|
||||
(opField "transaction_id" D.string)
|
|
@ -1,155 +0,0 @@
|
|||
version: v1.4
|
||||
name: Objects
|
||||
objects:
|
||||
Sync:
|
||||
description: The sync response the homeserver sends to the user.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
next_batch:
|
||||
type: string
|
||||
required: true
|
||||
presence:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
rooms:
|
||||
type: Rooms
|
||||
BlindEvent:
|
||||
description: A blind event that does not give context about itself.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
Rooms:
|
||||
description: Updates to rooms.
|
||||
fields:
|
||||
invite:
|
||||
type: "{[StrippedStateEvent]}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
join:
|
||||
type: "{JoinedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
knock:
|
||||
type: "{[StrippedStateEvent]}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
leave:
|
||||
type: "{LeftRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
StrippedStateEvent:
|
||||
description: Stripped state events of a room that the user has limited access to.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
JoinedRoom:
|
||||
description: Room that the user has joined.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
ephemeral:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
state:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: true
|
||||
summary:
|
||||
type: RoomSummary
|
||||
timeline:
|
||||
type: Timeline
|
||||
unread_notifications:
|
||||
type: UnreadNotificationCounts
|
||||
unread_thread_notifications:
|
||||
type: "{UnreadNotificationCounts}"
|
||||
required: true
|
||||
ClientEventWithoutRoomId:
|
||||
description: Client event that has all data except the room id.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
event_id:
|
||||
type: string
|
||||
required: true
|
||||
origin_server_ts:
|
||||
type: timestamp
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
unsigned:
|
||||
type: UnsignedData
|
||||
UnsignedData:
|
||||
anti_recursion: true
|
||||
description: Data that isn't getting signed for Canonical JSON.
|
||||
fields:
|
||||
age:
|
||||
type: int
|
||||
prev_content:
|
||||
type: value
|
||||
redacted_because:
|
||||
type: ClientEventWithoutRoomId
|
||||
transaction_id:
|
||||
type: string
|
||||
RoomSummary:
|
||||
description: Information about a room which clients may need to correctly render it to users.
|
||||
fields:
|
||||
m.heroes:
|
||||
type: "[string]"
|
||||
m.invited_member_count:
|
||||
type: int
|
||||
m.joined_member_count:
|
||||
type: int
|
||||
Timeline:
|
||||
description: The timeline of messages and state changes in a room.
|
||||
fields:
|
||||
events:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: false
|
||||
default: "[]"
|
||||
limited:
|
||||
type: bool
|
||||
required: false
|
||||
default: "False"
|
||||
prev_batch:
|
||||
type: string
|
||||
UnreadNotificationCounts:
|
||||
description: Counts of unread notifications for this room.
|
||||
fields:
|
||||
highlight_count:
|
||||
type: int
|
||||
notification_count:
|
||||
type: int
|
||||
LeftRoom:
|
||||
description: Room that the user has left.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
state:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: true
|
||||
timeline:
|
||||
type: Timeline
|
|
@ -1,635 +0,0 @@
|
|||
module Internal.Api.Sync.V1_4.SpecObjects exposing
|
||||
( AccountData
|
||||
, ClientEventWithoutRoomId
|
||||
, Ephemeral
|
||||
, Event
|
||||
, InviteState
|
||||
, InvitedRoom
|
||||
, JoinedRoom
|
||||
, KnockState
|
||||
, KnockedRoom
|
||||
, LeftRoom
|
||||
, Presence
|
||||
, RoomSummary
|
||||
, Rooms
|
||||
, State
|
||||
, StrippedStateEvent
|
||||
, Sync
|
||||
, ThreadNotificationCounts
|
||||
, Timeline
|
||||
, UnreadNotificationCounts
|
||||
, UnsignedData(..)
|
||||
, accountDataDecoder
|
||||
, clientEventWithoutRoomIdDecoder
|
||||
, encodeAccountData
|
||||
, encodeClientEventWithoutRoomId
|
||||
, encodeEphemeral
|
||||
, encodeEvent
|
||||
, encodeInviteState
|
||||
, encodeInvitedRoom
|
||||
, encodeJoinedRoom
|
||||
, encodeKnockState
|
||||
, encodeKnockedRoom
|
||||
, encodeLeftRoom
|
||||
, encodePresence
|
||||
, encodeRoomSummary
|
||||
, encodeRooms
|
||||
, encodeState
|
||||
, encodeStrippedStateEvent
|
||||
, encodeSync
|
||||
, encodeThreadNotificationCounts
|
||||
, encodeTimeline
|
||||
, encodeUnreadNotificationCounts
|
||||
, encodeUnsignedData
|
||||
, ephemeralDecoder
|
||||
, eventDecoder
|
||||
, inviteStateDecoder
|
||||
, invitedRoomDecoder
|
||||
, joinedRoomDecoder
|
||||
, knockStateDecoder
|
||||
, knockedRoomDecoder
|
||||
, leftRoomDecoder
|
||||
, presenceDecoder
|
||||
, roomSummaryDecoder
|
||||
, roomsDecoder
|
||||
, stateDecoder
|
||||
, strippedStateEventDecoder
|
||||
, syncDecoder
|
||||
, threadNotificationCountsDecoder
|
||||
, timelineDecoder
|
||||
, unreadNotificationCountsDecoder
|
||||
, unsignedDataDecoder
|
||||
)
|
||||
|
||||
{-| Automatically generated 'SpecObjects'
|
||||
|
||||
Last generated at Unix time 1673279712
|
||||
|
||||
-}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
|
||||
import Internal.Tools.EncodeExtra exposing (maybeObject)
|
||||
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
{-| The private data created by this user in a given context.
|
||||
-}
|
||||
type alias AccountData =
|
||||
{ events : List Event
|
||||
}
|
||||
|
||||
|
||||
encodeAccountData : AccountData -> E.Value
|
||||
encodeAccountData data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
accountDataDecoder : D.Decoder AccountData
|
||||
accountDataDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list eventDecoder))
|
||||
|
||||
|
||||
{-| Client event that has all data except the room id.
|
||||
-}
|
||||
type alias ClientEventWithoutRoomId =
|
||||
{ content : E.Value
|
||||
, eventId : String
|
||||
, originServerTs : Timestamp
|
||||
, sender : String
|
||||
, stateKey : Maybe String
|
||||
, contentType : String
|
||||
, unsigned : Maybe UnsignedData
|
||||
}
|
||||
|
||||
|
||||
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
|
||||
encodeClientEventWithoutRoomId data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "event_id", Just <| E.string data.eventId )
|
||||
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Maybe.map E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
|
||||
]
|
||||
|
||||
|
||||
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
|
||||
clientEventWithoutRoomIdDecoder =
|
||||
D.map7
|
||||
(\a b c d e f g ->
|
||||
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "event_id" D.string)
|
||||
(D.field "origin_server_ts" timestampDecoder)
|
||||
(D.field "sender" D.string)
|
||||
(opField "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
|
||||
|
||||
|
||||
{-| Ephemeral events in a room that aren't recorded in the timeline or the room state.
|
||||
-}
|
||||
type alias Ephemeral =
|
||||
{ events : List Event
|
||||
}
|
||||
|
||||
|
||||
encodeEphemeral : Ephemeral -> E.Value
|
||||
encodeEphemeral data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
ephemeralDecoder : D.Decoder Ephemeral
|
||||
ephemeralDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list eventDecoder))
|
||||
|
||||
|
||||
{-| A blind event that does not give context about itself.
|
||||
-}
|
||||
type alias Event =
|
||||
{ content : E.Value
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeEvent : Event -> E.Value
|
||||
encodeEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
eventDecoder : D.Decoder Event
|
||||
eventDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ content = a, contentType = b }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| Room that the user has been invited to.
|
||||
-}
|
||||
type alias InvitedRoom =
|
||||
{ inviteState : Maybe InviteState
|
||||
}
|
||||
|
||||
|
||||
encodeInvitedRoom : InvitedRoom -> E.Value
|
||||
encodeInvitedRoom data =
|
||||
maybeObject
|
||||
[ ( "invite_state", Maybe.map encodeInviteState data.inviteState )
|
||||
]
|
||||
|
||||
|
||||
invitedRoomDecoder : D.Decoder InvitedRoom
|
||||
invitedRoomDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ inviteState = a }
|
||||
)
|
||||
(opField "invite_state" inviteStateDecoder)
|
||||
|
||||
|
||||
{-| The state of a room that the user has been invited to.
|
||||
-}
|
||||
type alias InviteState =
|
||||
{ events : List StrippedStateEvent
|
||||
}
|
||||
|
||||
|
||||
encodeInviteState : InviteState -> E.Value
|
||||
encodeInviteState data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeStrippedStateEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
inviteStateDecoder : D.Decoder InviteState
|
||||
inviteStateDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list strippedStateEventDecoder))
|
||||
|
||||
|
||||
{-| Room that the user has joined.
|
||||
-}
|
||||
type alias JoinedRoom =
|
||||
{ accountData : Maybe AccountData
|
||||
, ephemeral : Maybe Ephemeral
|
||||
, state : Maybe State
|
||||
, summary : Maybe RoomSummary
|
||||
, timeline : Maybe Timeline
|
||||
, unreadNotifications : Maybe UnreadNotificationCounts
|
||||
, unreadThreadNotifications : Dict String ThreadNotificationCounts
|
||||
}
|
||||
|
||||
|
||||
encodeJoinedRoom : JoinedRoom -> E.Value
|
||||
encodeJoinedRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
|
||||
, ( "ephemeral", Maybe.map encodeEphemeral data.ephemeral )
|
||||
, ( "state", Maybe.map encodeState data.state )
|
||||
, ( "summary", Maybe.map encodeRoomSummary data.summary )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
|
||||
, ( "unread_thread_notifications", Just <| E.dict identity encodeThreadNotificationCounts data.unreadThreadNotifications )
|
||||
]
|
||||
|
||||
|
||||
joinedRoomDecoder : D.Decoder JoinedRoom
|
||||
joinedRoomDecoder =
|
||||
D.map7
|
||||
(\a b c d e f g ->
|
||||
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f, unreadThreadNotifications = g }
|
||||
)
|
||||
(opField "account_data" accountDataDecoder)
|
||||
(opField "ephemeral" ephemeralDecoder)
|
||||
(opField "state" stateDecoder)
|
||||
(opField "summary" roomSummaryDecoder)
|
||||
(opField "timeline" timelineDecoder)
|
||||
(opField "unread_notifications" unreadNotificationCountsDecoder)
|
||||
(opFieldWithDefault "unread_thread_notifications" Dict.empty (D.dict threadNotificationCountsDecoder))
|
||||
|
||||
|
||||
{-| Room that the user has knocked upon.
|
||||
-}
|
||||
type alias KnockedRoom =
|
||||
{ knockState : Maybe KnockState
|
||||
}
|
||||
|
||||
|
||||
encodeKnockedRoom : KnockedRoom -> E.Value
|
||||
encodeKnockedRoom data =
|
||||
maybeObject
|
||||
[ ( "knock_state", Maybe.map encodeKnockState data.knockState )
|
||||
]
|
||||
|
||||
|
||||
knockedRoomDecoder : D.Decoder KnockedRoom
|
||||
knockedRoomDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ knockState = a }
|
||||
)
|
||||
(opField "knock_state" knockStateDecoder)
|
||||
|
||||
|
||||
{-| The state of a room that the user has knocked upon.
|
||||
-}
|
||||
type alias KnockState =
|
||||
{ events : List StrippedStateEvent
|
||||
}
|
||||
|
||||
|
||||
encodeKnockState : KnockState -> E.Value
|
||||
encodeKnockState data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeStrippedStateEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
knockStateDecoder : D.Decoder KnockState
|
||||
knockStateDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list strippedStateEventDecoder))
|
||||
|
||||
|
||||
{-| Room that the user has left.
|
||||
-}
|
||||
type alias LeftRoom =
|
||||
{ accountData : Maybe AccountData
|
||||
, state : Maybe State
|
||||
, timeline : Maybe Timeline
|
||||
}
|
||||
|
||||
|
||||
encodeLeftRoom : LeftRoom -> E.Value
|
||||
encodeLeftRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
|
||||
, ( "state", Maybe.map encodeState data.state )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
]
|
||||
|
||||
|
||||
leftRoomDecoder : D.Decoder LeftRoom
|
||||
leftRoomDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ accountData = a, state = b, timeline = c }
|
||||
)
|
||||
(opField "account_data" accountDataDecoder)
|
||||
(opField "state" stateDecoder)
|
||||
(opField "timeline" timelineDecoder)
|
||||
|
||||
|
||||
{-| The updates to the presence status of other users.
|
||||
-}
|
||||
type alias Presence =
|
||||
{ events : List Event
|
||||
}
|
||||
|
||||
|
||||
encodePresence : Presence -> E.Value
|
||||
encodePresence data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeEvent data.events )
|
||||
]
|
||||
|
||||
|
||||
presenceDecoder : D.Decoder Presence
|
||||
presenceDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list eventDecoder))
|
||||
|
||||
|
||||
{-| Updates to rooms.
|
||||
-}
|
||||
type alias Rooms =
|
||||
{ invite : Dict String InvitedRoom
|
||||
, join : Dict String JoinedRoom
|
||||
, knock : Dict String KnockedRoom
|
||||
, leave : Dict String LeftRoom
|
||||
}
|
||||
|
||||
|
||||
encodeRooms : Rooms -> E.Value
|
||||
encodeRooms data =
|
||||
maybeObject
|
||||
[ ( "invite", Just <| E.dict identity encodeInvitedRoom data.invite )
|
||||
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
|
||||
, ( "knock", Just <| E.dict identity encodeKnockedRoom data.knock )
|
||||
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
|
||||
]
|
||||
|
||||
|
||||
roomsDecoder : D.Decoder Rooms
|
||||
roomsDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ invite = a, join = b, knock = c, leave = d }
|
||||
)
|
||||
(opFieldWithDefault "invite" Dict.empty (D.dict invitedRoomDecoder))
|
||||
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
|
||||
(opFieldWithDefault "knock" Dict.empty (D.dict knockedRoomDecoder))
|
||||
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
|
||||
|
||||
|
||||
{-| Information about a room which clients may need to correctly render it to users.
|
||||
-}
|
||||
type alias RoomSummary =
|
||||
{ mHeroes : Maybe (List String)
|
||||
, mInvitedMemberCount : Maybe Int
|
||||
, mJoinedMemberCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeRoomSummary : RoomSummary -> E.Value
|
||||
encodeRoomSummary data =
|
||||
maybeObject
|
||||
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
|
||||
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
|
||||
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
|
||||
]
|
||||
|
||||
|
||||
roomSummaryDecoder : D.Decoder RoomSummary
|
||||
roomSummaryDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
|
||||
)
|
||||
(opField "m.heroes" (D.list D.string))
|
||||
(opField "m.invited_member_count" D.int)
|
||||
(opField "m.joined_member_count" D.int)
|
||||
|
||||
|
||||
{-| Updates to the state of a room.
|
||||
-}
|
||||
type alias State =
|
||||
{ events : List ClientEventWithoutRoomId
|
||||
}
|
||||
|
||||
|
||||
encodeState : State -> E.Value
|
||||
encodeState data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
|
||||
]
|
||||
|
||||
|
||||
stateDecoder : D.Decoder State
|
||||
stateDecoder =
|
||||
D.map
|
||||
(\a ->
|
||||
{ events = a }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
|
||||
|
||||
|
||||
{-| Stripped state events of a room that the user has limited access to.
|
||||
-}
|
||||
type alias StrippedStateEvent =
|
||||
{ content : E.Value
|
||||
, sender : String
|
||||
, stateKey : String
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
|
||||
encodeStrippedStateEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Just <| E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
strippedStateEventDecoder : D.Decoder StrippedStateEvent
|
||||
strippedStateEventDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ content = a, sender = b, stateKey = c, contentType = d }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "sender" D.string)
|
||||
(D.field "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| The sync response the homeserver sends to the user.
|
||||
-}
|
||||
type alias Sync =
|
||||
{ accountData : Maybe AccountData
|
||||
, nextBatch : String
|
||||
, presence : Maybe Presence
|
||||
, rooms : Maybe Rooms
|
||||
}
|
||||
|
||||
|
||||
encodeSync : Sync -> E.Value
|
||||
encodeSync data =
|
||||
maybeObject
|
||||
[ ( "account_data", Maybe.map encodeAccountData data.accountData )
|
||||
, ( "next_batch", Just <| E.string data.nextBatch )
|
||||
, ( "presence", Maybe.map encodePresence data.presence )
|
||||
, ( "rooms", Maybe.map encodeRooms data.rooms )
|
||||
]
|
||||
|
||||
|
||||
syncDecoder : D.Decoder Sync
|
||||
syncDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ accountData = a, nextBatch = b, presence = c, rooms = d }
|
||||
)
|
||||
(opField "account_data" accountDataDecoder)
|
||||
(D.field "next_batch" D.string)
|
||||
(opField "presence" presenceDecoder)
|
||||
(opField "rooms" roomsDecoder)
|
||||
|
||||
|
||||
{-| Counts of unread notifications for a given thread.
|
||||
-}
|
||||
type alias ThreadNotificationCounts =
|
||||
{ highlightCount : Maybe Int
|
||||
, notificationCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeThreadNotificationCounts : ThreadNotificationCounts -> E.Value
|
||||
encodeThreadNotificationCounts data =
|
||||
maybeObject
|
||||
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
|
||||
, ( "notification_count", Maybe.map E.int data.notificationCount )
|
||||
]
|
||||
|
||||
|
||||
threadNotificationCountsDecoder : D.Decoder ThreadNotificationCounts
|
||||
threadNotificationCountsDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ highlightCount = a, notificationCount = b }
|
||||
)
|
||||
(opField "highlight_count" D.int)
|
||||
(opField "notification_count" D.int)
|
||||
|
||||
|
||||
{-| The timeline of messages and state changes in a room.
|
||||
-}
|
||||
type alias Timeline =
|
||||
{ events : List ClientEventWithoutRoomId
|
||||
, limited : Bool
|
||||
, prevBatch : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeTimeline : Timeline -> E.Value
|
||||
encodeTimeline data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
|
||||
, ( "limited", Just <| E.bool data.limited )
|
||||
, ( "prev_batch", Maybe.map E.string data.prevBatch )
|
||||
]
|
||||
|
||||
|
||||
timelineDecoder : D.Decoder Timeline
|
||||
timelineDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ events = a, limited = b, prevBatch = c }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opFieldWithDefault "limited" False D.bool)
|
||||
(opField "prev_batch" D.string)
|
||||
|
||||
|
||||
{-| Counts of unread notifications for this room.
|
||||
-}
|
||||
type alias UnreadNotificationCounts =
|
||||
{ highlightCount : Maybe Int
|
||||
, notificationCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
|
||||
encodeUnreadNotificationCounts data =
|
||||
maybeObject
|
||||
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
|
||||
, ( "notification_count", Maybe.map E.int data.notificationCount )
|
||||
]
|
||||
|
||||
|
||||
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
|
||||
unreadNotificationCountsDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ highlightCount = a, notificationCount = b }
|
||||
)
|
||||
(opField "highlight_count" D.int)
|
||||
(opField "notification_count" D.int)
|
||||
|
||||
|
||||
{-| Data that isn't getting signed for Canonical JSON.
|
||||
-}
|
||||
type UnsignedData
|
||||
= UnsignedData
|
||||
{ age : Maybe Int
|
||||
, prevContent : Maybe E.Value
|
||||
, redactedBecause : Maybe ClientEventWithoutRoomId
|
||||
, transactionId : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeUnsignedData : UnsignedData -> E.Value
|
||||
encodeUnsignedData (UnsignedData data) =
|
||||
maybeObject
|
||||
[ ( "age", Maybe.map E.int data.age )
|
||||
, ( "prev_content", data.prevContent )
|
||||
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
|
||||
, ( "transaction_id", Maybe.map E.string data.transactionId )
|
||||
]
|
||||
|
||||
|
||||
unsignedDataDecoder : D.Decoder UnsignedData
|
||||
unsignedDataDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
|
||||
)
|
||||
(opField "age" D.int)
|
||||
(opField "prev_content" D.value)
|
||||
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
|
||||
(opField "transaction_id" D.string)
|
|
@ -1,208 +0,0 @@
|
|||
version: v1.4
|
||||
name: SpecObjects
|
||||
objects:
|
||||
Sync:
|
||||
description: The sync response the homeserver sends to the user.
|
||||
fields:
|
||||
account_data:
|
||||
type: AccountData
|
||||
next_batch:
|
||||
type: string
|
||||
required: true
|
||||
presence:
|
||||
type: Presence
|
||||
rooms:
|
||||
type: Rooms
|
||||
AccountData:
|
||||
description: The private data created by this user in a given context.
|
||||
fields:
|
||||
events:
|
||||
type: "[Event]"
|
||||
required: false
|
||||
default: "[]"
|
||||
Event:
|
||||
description: A blind event that does not give context about itself.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
Presence:
|
||||
description: The updates to the presence status of other users.
|
||||
fields:
|
||||
events:
|
||||
type: "[Event]"
|
||||
required: false
|
||||
default: "[]"
|
||||
Rooms:
|
||||
description: Updates to rooms.
|
||||
fields:
|
||||
invite:
|
||||
type: "{InvitedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
join:
|
||||
type: "{JoinedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
knock:
|
||||
type: "{KnockedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
leave:
|
||||
type: "{LeftRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
InvitedRoom:
|
||||
description: Room that the user has been invited to.
|
||||
fields:
|
||||
invite_state:
|
||||
type: InviteState
|
||||
InviteState:
|
||||
description: The state of a room that the user has been invited to.
|
||||
fields:
|
||||
events:
|
||||
type: "[StrippedStateEvent]"
|
||||
required: false
|
||||
default: "[]"
|
||||
StrippedStateEvent:
|
||||
description: Stripped state events of a room that the user has limited access to.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
JoinedRoom:
|
||||
description: Room that the user has joined.
|
||||
fields:
|
||||
account_data:
|
||||
type: AccountData
|
||||
ephemeral:
|
||||
type: Ephemeral
|
||||
state:
|
||||
type: State
|
||||
summary:
|
||||
type: RoomSummary
|
||||
timeline:
|
||||
type: Timeline
|
||||
unread_notifications:
|
||||
type: UnreadNotificationCounts
|
||||
unread_thread_notifications:
|
||||
type: "{ThreadNotificationCounts}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
Ephemeral:
|
||||
description: Ephemeral events in a room that aren't recorded in the timeline or the room state.
|
||||
fields:
|
||||
events:
|
||||
type: "[Event]"
|
||||
required: false
|
||||
default: "[]"
|
||||
State:
|
||||
description: Updates to the state of a room.
|
||||
fields:
|
||||
events:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: false
|
||||
default: "[]"
|
||||
ClientEventWithoutRoomId:
|
||||
description: Client event that has all data except the room id.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
event_id:
|
||||
type: string
|
||||
required: true
|
||||
origin_server_ts:
|
||||
type: timestamp
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
unsigned:
|
||||
type: UnsignedData
|
||||
UnsignedData:
|
||||
anti_recursion: true
|
||||
description: Data that isn't getting signed for Canonical JSON.
|
||||
fields:
|
||||
age:
|
||||
type: int
|
||||
prev_content:
|
||||
type: value
|
||||
redacted_because:
|
||||
type: ClientEventWithoutRoomId
|
||||
transaction_id:
|
||||
type: string
|
||||
RoomSummary:
|
||||
description: Information about a room which clients may need to correctly render it to users.
|
||||
fields:
|
||||
m.heroes:
|
||||
type: "[string]"
|
||||
m.invited_member_count:
|
||||
type: int
|
||||
m.joined_member_count:
|
||||
type: int
|
||||
Timeline:
|
||||
description: The timeline of messages and state changes in a room.
|
||||
fields:
|
||||
events:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: false
|
||||
default: "[]"
|
||||
limited:
|
||||
type: bool
|
||||
required: false
|
||||
default: "False"
|
||||
prev_batch:
|
||||
type: string
|
||||
UnreadNotificationCounts:
|
||||
description: Counts of unread notifications for this room.
|
||||
fields:
|
||||
highlight_count:
|
||||
type: int
|
||||
notification_count:
|
||||
type: int
|
||||
ThreadNotificationCounts:
|
||||
description: Counts of unread notifications for a given thread.
|
||||
fields:
|
||||
highlight_count:
|
||||
type: int
|
||||
notification_count:
|
||||
type: int
|
||||
KnockedRoom:
|
||||
description: Room that the user has knocked upon.
|
||||
fields:
|
||||
knock_state:
|
||||
type: KnockState
|
||||
KnockState:
|
||||
description: The state of a room that the user has knocked upon.
|
||||
fields:
|
||||
events:
|
||||
type: "[StrippedStateEvent]"
|
||||
required: false
|
||||
default: "[]"
|
||||
LeftRoom:
|
||||
description: Room that the user has left.
|
||||
fields:
|
||||
account_data:
|
||||
type: AccountData
|
||||
state:
|
||||
type: State
|
||||
timeline:
|
||||
type: Timeline
|
|
@ -1,73 +0,0 @@
|
|||
module Internal.Api.Sync.V1_4.Upcast exposing (..)
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Sync.V1_3.Objects as PO
|
||||
import Internal.Api.Sync.V1_4.Objects as O
|
||||
|
||||
|
||||
upcast : PO.Sync -> O.Sync
|
||||
upcast sync =
|
||||
{ accountData = sync.accountData
|
||||
, nextBatch = sync.nextBatch
|
||||
, presence = sync.presence
|
||||
, rooms = Maybe.map upcastRooms sync.rooms
|
||||
}
|
||||
|
||||
|
||||
upcastRooms : PO.Rooms -> O.Rooms
|
||||
upcastRooms rooms =
|
||||
{ invite = rooms.invite
|
||||
, join = Dict.map (\_ -> upcastJoinedRoom) rooms.join
|
||||
, knock = rooms.knock
|
||||
, leave = Dict.map (\_ -> upcastLeftRoom) rooms.leave
|
||||
}
|
||||
|
||||
|
||||
upcastJoinedRoom : PO.JoinedRoom -> O.JoinedRoom
|
||||
upcastJoinedRoom room =
|
||||
{ accountData = room.accountData
|
||||
, ephemeral = room.ephemeral
|
||||
, state = List.map upcastClientEventWithoutRoomId room.state
|
||||
, summary = room.summary
|
||||
, timeline = Maybe.map upcastTimeline room.timeline
|
||||
, unreadNotifications = room.unreadNotifications
|
||||
, unreadThreadNotifications = Dict.empty
|
||||
}
|
||||
|
||||
|
||||
upcastClientEventWithoutRoomId : PO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
|
||||
upcastClientEventWithoutRoomId event =
|
||||
{ content = event.content
|
||||
, eventId = event.eventId
|
||||
, originServerTs = event.originServerTs
|
||||
, sender = event.sender
|
||||
, stateKey = event.stateKey
|
||||
, contentType = event.contentType
|
||||
, unsigned = Maybe.map upcastUnsigned event.unsigned
|
||||
}
|
||||
|
||||
|
||||
upcastUnsigned : PO.UnsignedData -> O.UnsignedData
|
||||
upcastUnsigned (PO.UnsignedData data) =
|
||||
O.UnsignedData
|
||||
{ age = data.age
|
||||
, prevContent = data.prevContent
|
||||
, redactedBecause = Maybe.map upcastClientEventWithoutRoomId data.redactedBecause
|
||||
, transactionId = data.transactionId
|
||||
}
|
||||
|
||||
|
||||
upcastTimeline : PO.Timeline -> O.Timeline
|
||||
upcastTimeline timeline =
|
||||
{ events = List.map upcastClientEventWithoutRoomId timeline.events
|
||||
, limited = timeline.limited
|
||||
, prevBatch = timeline.prevBatch
|
||||
}
|
||||
|
||||
|
||||
upcastLeftRoom : PO.LeftRoom -> O.LeftRoom
|
||||
upcastLeftRoom room =
|
||||
{ accountData = room.accountData
|
||||
, state = List.map upcastClientEventWithoutRoomId room.state
|
||||
, timeline = Maybe.map upcastTimeline room.timeline
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
module Internal.Api.Sync.V1_5.Api exposing (..)
|
||||
|
||||
import Internal.Api.Sync.Api as Api
|
||||
import Internal.Api.Sync.V1_4.Objects as PO
|
||||
import Internal.Api.Sync.V1_5.Convert as C
|
||||
import Internal.Api.Sync.V1_5.Objects as O
|
||||
import Internal.Api.Sync.V1_5.SpecObjects as SO
|
||||
import Internal.Api.Sync.V1_5.Upcast as U
|
||||
import Internal.Api.VersionControl as V
|
||||
|
||||
|
||||
packet : V.SingleVersion Api.SyncInputV1 PO.Sync Api.SyncInputV1 O.Sync
|
||||
packet =
|
||||
{ version = "v1.5"
|
||||
, downcast = identity
|
||||
, current = Api.syncV1 SO.syncDecoder C.convert
|
||||
, upcast = U.upcast
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
module Internal.Api.Sync.V1_5.Convert exposing (..)
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Sync.V1_5.Objects as O
|
||||
import Internal.Api.Sync.V1_5.SpecObjects as SO
|
||||
|
||||
|
||||
convert : SO.Sync -> O.Sync
|
||||
convert sync =
|
||||
{ accountData = convertEventHolder sync.accountData
|
||||
, nextBatch = sync.nextBatch
|
||||
, presence = convertEventHolder sync.presence
|
||||
, rooms = Maybe.map convertRooms sync.rooms
|
||||
}
|
||||
|
||||
|
||||
convertEventHolder : Maybe { a | events : List b } -> List b
|
||||
convertEventHolder =
|
||||
Maybe.map .events >> Maybe.withDefault []
|
||||
|
||||
|
||||
convertRooms : SO.Rooms -> O.Rooms
|
||||
convertRooms rooms =
|
||||
{ invite =
|
||||
Dict.map
|
||||
(\_ -> .inviteState >> Maybe.map .events >> Maybe.withDefault [])
|
||||
rooms.invite
|
||||
, join = Dict.map (\_ -> convertJoinedRoom) rooms.join
|
||||
, knock =
|
||||
Dict.map
|
||||
(\_ -> .knockState >> Maybe.map .events >> Maybe.withDefault [])
|
||||
rooms.knock
|
||||
, leave = Dict.map (\_ -> convertLeftRoom) rooms.leave
|
||||
}
|
||||
|
||||
|
||||
convertJoinedRoom : SO.JoinedRoom -> O.JoinedRoom
|
||||
convertJoinedRoom room =
|
||||
{ accountData = convertEventHolder room.accountData
|
||||
, ephemeral = convertEventHolder room.ephemeral
|
||||
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
|
||||
, summary = room.summary
|
||||
, timeline = Maybe.map convertTimeline room.timeline
|
||||
, unreadNotifications = room.unreadNotifications
|
||||
, unreadThreadNotifications = room.unreadThreadNotifications
|
||||
}
|
||||
|
||||
|
||||
convertClientEventWithoutRoomId : SO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
|
||||
convertClientEventWithoutRoomId event =
|
||||
{ content = event.content
|
||||
, eventId = event.eventId
|
||||
, originServerTs = event.originServerTs
|
||||
, sender = event.sender
|
||||
, stateKey = event.stateKey
|
||||
, contentType = event.contentType
|
||||
, unsigned = Maybe.map convertUnsigned event.unsigned
|
||||
}
|
||||
|
||||
|
||||
convertUnsigned : SO.UnsignedData -> O.UnsignedData
|
||||
convertUnsigned (SO.UnsignedData data) =
|
||||
O.UnsignedData
|
||||
{ age = data.age
|
||||
, prevContent = data.prevContent
|
||||
, redactedBecause = Maybe.map convertClientEventWithoutRoomId data.redactedBecause
|
||||
, transactionId = data.transactionId
|
||||
}
|
||||
|
||||
|
||||
convertTimeline : SO.Timeline -> O.Timeline
|
||||
convertTimeline timeline =
|
||||
{ events = List.map convertClientEventWithoutRoomId timeline.events
|
||||
, limited = timeline.limited
|
||||
, prevBatch = timeline.prevBatch
|
||||
}
|
||||
|
||||
|
||||
convertLeftRoom : SO.LeftRoom -> O.LeftRoom
|
||||
convertLeftRoom room =
|
||||
{ accountData = convertEventHolder room.accountData
|
||||
, state = convertEventHolder room.state |> List.map convertClientEventWithoutRoomId
|
||||
, timeline = Maybe.map convertTimeline room.timeline
|
||||
}
|
|
@ -1,398 +0,0 @@
|
|||
module Internal.Api.Sync.V1_5.Objects exposing
|
||||
( BlindEvent
|
||||
, ClientEventWithoutRoomId
|
||||
, JoinedRoom
|
||||
, LeftRoom
|
||||
, RoomSummary
|
||||
, Rooms
|
||||
, StrippedStateEvent
|
||||
, Sync
|
||||
, Timeline
|
||||
, UnreadNotificationCounts
|
||||
, UnsignedData(..)
|
||||
, blindEventDecoder
|
||||
, clientEventWithoutRoomIdDecoder
|
||||
, encodeBlindEvent
|
||||
, encodeClientEventWithoutRoomId
|
||||
, encodeJoinedRoom
|
||||
, encodeLeftRoom
|
||||
, encodeRoomSummary
|
||||
, encodeRooms
|
||||
, encodeStrippedStateEvent
|
||||
, encodeSync
|
||||
, encodeTimeline
|
||||
, encodeUnreadNotificationCounts
|
||||
, encodeUnsignedData
|
||||
, joinedRoomDecoder
|
||||
, leftRoomDecoder
|
||||
, roomSummaryDecoder
|
||||
, roomsDecoder
|
||||
, strippedStateEventDecoder
|
||||
, syncDecoder
|
||||
, timelineDecoder
|
||||
, unreadNotificationCountsDecoder
|
||||
, unsignedDataDecoder
|
||||
)
|
||||
|
||||
{-| Automatically generated 'Objects'
|
||||
|
||||
Last generated at Unix time 1673279712
|
||||
|
||||
-}
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)
|
||||
import Internal.Tools.EncodeExtra exposing (maybeObject)
|
||||
import Internal.Tools.Timestamp exposing (Timestamp, encodeTimestamp, timestampDecoder)
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
{-| A blind event that does not give context about itself.
|
||||
-}
|
||||
type alias BlindEvent =
|
||||
{ content : E.Value
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeBlindEvent : BlindEvent -> E.Value
|
||||
encodeBlindEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
blindEventDecoder : D.Decoder BlindEvent
|
||||
blindEventDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ content = a, contentType = b }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| Client event that has all data except the room id.
|
||||
-}
|
||||
type alias ClientEventWithoutRoomId =
|
||||
{ content : E.Value
|
||||
, eventId : String
|
||||
, originServerTs : Timestamp
|
||||
, sender : String
|
||||
, stateKey : Maybe String
|
||||
, contentType : String
|
||||
, unsigned : Maybe UnsignedData
|
||||
}
|
||||
|
||||
|
||||
encodeClientEventWithoutRoomId : ClientEventWithoutRoomId -> E.Value
|
||||
encodeClientEventWithoutRoomId data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "event_id", Just <| E.string data.eventId )
|
||||
, ( "origin_server_ts", Just <| encodeTimestamp data.originServerTs )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Maybe.map E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
, ( "unsigned", Maybe.map encodeUnsignedData data.unsigned )
|
||||
]
|
||||
|
||||
|
||||
clientEventWithoutRoomIdDecoder : D.Decoder ClientEventWithoutRoomId
|
||||
clientEventWithoutRoomIdDecoder =
|
||||
D.map7
|
||||
(\a b c d e f g ->
|
||||
{ content = a, eventId = b, originServerTs = c, sender = d, stateKey = e, contentType = f, unsigned = g }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "event_id" D.string)
|
||||
(D.field "origin_server_ts" timestampDecoder)
|
||||
(D.field "sender" D.string)
|
||||
(opField "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
(opField "unsigned" (D.lazy (\_ -> unsignedDataDecoder)))
|
||||
|
||||
|
||||
{-| Room that the user has joined.
|
||||
-}
|
||||
type alias JoinedRoom =
|
||||
{ accountData : List BlindEvent
|
||||
, ephemeral : List BlindEvent
|
||||
, state : List ClientEventWithoutRoomId
|
||||
, summary : Maybe RoomSummary
|
||||
, timeline : Maybe Timeline
|
||||
, unreadNotifications : Maybe UnreadNotificationCounts
|
||||
, unreadThreadNotifications : Dict String UnreadNotificationCounts
|
||||
}
|
||||
|
||||
|
||||
encodeJoinedRoom : JoinedRoom -> E.Value
|
||||
encodeJoinedRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "ephemeral", Just <| E.list encodeBlindEvent data.ephemeral )
|
||||
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
|
||||
, ( "summary", Maybe.map encodeRoomSummary data.summary )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
, ( "unread_notifications", Maybe.map encodeUnreadNotificationCounts data.unreadNotifications )
|
||||
, ( "unread_thread_notifications", Just <| E.dict identity encodeUnreadNotificationCounts data.unreadThreadNotifications )
|
||||
]
|
||||
|
||||
|
||||
joinedRoomDecoder : D.Decoder JoinedRoom
|
||||
joinedRoomDecoder =
|
||||
D.map7
|
||||
(\a b c d e f g ->
|
||||
{ accountData = a, ephemeral = b, state = c, summary = d, timeline = e, unreadNotifications = f, unreadThreadNotifications = g }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "ephemeral" (D.list blindEventDecoder))
|
||||
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opField "summary" roomSummaryDecoder)
|
||||
(opField "timeline" timelineDecoder)
|
||||
(opField "unread_notifications" unreadNotificationCountsDecoder)
|
||||
(D.field "unread_thread_notifications" (D.dict unreadNotificationCountsDecoder))
|
||||
|
||||
|
||||
{-| Room that the user has left.
|
||||
-}
|
||||
type alias LeftRoom =
|
||||
{ accountData : List BlindEvent
|
||||
, state : List ClientEventWithoutRoomId
|
||||
, timeline : Maybe Timeline
|
||||
}
|
||||
|
||||
|
||||
encodeLeftRoom : LeftRoom -> E.Value
|
||||
encodeLeftRoom data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "state", Just <| E.list encodeClientEventWithoutRoomId data.state )
|
||||
, ( "timeline", Maybe.map encodeTimeline data.timeline )
|
||||
]
|
||||
|
||||
|
||||
leftRoomDecoder : D.Decoder LeftRoom
|
||||
leftRoomDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ accountData = a, state = b, timeline = c }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "state" (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opField "timeline" timelineDecoder)
|
||||
|
||||
|
||||
{-| Updates to rooms.
|
||||
-}
|
||||
type alias Rooms =
|
||||
{ invite : Dict String (List StrippedStateEvent)
|
||||
, join : Dict String JoinedRoom
|
||||
, knock : Dict String (List StrippedStateEvent)
|
||||
, leave : Dict String LeftRoom
|
||||
}
|
||||
|
||||
|
||||
encodeRooms : Rooms -> E.Value
|
||||
encodeRooms data =
|
||||
maybeObject
|
||||
[ ( "invite", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.invite )
|
||||
, ( "join", Just <| E.dict identity encodeJoinedRoom data.join )
|
||||
, ( "knock", Just <| E.dict identity (E.list encodeStrippedStateEvent) data.knock )
|
||||
, ( "leave", Just <| E.dict identity encodeLeftRoom data.leave )
|
||||
]
|
||||
|
||||
|
||||
roomsDecoder : D.Decoder Rooms
|
||||
roomsDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ invite = a, join = b, knock = c, leave = d }
|
||||
)
|
||||
(opFieldWithDefault "invite" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
|
||||
(opFieldWithDefault "join" Dict.empty (D.dict joinedRoomDecoder))
|
||||
(opFieldWithDefault "knock" Dict.empty (D.dict (D.list strippedStateEventDecoder)))
|
||||
(opFieldWithDefault "leave" Dict.empty (D.dict leftRoomDecoder))
|
||||
|
||||
|
||||
{-| Information about a room which clients may need to correctly render it to users.
|
||||
-}
|
||||
type alias RoomSummary =
|
||||
{ mHeroes : Maybe (List String)
|
||||
, mInvitedMemberCount : Maybe Int
|
||||
, mJoinedMemberCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeRoomSummary : RoomSummary -> E.Value
|
||||
encodeRoomSummary data =
|
||||
maybeObject
|
||||
[ ( "m.heroes", Maybe.map (E.list E.string) data.mHeroes )
|
||||
, ( "m.invited_member_count", Maybe.map E.int data.mInvitedMemberCount )
|
||||
, ( "m.joined_member_count", Maybe.map E.int data.mJoinedMemberCount )
|
||||
]
|
||||
|
||||
|
||||
roomSummaryDecoder : D.Decoder RoomSummary
|
||||
roomSummaryDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ mHeroes = a, mInvitedMemberCount = b, mJoinedMemberCount = c }
|
||||
)
|
||||
(opField "m.heroes" (D.list D.string))
|
||||
(opField "m.invited_member_count" D.int)
|
||||
(opField "m.joined_member_count" D.int)
|
||||
|
||||
|
||||
{-| Stripped state events of a room that the user has limited access to.
|
||||
-}
|
||||
type alias StrippedStateEvent =
|
||||
{ content : E.Value
|
||||
, sender : String
|
||||
, stateKey : String
|
||||
, contentType : String
|
||||
}
|
||||
|
||||
|
||||
encodeStrippedStateEvent : StrippedStateEvent -> E.Value
|
||||
encodeStrippedStateEvent data =
|
||||
maybeObject
|
||||
[ ( "content", Just <| data.content )
|
||||
, ( "sender", Just <| E.string data.sender )
|
||||
, ( "state_key", Just <| E.string data.stateKey )
|
||||
, ( "type", Just <| E.string data.contentType )
|
||||
]
|
||||
|
||||
|
||||
strippedStateEventDecoder : D.Decoder StrippedStateEvent
|
||||
strippedStateEventDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ content = a, sender = b, stateKey = c, contentType = d }
|
||||
)
|
||||
(D.field "content" D.value)
|
||||
(D.field "sender" D.string)
|
||||
(D.field "state_key" D.string)
|
||||
(D.field "type" D.string)
|
||||
|
||||
|
||||
{-| The sync response the homeserver sends to the user.
|
||||
-}
|
||||
type alias Sync =
|
||||
{ accountData : List BlindEvent
|
||||
, nextBatch : String
|
||||
, presence : List BlindEvent
|
||||
, rooms : Maybe Rooms
|
||||
}
|
||||
|
||||
|
||||
encodeSync : Sync -> E.Value
|
||||
encodeSync data =
|
||||
maybeObject
|
||||
[ ( "account_data", Just <| E.list encodeBlindEvent data.accountData )
|
||||
, ( "next_batch", Just <| E.string data.nextBatch )
|
||||
, ( "presence", Just <| E.list encodeBlindEvent data.presence )
|
||||
, ( "rooms", Maybe.map encodeRooms data.rooms )
|
||||
]
|
||||
|
||||
|
||||
syncDecoder : D.Decoder Sync
|
||||
syncDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
{ accountData = a, nextBatch = b, presence = c, rooms = d }
|
||||
)
|
||||
(D.field "account_data" (D.list blindEventDecoder))
|
||||
(D.field "next_batch" D.string)
|
||||
(D.field "presence" (D.list blindEventDecoder))
|
||||
(opField "rooms" roomsDecoder)
|
||||
|
||||
|
||||
{-| The timeline of messages and state changes in a room.
|
||||
-}
|
||||
type alias Timeline =
|
||||
{ events : List ClientEventWithoutRoomId
|
||||
, limited : Bool
|
||||
, prevBatch : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeTimeline : Timeline -> E.Value
|
||||
encodeTimeline data =
|
||||
maybeObject
|
||||
[ ( "events", Just <| E.list encodeClientEventWithoutRoomId data.events )
|
||||
, ( "limited", Just <| E.bool data.limited )
|
||||
, ( "prev_batch", Maybe.map E.string data.prevBatch )
|
||||
]
|
||||
|
||||
|
||||
timelineDecoder : D.Decoder Timeline
|
||||
timelineDecoder =
|
||||
D.map3
|
||||
(\a b c ->
|
||||
{ events = a, limited = b, prevBatch = c }
|
||||
)
|
||||
(opFieldWithDefault "events" [] (D.list clientEventWithoutRoomIdDecoder))
|
||||
(opFieldWithDefault "limited" False D.bool)
|
||||
(opField "prev_batch" D.string)
|
||||
|
||||
|
||||
{-| Counts of unread notifications for this room.
|
||||
-}
|
||||
type alias UnreadNotificationCounts =
|
||||
{ highlightCount : Maybe Int
|
||||
, notificationCount : Maybe Int
|
||||
}
|
||||
|
||||
|
||||
encodeUnreadNotificationCounts : UnreadNotificationCounts -> E.Value
|
||||
encodeUnreadNotificationCounts data =
|
||||
maybeObject
|
||||
[ ( "highlight_count", Maybe.map E.int data.highlightCount )
|
||||
, ( "notification_count", Maybe.map E.int data.notificationCount )
|
||||
]
|
||||
|
||||
|
||||
unreadNotificationCountsDecoder : D.Decoder UnreadNotificationCounts
|
||||
unreadNotificationCountsDecoder =
|
||||
D.map2
|
||||
(\a b ->
|
||||
{ highlightCount = a, notificationCount = b }
|
||||
)
|
||||
(opField "highlight_count" D.int)
|
||||
(opField "notification_count" D.int)
|
||||
|
||||
|
||||
{-| Data that isn't getting signed for Canonical JSON.
|
||||
-}
|
||||
type UnsignedData
|
||||
= UnsignedData
|
||||
{ age : Maybe Int
|
||||
, prevContent : Maybe E.Value
|
||||
, redactedBecause : Maybe ClientEventWithoutRoomId
|
||||
, transactionId : Maybe String
|
||||
}
|
||||
|
||||
|
||||
encodeUnsignedData : UnsignedData -> E.Value
|
||||
encodeUnsignedData (UnsignedData data) =
|
||||
maybeObject
|
||||
[ ( "age", Maybe.map E.int data.age )
|
||||
, ( "prev_content", data.prevContent )
|
||||
, ( "redacted_because", Maybe.map encodeClientEventWithoutRoomId data.redactedBecause )
|
||||
, ( "transaction_id", Maybe.map E.string data.transactionId )
|
||||
]
|
||||
|
||||
|
||||
unsignedDataDecoder : D.Decoder UnsignedData
|
||||
unsignedDataDecoder =
|
||||
D.map4
|
||||
(\a b c d ->
|
||||
UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
|
||||
)
|
||||
(opField "age" D.int)
|
||||
(opField "prev_content" D.value)
|
||||
(opField "redacted_because" clientEventWithoutRoomIdDecoder)
|
||||
(opField "transaction_id" D.string)
|
|
@ -1,155 +0,0 @@
|
|||
version: v1.5
|
||||
name: Objects
|
||||
objects:
|
||||
Sync:
|
||||
description: The sync response the homeserver sends to the user.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
next_batch:
|
||||
type: string
|
||||
required: true
|
||||
presence:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
rooms:
|
||||
type: Rooms
|
||||
BlindEvent:
|
||||
description: A blind event that does not give context about itself.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
Rooms:
|
||||
description: Updates to rooms.
|
||||
fields:
|
||||
invite:
|
||||
type: "{[StrippedStateEvent]}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
join:
|
||||
type: "{JoinedRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
knock:
|
||||
type: "{[StrippedStateEvent]}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
leave:
|
||||
type: "{LeftRoom}"
|
||||
required: false
|
||||
default: Dict.empty
|
||||
StrippedStateEvent:
|
||||
description: Stripped state events of a room that the user has limited access to.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
required: true
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
JoinedRoom:
|
||||
description: Room that the user has joined.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
ephemeral:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
state:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: true
|
||||
summary:
|
||||
type: RoomSummary
|
||||
timeline:
|
||||
type: Timeline
|
||||
unread_notifications:
|
||||
type: UnreadNotificationCounts
|
||||
unread_thread_notifications:
|
||||
type: "{UnreadNotificationCounts}"
|
||||
required: true
|
||||
ClientEventWithoutRoomId:
|
||||
description: Client event that has all data except the room id.
|
||||
fields:
|
||||
content:
|
||||
type: value
|
||||
required: true
|
||||
event_id:
|
||||
type: string
|
||||
required: true
|
||||
origin_server_ts:
|
||||
type: timestamp
|
||||
required: true
|
||||
sender:
|
||||
type: string
|
||||
required: true
|
||||
state_key:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
required: true
|
||||
unsigned:
|
||||
type: UnsignedData
|
||||
UnsignedData:
|
||||
anti_recursion: true
|
||||
description: Data that isn't getting signed for Canonical JSON.
|
||||
fields:
|
||||
age:
|
||||
type: int
|
||||
prev_content:
|
||||
type: value
|
||||
redacted_because:
|
||||
type: ClientEventWithoutRoomId
|
||||
transaction_id:
|
||||
type: string
|
||||
RoomSummary:
|
||||
description: Information about a room which clients may need to correctly render it to users.
|
||||
fields:
|
||||
m.heroes:
|
||||
type: "[string]"
|
||||
m.invited_member_count:
|
||||
type: int
|
||||
m.joined_member_count:
|
||||
type: int
|
||||
Timeline:
|
||||
description: The timeline of messages and state changes in a room.
|
||||
fields:
|
||||
events:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: false
|
||||
default: "[]"
|
||||
limited:
|
||||
type: bool
|
||||
required: false
|
||||
default: "False"
|
||||
prev_batch:
|
||||
type: string
|
||||
UnreadNotificationCounts:
|
||||
description: Counts of unread notifications for this room.
|
||||
fields:
|
||||
highlight_count:
|
||||
type: int
|
||||
notification_count:
|
||||
type: int
|
||||
LeftRoom:
|
||||
description: Room that the user has left.
|
||||
fields:
|
||||
account_data:
|
||||
type: "[BlindEvent]"
|
||||
required: true
|
||||
state:
|
||||
type: "[ClientEventWithoutRoomId]"
|
||||
required: true
|
||||
timeline:
|
||||
type: Timeline
|
|
@ -1,73 +0,0 @@
|
|||
module Internal.Api.Sync.V1_5.Upcast exposing (..)
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Sync.V1_4.Objects as PO
|
||||
import Internal.Api.Sync.V1_5.Objects as O
|
||||
|
||||
|
||||
upcast : PO.Sync -> O.Sync
|
||||
upcast sync =
|
||||
{ accountData = sync.accountData
|
||||
, nextBatch = sync.nextBatch
|
||||
, presence = sync.presence
|
||||
, rooms = Maybe.map upcastRooms sync.rooms
|
||||
}
|
||||
|
||||
|
||||
upcastRooms : PO.Rooms -> O.Rooms
|
||||
upcastRooms rooms =
|
||||
{ invite = rooms.invite
|
||||
, join = Dict.map (\_ -> upcastJoinedRoom) rooms.join
|
||||
, knock = rooms.knock
|
||||
, leave = Dict.map (\_ -> upcastLeftRoom) rooms.leave
|
||||
}
|
||||
|
||||
|
||||
upcastJoinedRoom : PO.JoinedRoom -> O.JoinedRoom
|
||||
upcastJoinedRoom room =
|
||||
{ accountData = room.accountData
|
||||
, ephemeral = room.ephemeral
|
||||
, state = List.map upcastClientEventWithoutRoomId room.state
|
||||
, summary = room.summary
|
||||
, timeline = Maybe.map upcastTimeline room.timeline
|
||||
, unreadNotifications = room.unreadNotifications
|
||||
, unreadThreadNotifications = room.unreadThreadNotifications
|
||||
}
|
||||
|
||||
|
||||
upcastClientEventWithoutRoomId : PO.ClientEventWithoutRoomId -> O.ClientEventWithoutRoomId
|
||||
upcastClientEventWithoutRoomId event =
|
||||
{ content = event.content
|
||||
, eventId = event.eventId
|
||||
, originServerTs = event.originServerTs
|
||||
, sender = event.sender
|
||||
, stateKey = event.stateKey
|
||||
, contentType = event.contentType
|
||||
, unsigned = Maybe.map upcastUnsigned event.unsigned
|
||||
}
|
||||
|
||||
|
||||
upcastUnsigned : PO.UnsignedData -> O.UnsignedData
|
||||
upcastUnsigned (PO.UnsignedData data) =
|
||||
O.UnsignedData
|
||||
{ age = data.age
|
||||
, prevContent = data.prevContent
|
||||
, redactedBecause = Maybe.map upcastClientEventWithoutRoomId data.redactedBecause
|
||||
, transactionId = data.transactionId
|
||||
}
|
||||
|
||||
|
||||
upcastTimeline : PO.Timeline -> O.Timeline
|
||||
upcastTimeline timeline =
|
||||
{ events = List.map upcastClientEventWithoutRoomId timeline.events
|
||||
, limited = timeline.limited
|
||||
, prevBatch = timeline.prevBatch
|
||||
}
|
||||
|
||||
|
||||
upcastLeftRoom : PO.LeftRoom -> O.LeftRoom
|
||||
upcastLeftRoom room =
|
||||
{ accountData = room.accountData
|
||||
, state = List.map upcastClientEventWithoutRoomId room.state
|
||||
, timeline = Maybe.map upcastTimeline room.timeline
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
module Internal.Api.Sync.V1_5.SpecObjects exposing
|
||||
module Internal.Api.Sync.V2.SpecObjects exposing
|
||||
( AccountData
|
||||
, ClientEventWithoutRoomId
|
||||
, Ephemeral
|
||||
|
@ -63,7 +63,7 @@ module Internal.Api.Sync.V1_5.SpecObjects exposing
|
|||
|
||||
{-| Automatically generated 'SpecObjects'
|
||||
|
||||
Last generated at Unix time 1673279712
|
||||
Last generated at Unix time 1676625735
|
||||
|
||||
-}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
version: v1.5
|
||||
version: v2
|
||||
name: SpecObjects
|
||||
objects:
|
||||
Sync:
|
|
@ -0,0 +1,70 @@
|
|||
module Internal.Api.Sync.V2.Upcast exposing (..)
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Sync.V1.SpecObjects as PO
|
||||
import Internal.Api.Sync.V2.SpecObjects as SO
|
||||
|
||||
upcastSync : PO.Sync -> SO.Sync
|
||||
upcastSync old =
|
||||
{ accountData = old.accountData
|
||||
, nextBatch = old.nextBatch
|
||||
, presence = old.presence
|
||||
, rooms = Maybe.map upcastRooms old.rooms
|
||||
}
|
||||
|
||||
upcastRooms : PO.Rooms -> SO.Rooms
|
||||
upcastRooms old =
|
||||
{ invite = old.invite
|
||||
, join = Dict.map (\_ -> upcastJoinedRoom) old.join
|
||||
, knock = old.knock
|
||||
, leave = Dict.map (\_ -> upcastLeftRoom) old.leave
|
||||
}
|
||||
|
||||
upcastJoinedRoom : PO.JoinedRoom -> SO.JoinedRoom
|
||||
upcastJoinedRoom old =
|
||||
{ accountData = old.accountData
|
||||
, ephemeral = old.ephemeral
|
||||
, state = Maybe.map upcastState old.state
|
||||
, summary = old.summary
|
||||
, timeline = Maybe.map upcastTimeline old.timeline
|
||||
, unreadNotifications = old.unreadNotifications
|
||||
, unreadThreadNotifications = Dict.empty
|
||||
}
|
||||
|
||||
upcastState : PO.State -> SO.State
|
||||
upcastState old =
|
||||
{ events = List.map upcastClientEventWithoutRoomId old.events }
|
||||
|
||||
upcastClientEventWithoutRoomId : PO.ClientEventWithoutRoomId -> SO.ClientEventWithoutRoomId
|
||||
upcastClientEventWithoutRoomId old =
|
||||
{ content = old.content
|
||||
, eventId = old.eventId
|
||||
, originServerTs = old.originServerTs
|
||||
, sender = old.sender
|
||||
, stateKey = old.stateKey
|
||||
, contentType = old.contentType
|
||||
, unsigned = Maybe.map upcastUnsigned old.unsigned
|
||||
}
|
||||
|
||||
upcastUnsigned : PO.UnsignedData -> SO.UnsignedData
|
||||
upcastUnsigned (PO.UnsignedData old) =
|
||||
SO.UnsignedData
|
||||
{ age = old.age
|
||||
, prevContent = old.prevContent
|
||||
, redactedBecause = Maybe.map upcastClientEventWithoutRoomId old.redactedBecause
|
||||
, transactionId = old.transactionId
|
||||
}
|
||||
|
||||
upcastTimeline : PO.Timeline -> SO.Timeline
|
||||
upcastTimeline old =
|
||||
{ events = List.map upcastClientEventWithoutRoomId old.events
|
||||
, limited = old.limited
|
||||
, prevBatch = old.prevBatch
|
||||
}
|
||||
|
||||
upcastLeftRoom : PO.LeftRoom -> SO.LeftRoom
|
||||
upcastLeftRoom old =
|
||||
{ accountData = old.accountData
|
||||
, state = Maybe.map upcastState old.state
|
||||
, timeline = Maybe.map upcastTimeline old.timeline
|
||||
}
|
Loading…
Reference in New Issue