Add toUpdate function for /sync v1

pull/31/head
Bram 2024-07-09 00:08:46 +02:00
parent e7d3a129b1
commit b239eecc6b
6 changed files with 216 additions and 6 deletions

View File

@ -11,10 +11,14 @@ This API module represents the /sync endpoint on Matrix spec version v1.1.
-}
import FastDict exposing (Dict)
import FastDict as Dict exposing (Dict)
import Internal.Config.Log exposing (Log)
import Internal.Tools.Json as Json
import Internal.Tools.StrippedEvent as StrippedEvent exposing (StrippedEvent)
import Internal.Tools.Timestamp as Timestamp exposing (Timestamp)
import Internal.Values.Envelope as E
import Internal.Values.Room as R
import Internal.Values.Vault as V
type alias SyncResponse =
@ -807,3 +811,85 @@ coderToDeviceEvent =
, coder = Json.string
}
)
updateSyncResponse : SyncResponse -> ( E.EnvelopeUpdate V.VaultUpdate, List Log )
updateSyncResponse response =
-- TODO: Add account data
-- TODO: Add device lists
-- Next batch
[ Just ( E.SetNextBatch response.nextBatch, [] )
-- TODO: Add presence
-- Rooms
, Maybe.map (updateRooms >> Tuple.mapFirst E.ContentUpdate) response.rooms
-- TODO: Add to_device
]
|> List.filterMap identity
|> List.unzip
|> Tuple.mapFirst E.More
|> Tuple.mapSecond List.concat
updateRooms : Rooms -> ( V.VaultUpdate, List Log )
updateRooms rooms =
let
( roomUpdate, roomLogs ) =
rooms.join
|> Maybe.withDefault Dict.empty
|> Dict.toList
|> List.map
(\( roomId, room ) ->
let
( u, l ) =
updateJoinedRoom room
in
( V.MapRoom roomId u, l )
)
|> List.unzip
|> Tuple.mapBoth V.More List.concat
in
( V.More
-- Add rooms
[ rooms.join
|> Maybe.withDefault Dict.empty
|> Dict.keys
|> List.map V.CreateRoomIfNotExists
|> V.More
-- Update rooms
, roomUpdate
-- TODO: Add invited rooms
-- TODO: Add knocked rooms
-- TODO: Add left rooms
]
, roomLogs
)
updateJoinedRoom : JoinedRoom -> ( R.RoomUpdate, List Log )
updateJoinedRoom room =
( R.More
[ room.accountData
|> Maybe.andThen .events
|> Maybe.map
(\events ->
events
|> List.map (\e -> R.SetAccountData e.eventType e.content)
|> R.More
)
|> R.Optional
, room.ephemeral
|> Maybe.andThen .events
|> Maybe.map R.SetEphemeral
|> R.Optional
-- TODO: Add state
-- TODO: Add RoomSummary
-- TODO: Add timeline
-- TODO: Add unread notifications
]
, []
)

View File

@ -277,6 +277,7 @@ fields :
, baseUrl : Desc
, deviceId : Desc
, experimental : Desc
, nextBatch : Desc
, now : Desc
, password : Desc
, refreshToken : Desc
@ -388,6 +389,9 @@ fields =
, experimental =
[ "Experimental features supported by the homeserver."
]
, nextBatch =
[ "The batch token to supply in the since param of the next /sync request."
]
, now =
[ "The most recently found timestamp."
]

View File

@ -1,6 +1,6 @@
module Internal.Tools.DecodeExtra exposing
( opField, opFieldWithDefault
, map9, map10, map11
, map9, map10, map11, map12
)
{-|
@ -18,7 +18,7 @@ This module contains helper functions that help decode JSON.
## Extended map functions
@docs map9, map10, map11
@docs map9, map10, map11, map12
-}
@ -153,3 +153,35 @@ map11 func da db dc dd de df dg dh di dj dk =
(D.map2 Tuple.pair df dg)
(D.map2 Tuple.pair dh di)
(D.map2 Tuple.pair dj dk)
{-| Try 12 decoders and combine the result.
-}
map12 :
(a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> value)
-> D.Decoder a
-> D.Decoder b
-> D.Decoder c
-> D.Decoder d
-> D.Decoder e
-> D.Decoder f
-> D.Decoder g
-> D.Decoder h
-> D.Decoder i
-> D.Decoder j
-> D.Decoder k
-> D.Decoder l
-> D.Decoder value
map12 func da db dc dd de df dg dh di dj dk dl =
D.map8
(\a b c d ( e, f ) ( g, h ) ( i, j ) ( k, l ) ->
func a b c d e f g h i j k l
)
da
db
dc
dd
(D.map2 Tuple.pair de df)
(D.map2 Tuple.pair dg dh)
(D.map2 Tuple.pair di dj)
(D.map2 Tuple.pair dk dl)

View File

@ -5,7 +5,7 @@ module Internal.Tools.Json exposing
, Docs(..), RequiredField(..), toDocs
, list, listWithOne, slowDict, fastDict, fastIntDict, set, maybe
, Field, field, parser
, object1, object2, object3, object4, object5, object6, object7, object8, object9, object10, object11
, object1, object2, object3, object4, object5, object6, object7, object8, object9, object10, object11, object12
)
{-|
@ -62,7 +62,7 @@ first.
Once all fields are constructed, the user can create JSON objects.
@docs object1, object2, object3, object4, object5, object6, object7, object8, object9, object10, object11
@docs object1, object2, object3, object4, object5, object6, object7, object8, object9, object10, object11, object12
-}
@ -1175,6 +1175,81 @@ object11 { name, description, init } fa fb fc fd fe ff fg fh fi fj fk =
}
{-| Define an object with 12 keys
-}
object12 :
Descriptive { init : a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> object }
-> Field a object
-> Field b object
-> Field c object
-> Field d object
-> Field e object
-> Field f object
-> Field g object
-> Field h object
-> Field i object
-> Field j object
-> Field k object
-> Field l object
-> Coder object
object12 { name, description, init } fa fb fc fd fe ff fg fh fi fj fk fl =
Coder
{ encoder =
objectEncoder
[ toEncodeField fa
, toEncodeField fb
, toEncodeField fc
, toEncodeField fd
, toEncodeField fe
, toEncodeField ff
, toEncodeField fg
, toEncodeField fh
, toEncodeField fi
, toEncodeField fj
, toEncodeField fk
, toEncodeField fl
]
, decoder =
D.map12
(\( a, la ) ( b, lb ) ( c, lc ) ( d, ld ) ( e, le ) ( f, lf ) ( g, lg ) ( h, lh ) ( i, li ) ( j, lj ) ( k, lk ) ( l, ll ) ->
( init a b c d e f g h i j k l
, List.concat [ la, lb, lc, ld, le, lf, lg, lh, li, lj, lk, ll ]
)
)
(toDecoderField fa)
(toDecoderField fb)
(toDecoderField fc)
(toDecoderField fd)
(toDecoderField fe)
(toDecoderField ff)
(toDecoderField fg)
(toDecoderField fh)
(toDecoderField fi)
(toDecoderField fj)
(toDecoderField fk)
(toDecoderField fl)
, docs =
DocsObject
{ name = name
, description = description
, keys =
[ toDocsField fa
, toDocsField fb
, toDocsField fc
, toDocsField fd
, toDocsField fe
, toDocsField ff
, toDocsField fg
, toDocsField fh
, toDocsField fi
, toDocsField fj
, toDocsField fk
, toDocsField fl
]
}
}
{-| Define a parser that converts a string into a custom Elm type.
-}
parser : { name : String, p : P.Parser ( a, List Log ), toString : a -> String } -> Coder a

View File

@ -95,6 +95,7 @@ type alias Context =
{ accessTokens : Hashdict AccessToken
, baseUrl : Maybe String
, deviceId : Maybe String
, nextBatch : Maybe String
, now : Maybe Timestamp
, password : Maybe String
, refreshToken : Maybe String
@ -152,7 +153,7 @@ fromApiFormat (APIContext c) =
-}
coder : Json.Coder Context
coder =
Json.object11
Json.object12
{ name = Text.docs.context.name
, description = Text.docs.context.description
, init = Context
@ -178,6 +179,13 @@ coder =
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "nextBatch"
, toField = .nextBatch
, description = Text.fields.context.nextBatch
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "now"
, toField = .now
@ -303,6 +311,7 @@ init sn =
{ accessTokens = Hashdict.empty .value
, baseUrl = Nothing
, deviceId = Nothing
, nextBatch = Nothing
, now = Nothing
, refreshToken = Nothing
, password = Nothing

View File

@ -82,6 +82,7 @@ type EnvelopeUpdate a
| SetAccessToken AccessToken
| SetBaseUrl String
| SetDeviceId String
| SetNextBatch String
| SetNow Timestamp
| SetRefreshToken String
| SetVersions Versions
@ -327,6 +328,9 @@ update updateContent eu ({ context } as data) =
SetDeviceId d ->
{ data | context = { context | deviceId = Just d } }
SetNextBatch nextBatch ->
{ data | context = { context | nextBatch = Just nextBatch } }
SetNow n ->
{ data | context = { context | now = Just n } }