Refactor Sync endpoint
							parent
							
								
									a0f19a3fdc
								
							
						
					
					
						commit
						eaa7bc3444
					
				|  | @ -1,9 +1,10 @@ | ||||||
| module Internal.Api.Sync.Api exposing (..) | module Internal.Api.Sync.Api exposing (..) | ||||||
| 
 | 
 | ||||||
| import Internal.Api.Request as R | 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.Exceptions as X | ||||||
| import Internal.Tools.SpecEnums as Enums | import Internal.Tools.SpecEnums as Enums | ||||||
| import Json.Decode as D |  | ||||||
| import Task exposing (Task) | import Task exposing (Task) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -18,8 +19,15 @@ type alias SyncInputV1 = | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| syncV1 : D.Decoder a -> (a -> b) -> SyncInputV1 -> Task X.Error b | type alias SyncOutputV1 = | ||||||
| syncV1 decoder mapping data = |     Task X.Error SO1.Sync | ||||||
|  | 
 | ||||||
|  | type alias SyncOutputV2 = | ||||||
|  |     Task X.Error SO2.Sync | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | syncV1 : SyncInputV1 -> SyncOutputV1 | ||||||
|  | syncV1 data = | ||||||
|     R.rawApiCall |     R.rawApiCall | ||||||
|         { headers = R.WithAccessToken data.accessToken |         { headers = R.WithAccessToken data.accessToken | ||||||
|         , method = "GET" |         , method = "GET" | ||||||
|  | @ -38,5 +46,29 @@ syncV1 decoder mapping data = | ||||||
|             data.timeout |             data.timeout | ||||||
|                 |> Maybe.map ((+) 10000) |                 |> Maybe.map ((+) 10000) | ||||||
|                 |> Maybe.map toFloat |                 |> 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 (..) | module Internal.Api.Sync.Main exposing (..) | ||||||
| 
 | 
 | ||||||
| import Internal.Api.Sync.Api as Api | import Internal.Api.Sync.Api as Api | ||||||
| import Internal.Api.Sync.V1_2.Api as V1_2 | import Internal.Api.Sync.V2.Upcast as U2 | ||||||
| import Internal.Api.Sync.V1_3.Api as V1_3 | import Internal.Tools.VersionControl as VC | ||||||
| import Internal.Api.Sync.V1_4.Api as V1_4 | import Task | ||||||
| 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) |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| sync : List String -> SyncInput -> SyncOutput | sync : List String -> Maybe (SyncInput -> SyncOutput) | ||||||
| sync = | sync versions = | ||||||
|     V.firstVersion V1_2.packet |     VC.withBottomLayer | ||||||
|         |> V.updateWith V1_3.packet |         { current = Api.syncV1 | ||||||
|         |> V.updateWith V1_4.packet |         , version = "v1.2" | ||||||
|         |> V.updateWith V1_5.packet |         } | ||||||
|         |> V.toFunction |         |> 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 = | type alias SyncInput = | ||||||
|  | @ -25,4 +28,4 @@ type alias SyncInput = | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| type alias SyncOutput = | 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 |     ( AccountData | ||||||
|     , ClientEventWithoutRoomId |     , ClientEventWithoutRoomId | ||||||
|     , Ephemeral |     , Ephemeral | ||||||
|  | @ -60,7 +60,7 @@ module Internal.Api.Sync.V1_2.SpecObjects exposing | ||||||
| 
 | 
 | ||||||
| {-| Automatically generated 'SpecObjects' | {-| 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 | name: SpecObjects | ||||||
| objects: | objects: | ||||||
|   Sync: |   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 |     ( AccountData | ||||||
|     , ClientEventWithoutRoomId |     , ClientEventWithoutRoomId | ||||||
|     , Ephemeral |     , Ephemeral | ||||||
|  | @ -63,7 +63,7 @@ module Internal.Api.Sync.V1_5.SpecObjects exposing | ||||||
| 
 | 
 | ||||||
| {-| Automatically generated 'SpecObjects' | {-| 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 | name: SpecObjects | ||||||
| objects: | objects: | ||||||
|   Sync: |   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