Finish 1st version of open types
The code is very messy and there are a few optimizations to be made before the code is both user- and developer-friendly, but at least it works.pull/1/head
parent
7e345c2b05
commit
caab0ae0bb
|
@ -17,7 +17,7 @@ import Task
|
|||
import Time
|
||||
|
||||
|
||||
accessToken : String -> AccessToken -> ValueGetter String
|
||||
accessToken : String -> AccessToken -> ValueGetter X.Error String
|
||||
accessToken baseUrl t =
|
||||
{ value =
|
||||
case t of
|
||||
|
@ -37,7 +37,7 @@ accessToken baseUrl t =
|
|||
}
|
||||
|
||||
|
||||
transactionId : (Int -> String) -> ValueGetter String
|
||||
transactionId : (Int -> String) -> ValueGetter X.Error String
|
||||
transactionId seeder =
|
||||
{ value = Nothing
|
||||
, getValue =
|
||||
|
@ -47,7 +47,7 @@ transactionId seeder =
|
|||
}
|
||||
|
||||
|
||||
versions : String -> Maybe V.Versions -> ValueGetter V.Versions
|
||||
versions : String -> Maybe V.Versions -> ValueGetter X.Error V.Versions
|
||||
versions baseUrl mVersions =
|
||||
{ value = mVersions
|
||||
, getValue =
|
||||
|
|
|
@ -9,11 +9,14 @@ This file combines the internal functions with the API endpoints to create a ful
|
|||
|
||||
import Dict
|
||||
import Internal.Api.All as Api
|
||||
import Internal.Room as Room
|
||||
import Internal.Event as Event
|
||||
import Internal.Room as Room
|
||||
import Internal.Tools.Exceptions as X
|
||||
import Internal.Values.Credentials as Internal
|
||||
import Internal.Values.Event as IEvent
|
||||
import Internal.Values.Room as IRoom
|
||||
import Internal.Values.StateManager as StateManager
|
||||
import Task exposing (Task)
|
||||
|
||||
|
||||
{-| You can consider the `Credentials` type as a large ring of keys,
|
||||
|
@ -56,16 +59,23 @@ getRoomById roomId credentials =
|
|||
}
|
||||
)
|
||||
|
||||
|
||||
{-| Insert an internal room type into the credentials.
|
||||
-}
|
||||
insertInternalRoom : IRoom.Room -> Credentials -> Credentials
|
||||
insertInternalRoom = Internal.insertRoom
|
||||
insertInternalRoom =
|
||||
Internal.insertRoom
|
||||
|
||||
{-| Internal a full room type into the credentials. -}
|
||||
|
||||
{-| Internal a full room type into the credentials.
|
||||
-}
|
||||
insertRoom : Room.Room -> Credentials -> Credentials
|
||||
insertRoom = Room.internalValue >> insertInternalRoom
|
||||
insertRoom =
|
||||
Room.internalValue >> insertInternalRoom
|
||||
|
||||
{-| Update the Credentials type with new values -}
|
||||
|
||||
{-| Update the Credentials type with new values
|
||||
-}
|
||||
updateWith : Api.CredUpdate -> Credentials -> Credentials
|
||||
updateWith credUpdate credentials =
|
||||
case credUpdate of
|
||||
|
@ -76,7 +86,7 @@ updateWith credUpdate credentials =
|
|||
case getRoomById input.roomId credentials of
|
||||
Just room ->
|
||||
output
|
||||
|> IEvent.initFromGetEvent
|
||||
|> Event.initFromGetEvent
|
||||
|> Room.addInternalEvent
|
||||
|> (|>) room
|
||||
|> insertRoom
|
||||
|
@ -86,40 +96,91 @@ updateWith credUpdate credentials =
|
|||
credentials
|
||||
|
||||
Api.JoinedMembersToRoom _ _ ->
|
||||
credentials -- TODO
|
||||
credentials
|
||||
|
||||
-- TODO
|
||||
Api.MessageEventSent _ _ ->
|
||||
credentials -- TODO
|
||||
credentials
|
||||
|
||||
-- TODO
|
||||
Api.StateEventSent _ _ ->
|
||||
credentials -- TODO
|
||||
credentials
|
||||
|
||||
-- TODO
|
||||
Api.SyncUpdate input output ->
|
||||
let
|
||||
rooms =
|
||||
jRooms =
|
||||
output.rooms
|
||||
|> Maybe.map .join
|
||||
|> Maybe.withDefault Dict.empty
|
||||
|> Dict.toList
|
||||
|> List.map
|
||||
(\(roomId, jroom)->
|
||||
case getRoomById roomId credentials of
|
||||
-- Update existing room
|
||||
Just room ->
|
||||
room
|
||||
|> Room.internalValue
|
||||
|> IRoom.addEvents
|
||||
|> Maybe.map .join
|
||||
|> Maybe.withDefault Dict.empty
|
||||
|> Dict.toList
|
||||
|> List.map
|
||||
(\( roomId, jroom ) ->
|
||||
case getRoomById roomId credentials of
|
||||
-- Update existing room
|
||||
Just room ->
|
||||
room
|
||||
|> Room.internalValue
|
||||
|> IRoom.addEvents
|
||||
{ events =
|
||||
jroom.timeline
|
||||
|> Maybe.map .events
|
||||
|> Maybe.withDefault []
|
||||
|> List.map (Event.initFromClientEventWithoutRoomId roomId)
|
||||
, nextBatch = output.nextBatch
|
||||
, prevBatch =
|
||||
jroom.timeline
|
||||
|> Maybe.andThen .prevBatch
|
||||
|> Maybe.withDefault (Maybe.withDefault "" input.since)
|
||||
, stateDelta =
|
||||
jroom.state
|
||||
|> Maybe.map
|
||||
(.events
|
||||
>> List.map (Event.initFromClientEventWithoutRoomId roomId)
|
||||
>> StateManager.fromEventList
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
-- Add new room
|
||||
Nothing ->
|
||||
jroom
|
||||
)
|
||||
-- Add new room
|
||||
Nothing ->
|
||||
Room.initFromJoinedRoom { nextBatch = output.nextBatch, roomId = roomId } jroom
|
||||
)
|
||||
in
|
||||
credentials
|
||||
List.foldl Internal.insertRoom (Internal.addSince output.nextBatch credentials) jRooms
|
||||
|
||||
Api.UpdateAccessToken token ->
|
||||
Internal.addAccessToken token credentials
|
||||
|
||||
Api.UpdateVersions versions ->
|
||||
Internal.addVersions versions credentials
|
||||
|
||||
|
||||
{-| Synchronize credentials
|
||||
-}
|
||||
sync : Credentials -> Task X.Error Api.CredUpdate
|
||||
sync credentials =
|
||||
Api.syncCredentials
|
||||
{ accessToken = Internal.getAccessTokenType credentials
|
||||
, baseUrl = Internal.getBaseUrl credentials
|
||||
, filter = Nothing
|
||||
, fullState = Nothing
|
||||
, setPresence = Nothing
|
||||
, since = Internal.getSince credentials
|
||||
, timeout = Just 30
|
||||
, versions = Internal.getVersions credentials
|
||||
}
|
||||
|
||||
|
||||
{-| Get a list of all synchronised rooms.
|
||||
-}
|
||||
rooms : Credentials -> List Room.Room
|
||||
rooms credentials =
|
||||
credentials
|
||||
|> Internal.getRooms
|
||||
|> ({ accessToken = Internal.getAccessTokenType credentials
|
||||
, baseUrl = Internal.getBaseUrl credentials
|
||||
, versions = Internal.getVersions credentials
|
||||
}
|
||||
|> Room.init
|
||||
|> List.map
|
||||
)
|
||||
|
|
|
@ -10,7 +10,7 @@ resend other events or forward them elsewhere.
|
|||
import Internal.Api.GetEvent.Main as GetEvent
|
||||
import Internal.Api.GetEvent.V1.SpecObjects as GetEventSO
|
||||
import Internal.Api.PreApi.Objects.Versions as V
|
||||
import Internal.Api.Sync.V1.SpecObjects as SyncSO
|
||||
import Internal.Api.Sync.V2.SpecObjects as SyncSO
|
||||
import Internal.Tools.LoginValues exposing (AccessToken)
|
||||
import Internal.Tools.Timestamp exposing (Timestamp)
|
||||
import Internal.Values.Event as Internal
|
||||
|
@ -86,7 +86,7 @@ initFromClientEventWithoutRoomId rId output =
|
|||
(\(SyncSO.UnsignedData data) ->
|
||||
{ age = data.age
|
||||
, prevContent = data.prevContent
|
||||
, redactedBecause = Maybe.map (initFromClientEventWithoutRoomId roomId) data.redactedBecause
|
||||
, redactedBecause = Maybe.map (initFromClientEventWithoutRoomId rId) data.redactedBecause
|
||||
, transactionId = data.transactionId
|
||||
}
|
||||
)
|
||||
|
|
|
@ -3,13 +3,18 @@ module Internal.Room exposing (..)
|
|||
{-| The `Room` type represents a Matrix Room. In here, you will find utilities to ask information about a room.
|
||||
-}
|
||||
|
||||
import Dict
|
||||
import Internal.Api.All as Api
|
||||
import Internal.Api.PreApi.Objects.Versions as V
|
||||
import Internal.Api.Sync.V2.SpecObjects as Sync
|
||||
import Internal.Event as Event exposing (Event)
|
||||
import Internal.Tools.Exceptions as X
|
||||
import Internal.Tools.Hashdict as Hashdict
|
||||
import Internal.Tools.LoginValues exposing (AccessToken)
|
||||
import Internal.Values.Event as IEvent
|
||||
import Internal.Values.Room as Internal
|
||||
import Internal.Values.StateManager as StateManager
|
||||
import Internal.Values.Timeline as Timeline
|
||||
import Json.Encode as E
|
||||
import Task exposing (Task)
|
||||
|
||||
|
@ -31,6 +36,57 @@ type Room
|
|||
}
|
||||
|
||||
|
||||
{-| Create a new object from a joined room.
|
||||
-}
|
||||
initFromJoinedRoom : { roomId : String, nextBatch : String } -> Sync.JoinedRoom -> Internal.Room
|
||||
initFromJoinedRoom data jroom =
|
||||
Internal.Room
|
||||
{ accountData =
|
||||
jroom.accountData
|
||||
|> Maybe.map .events
|
||||
|> Maybe.withDefault []
|
||||
|> List.map (\{ contentType, content } -> ( contentType, content ))
|
||||
|> Dict.fromList
|
||||
, ephemeral =
|
||||
jroom.ephemeral
|
||||
|> Maybe.map .events
|
||||
|> Maybe.withDefault []
|
||||
|> List.map IEvent.BlindEvent
|
||||
, events =
|
||||
jroom.timeline
|
||||
|> Maybe.map .events
|
||||
|> Maybe.withDefault []
|
||||
|> List.map (Event.initFromClientEventWithoutRoomId data.roomId)
|
||||
|> Hashdict.fromList IEvent.eventId
|
||||
, roomId = data.roomId
|
||||
, timeline =
|
||||
jroom.timeline
|
||||
|> Maybe.map
|
||||
(\timeline ->
|
||||
Timeline.newFromEvents
|
||||
{ events = List.map (Event.initFromClientEventWithoutRoomId data.roomId) timeline.events
|
||||
, nextBatch = data.nextBatch
|
||||
, prevBatch = timeline.prevBatch
|
||||
, stateDelta =
|
||||
jroom.state
|
||||
|> Maybe.map
|
||||
(.events
|
||||
>> List.map (Event.initFromClientEventWithoutRoomId data.roomId)
|
||||
>> StateManager.fromEventList
|
||||
)
|
||||
}
|
||||
)
|
||||
|> Maybe.withDefault
|
||||
(Timeline.newFromEvents
|
||||
{ events = []
|
||||
, nextBatch = data.nextBatch
|
||||
, prevBatch = Nothing
|
||||
, stateDelta = Nothing
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
{-| Adds an internal event to the `Room`. An internal event is a custom event
|
||||
that has been generated by the client.
|
||||
-}
|
||||
|
@ -66,6 +122,21 @@ internalValue (Room { room }) =
|
|||
room
|
||||
|
||||
|
||||
{-| Get the most recent events.
|
||||
-}
|
||||
mostRecentEvents : Room -> List Event
|
||||
mostRecentEvents (Room data) =
|
||||
data.room
|
||||
|> Internal.mostRecentEvents
|
||||
|> List.map
|
||||
(Event.init
|
||||
{ accessToken = data.accessToken
|
||||
, baseUrl = data.baseUrl
|
||||
, versions = data.versions
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
{-| Retrieves the ID of the Matrix room associated with the given `Room`.
|
||||
-}
|
||||
roomId : Room -> String
|
||||
|
|
|
@ -11,7 +11,13 @@ import Internal.Values.Room as Room exposing (Room)
|
|||
|
||||
|
||||
type Credentials
|
||||
= Credentials { access : AccessToken, baseUrl : String, rooms : Hashdict Room, versions : Maybe V.Versions }
|
||||
= Credentials
|
||||
{ access : AccessToken
|
||||
, baseUrl : String
|
||||
, rooms : Hashdict Room
|
||||
, since : Maybe String
|
||||
, versions : Maybe V.Versions
|
||||
}
|
||||
|
||||
|
||||
{-| Add a new access token based on prior information.
|
||||
|
@ -28,6 +34,13 @@ addVersions versions (Credentials data) =
|
|||
Credentials { data | versions = Just versions }
|
||||
|
||||
|
||||
{-| Add a new `since` token to sync from.
|
||||
-}
|
||||
addSince : String -> Credentials -> Credentials
|
||||
addSince since (Credentials data) =
|
||||
Credentials { data | since = Just since }
|
||||
|
||||
|
||||
{-| Get the stringed access token the Credentials type is using, if any.
|
||||
-}
|
||||
getAccessToken : Credentials -> Maybe String
|
||||
|
@ -64,10 +77,18 @@ defaultCredentials homeserver =
|
|||
{ access = NoAccess
|
||||
, baseUrl = homeserver
|
||||
, rooms = Hashdict.empty Room.roomId
|
||||
, since = Nothing
|
||||
, versions = Nothing
|
||||
}
|
||||
|
||||
|
||||
{-| Get the latest `since` token.
|
||||
-}
|
||||
getSince : Credentials -> Maybe String
|
||||
getSince (Credentials { since }) =
|
||||
since
|
||||
|
||||
|
||||
{-| Create a Credentials type using an unknown access token.
|
||||
-}
|
||||
fromAccessToken : { accessToken : String, homeserver : String } -> Credentials
|
||||
|
@ -102,3 +123,10 @@ insertRoom : Room -> Credentials -> Credentials
|
|||
insertRoom room (Credentials cred) =
|
||||
Credentials
|
||||
{ cred | rooms = Hashdict.insert room cred.rooms }
|
||||
|
||||
|
||||
{-| Get a list of all synchronised rooms.
|
||||
-}
|
||||
getRooms : Credentials -> List Room
|
||||
getRooms (Credentials { rooms }) =
|
||||
Hashdict.values rooms
|
||||
|
|
|
@ -56,3 +56,10 @@ getEventById eventId (Room room) =
|
|||
roomId : Room -> String
|
||||
roomId (Room room) =
|
||||
room.roomId
|
||||
|
||||
|
||||
{-| Get the most recent events.
|
||||
-}
|
||||
mostRecentEvents : Room -> List Event
|
||||
mostRecentEvents (Room room) =
|
||||
Timeline.mostRecentEvents room.timeline
|
||||
|
|
Loading…
Reference in New Issue