Refactor public types

pull/1/head
Bram van den Heuvel 2023-03-03 16:07:37 +01:00
parent caab0ae0bb
commit 9dec58b3d4
10 changed files with 317 additions and 284 deletions

73
src/Internal/Context.elm Normal file
View File

@ -0,0 +1,73 @@
module Internal.Context exposing (..)
{-| The `Context` type serves as an extra layer between the internal Room/Event types
and the types that the user may deal with directly.
Since pointers cannot point to values that the `Credentials` type has,
the `Credentials` type passes information down in the form of a `Context` type.
-}
import Internal.Api.PreApi.Objects.Versions as V
import Internal.Tools.LoginValues as Login exposing (AccessToken(..))
type Context
= Context
{ access : AccessToken
, homeserver : String
, vs : Maybe V.Versions
}
{-| Retrieves the access token from a given `Context` value.
-}
accessToken : Context -> AccessToken
accessToken (Context { access }) =
access
{-| Add a new access token to the `Context` type.
-}
addToken : String -> Context -> Context
addToken token (Context ({ access } as data)) =
Context { data | access = Login.addToken token access }
{-| Add a username and password to the `Context` type.
-}
addUsernameAndPassword : { username : String, password : String } -> Context -> Context
addUsernameAndPassword uap (Context ({ access } as data)) =
Context { data | access = Login.addUsernameAndPassword uap access }
{-| Add known spec versions to the `Context` type.
-}
addVersions : V.Versions -> Context -> Context
addVersions vs (Context data) =
Context { data | vs = Just vs }
{-| Retrieves the base url from a given `Context` value.
-}
baseUrl : Context -> String
baseUrl (Context { homeserver }) =
homeserver
{-| Creates a `Context` value from a base URL.
-}
fromBaseUrl : String -> Context
fromBaseUrl url =
Context
{ access = NoAccess
, homeserver = url
, vs = Nothing
}
{-| Retrieves the spec versions from a given `Context` value.
-}
versions : Context -> Maybe V.Versions
versions (Context { vs }) =
vs

View File

@ -9,6 +9,7 @@ This file combines the internal functions with the API endpoints to create a ful
import Dict
import Internal.Api.All as Api
import Internal.Context as Context exposing (Context)
import Internal.Event as Event
import Internal.Room as Room
import Internal.Tools.Exceptions as X
@ -24,8 +25,11 @@ and Elm will figure out which key to use.
If you pass the `Credentials` into any function, then the library will look for
the right keys and tokens to get the right information.
-}
type alias Credentials =
Internal.Credentials
type Credentials
= Credentials
{ cred : Internal.ICredentials
, context : Context
}
{-| Get a Credentials type based on an unknown access token.
@ -34,50 +38,57 @@ This is an easier way to connect to a Matrix homeserver, but your access may end
when the access token expires, is revoked or something else happens.
-}
fromAccessToken : { homeserver : String, accessToken : String } -> Credentials
fromAccessToken =
Internal.fromAccessToken
fromAccessToken : { baseUrl : String, accessToken : String } -> Credentials
fromAccessToken { baseUrl, accessToken } =
Context.fromBaseUrl baseUrl
|> Context.addToken accessToken
|> (\context ->
{ cred = Internal.init, context = context }
)
|> Credentials
{-| Get a Credentials type using a username and password.
-}
fromLoginCredentials : { username : String, password : String, homeserver : String } -> Credentials
fromLoginCredentials =
Internal.fromLoginCredentials
fromLoginCredentials : { username : String, password : String, baseUrl : String } -> Credentials
fromLoginCredentials { username, password, baseUrl } =
Context.fromBaseUrl baseUrl
|> Context.addUsernameAndPassword
{ username = username
, password = password
}
|> (\context ->
{ cred = Internal.init, context = context }
)
|> Credentials
{-| Get a room based on its id.
-}
getRoomById : String -> Credentials -> Maybe Room.Room
getRoomById roomId credentials =
Internal.getRoomById roomId credentials
|> Maybe.map
(Room.init
{ accessToken = Internal.getAccessTokenType credentials
, baseUrl = Internal.getBaseUrl credentials
, versions = Internal.getVersions credentials
}
)
getRoomById roomId (Credentials { cred, context }) =
Internal.getRoomById roomId cred
|> Maybe.map (Room.withContext context)
{-| Insert an internal room type into the credentials.
-}
insertInternalRoom : IRoom.Room -> Credentials -> Credentials
insertInternalRoom =
Internal.insertRoom
insertInternalRoom : IRoom.IRoom -> Credentials -> Credentials
insertInternalRoom iroom (Credentials data) =
Credentials { data | cred = Internal.insertRoom iroom data.cred }
{-| Internal a full room type into the credentials.
-}
insertRoom : Room.Room -> Credentials -> Credentials
insertRoom =
Room.internalValue >> insertInternalRoom
Room.withoutContext >> insertInternalRoom
{-| Update the Credentials type with new values
-}
updateWith : Api.CredUpdate -> Credentials -> Credentials
updateWith credUpdate credentials =
updateWith credUpdate ((Credentials ({ cred, context } as data)) as credentials) =
case credUpdate of
Api.MultipleUpdates updates ->
List.foldl updateWith credentials updates
@ -109,6 +120,7 @@ updateWith credUpdate credentials =
-- TODO
Api.SyncUpdate input output ->
let
jRooms : List IRoom.IRoom
jRooms =
output.rooms
|> Maybe.map .join
@ -119,68 +131,73 @@ updateWith credUpdate credentials =
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
)
}
case jroom.timeline of
Just timeline ->
room
|> Room.withoutContext
|> IRoom.addEvents
{ events =
List.map
(Event.initFromClientEventWithoutRoomId roomId)
timeline.events
, limited = timeline.limited
, nextBatch = output.nextBatch
, prevBatch =
timeline.prevBatch
|> Maybe.withDefault
(Maybe.withDefault "" input.since)
, stateDelta =
jroom.state
|> Maybe.map
(.events
>> List.map (Event.initFromClientEventWithoutRoomId roomId)
>> StateManager.fromEventList
)
}
Nothing ->
Room.withoutContext room
-- Add new room
Nothing ->
Room.initFromJoinedRoom { nextBatch = output.nextBatch, roomId = roomId } jroom
jroom
|> Room.initFromJoinedRoom { nextBatch = output.nextBatch, roomId = roomId }
)
in
List.foldl Internal.insertRoom (Internal.addSince output.nextBatch credentials) jRooms
cred
|> Internal.addSince output.nextBatch
|> List.foldl Internal.insertRoom
|> (|>) jRooms
|> (\x -> { cred = x, context = context })
|> Credentials
Api.UpdateAccessToken token ->
Internal.addAccessToken token credentials
Credentials { data | context = Context.addToken token context }
Api.UpdateVersions versions ->
Internal.addVersions versions credentials
Credentials { data | context = Context.addVersions versions context }
{-| Synchronize credentials
-}
sync : Credentials -> Task X.Error Api.CredUpdate
sync credentials =
sync (Credentials { cred, context }) =
Api.syncCredentials
{ accessToken = Internal.getAccessTokenType credentials
, baseUrl = Internal.getBaseUrl credentials
{ accessToken = Context.accessToken context
, baseUrl = Context.baseUrl context
, filter = Nothing
, fullState = Nothing
, setPresence = Nothing
, since = Internal.getSince credentials
, since = Internal.getSince cred
, timeout = Just 30
, versions = Internal.getVersions credentials
, versions = Context.versions context
}
{-| Get a list of all synchronised rooms.
-}
rooms : Credentials -> List Room.Room
rooms credentials =
credentials
rooms (Credentials { cred, context }) =
cred
|> Internal.getRooms
|> ({ accessToken = Internal.getAccessTokenType credentials
, baseUrl = Internal.getBaseUrl credentials
, versions = Internal.getVersions credentials
}
|> Room.init
|> List.map
)
|> List.map (Room.withContext context)

View File

@ -9,9 +9,8 @@ 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.V2.SpecObjects as SyncSO
import Internal.Tools.LoginValues exposing (AccessToken)
import Internal.Context exposing (Context)
import Internal.Tools.Timestamp exposing (Timestamp)
import Internal.Values.Event as Internal
import Json.Encode as E
@ -21,30 +20,26 @@ import Json.Encode as E
-}
type Event
= Event
{ event : Internal.Event
, accessToken : AccessToken
, baseUrl : String
, versions : Maybe V.Versions
{ event : Internal.IEvent
, context : Context
}
{-| Using the credentials' background information and an internal event type,
create an interactive event type.
-}
init : { accessToken : AccessToken, baseUrl : String, versions : Maybe V.Versions } -> Internal.Event -> Event
init { accessToken, baseUrl, versions } event =
withContext : Context -> Internal.IEvent -> Event
withContext context event =
Event
{ event = event
, accessToken = accessToken
, baseUrl = baseUrl
, versions = versions
, context = context
}
{-| Create an internal event type from an API endpoint event object.
This function is placed in this file to respect file hierarchy and avoid circular imports.
-}
initFromGetEvent : GetEvent.EventOutput -> Internal.Event
initFromGetEvent : GetEvent.EventOutput -> Internal.IEvent
initFromGetEvent output =
Internal.init
{ content = output.content
@ -70,7 +65,7 @@ initFromGetEvent output =
{-| Create an internal event type from an API endpoint event object.
This function is placed in this file to respect file hierarchy and avoid circular imports.
-}
initFromClientEventWithoutRoomId : String -> SyncSO.ClientEventWithoutRoomId -> Internal.Event
initFromClientEventWithoutRoomId : String -> SyncSO.ClientEventWithoutRoomId -> Internal.IEvent
initFromClientEventWithoutRoomId rId output =
Internal.init
{ content = output.content
@ -95,8 +90,8 @@ initFromClientEventWithoutRoomId rId output =
{-| Get the internal event type that is hidden in the interactive event type.
-}
internalValue : Event -> Internal.Event
internalValue (Event { event }) =
withoutContext : Event -> Internal.IEvent
withoutContext (Event { event }) =
event
@ -106,42 +101,42 @@ internalValue (Event { event }) =
content : Event -> E.Value
content =
internalValue >> Internal.content
withoutContext >> Internal.content
eventId : Event -> String
eventId =
internalValue >> Internal.eventId
withoutContext >> Internal.eventId
originServerTs : Event -> Timestamp
originServerTs =
internalValue >> Internal.originServerTs
withoutContext >> Internal.originServerTs
roomId : Event -> String
roomId =
internalValue >> Internal.roomId
withoutContext >> Internal.roomId
sender : Event -> String
sender =
internalValue >> Internal.sender
withoutContext >> Internal.sender
stateKey : Event -> Maybe String
stateKey =
internalValue >> Internal.stateKey
withoutContext >> Internal.stateKey
contentType : Event -> String
contentType =
internalValue >> Internal.contentType
withoutContext >> Internal.contentType
age : Event -> Maybe Int
age =
internalValue >> Internal.age
withoutContext >> Internal.age
redactedBecause : Event -> Maybe Event
@ -156,4 +151,4 @@ redactedBecause (Event data) =
transactionId : Event -> Maybe String
transactionId =
internalValue >> Internal.transactionId
withoutContext >> Internal.transactionId

View File

@ -5,12 +5,11 @@ module Internal.Room exposing (..)
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.Context as Context exposing (Context)
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
@ -29,18 +28,16 @@ to it.
-}
type Room
= Room
{ room : Internal.Room
, accessToken : AccessToken
, baseUrl : String
, versions : Maybe V.Versions
{ room : Internal.IRoom
, context : Context
}
{-| Create a new object from a joined room.
-}
initFromJoinedRoom : { roomId : String, nextBatch : String } -> Sync.JoinedRoom -> Internal.Room
initFromJoinedRoom : { roomId : String, nextBatch : String } -> Sync.JoinedRoom -> Internal.IRoom
initFromJoinedRoom data jroom =
Internal.Room
Internal.IRoom
{ accountData =
jroom.accountData
|> Maybe.map .events
@ -90,7 +87,7 @@ initFromJoinedRoom data jroom =
{-| Adds an internal event to the `Room`. An internal event is a custom event
that has been generated by the client.
-}
addInternalEvent : IEvent.Event -> Room -> Room
addInternalEvent : IEvent.IEvent -> Room -> Room
addInternalEvent ievent (Room ({ room } as data)) =
Room { data | room = Internal.addEvent ievent room }
@ -100,61 +97,53 @@ addInternalEvent ievent (Room ({ room } as data)) =
-}
addEvent : Event -> Room -> Room
addEvent =
Event.internalValue >> addInternalEvent
Event.withoutContext >> addInternalEvent
{-| Creates a new `Room` object with the given parameters.
-}
init : { accessToken : AccessToken, baseUrl : String, versions : Maybe V.Versions } -> Internal.Room -> Room
init { accessToken, baseUrl, versions } room =
withContext : Context -> Internal.IRoom -> Room
withContext context room =
Room
{ accessToken = accessToken
, baseUrl = baseUrl
{ context = context
, room = room
, versions = versions
}
{-| Retrieves the `Internal.Room` type contained within the given `Room`.
{-| Retrieves the `Internal.IRoom` type contained within the given `Room`.
-}
internalValue : Room -> Internal.Room
internalValue (Room { room }) =
withoutContext : Room -> Internal.IRoom
withoutContext (Room { room }) =
room
{-| Get the most recent events.
-}
mostRecentEvents : Room -> List Event
mostRecentEvents (Room data) =
data.room
mostRecentEvents (Room { context, room }) =
room
|> Internal.mostRecentEvents
|> List.map
(Event.init
{ accessToken = data.accessToken
, baseUrl = data.baseUrl
, versions = data.versions
}
)
|> List.map (Event.withContext context)
{-| Retrieves the ID of the Matrix room associated with the given `Room`.
-}
roomId : Room -> String
roomId =
internalValue >> Internal.roomId
withoutContext >> Internal.roomId
{-| Sends a new event to the Matrix room associated with the given `Room`.
-}
sendEvent : Room -> { eventType : String, content : E.Value } -> Task X.Error Api.CredUpdate
sendEvent (Room { room, accessToken, baseUrl, versions }) { eventType, content } =
sendEvent (Room { context, room }) { eventType, content } =
Api.sendMessageEvent
{ accessToken = accessToken
, baseUrl = baseUrl
{ accessToken = Context.accessToken context
, baseUrl = Context.baseUrl context
, content = content
, eventType = eventType
, roomId = Internal.roomId room
, versions = versions
, versions = Context.versions context
, extraTransactionNoise = "content-value:<object>"
}
@ -162,10 +151,10 @@ sendEvent (Room { room, accessToken, baseUrl, versions }) { eventType, content }
{-| Sends a new text message to the Matrix room associated with the given `Room`.
-}
sendMessage : Room -> String -> Task X.Error Api.CredUpdate
sendMessage (Room { room, accessToken, baseUrl, versions }) text =
sendMessage (Room { context, room }) text =
Api.sendMessageEvent
{ accessToken = accessToken
, baseUrl = baseUrl
{ accessToken = Context.accessToken context
, baseUrl = Context.baseUrl context
, content =
E.object
[ ( "msgtype", E.string "m.text" )
@ -173,6 +162,6 @@ sendMessage (Room { room, accessToken, baseUrl, versions }) text =
]
, eventType = "m.room.message"
, roomId = Internal.roomId room
, versions = versions
, versions = Context.versions context
, extraTransactionNoise = "literal-message:" ++ text
}

View File

@ -54,3 +54,28 @@ addToken s t =
, password = password
, token = Just s
}
addUsernameAndPassword : { username : String, password : String } -> AccessToken -> AccessToken
addUsernameAndPassword { username, password } t =
case t of
NoAccess ->
UsernameAndPassword
{ username = username
, password = password
, token = Nothing
}
AccessToken a ->
UsernameAndPassword
{ username = username
, password = password
, token = Just a
}
UsernameAndPassword { token } ->
UsernameAndPassword
{ username = username
, password = password
, token = token
}

View File

@ -4,129 +4,61 @@ module Internal.Values.Credentials exposing (..)
It handles all communication with the homeserver.
-}
import Internal.Api.PreApi.Objects.Versions as V
import Internal.Tools.Hashdict as Hashdict exposing (Hashdict)
import Internal.Tools.LoginValues as Login exposing (AccessToken(..))
import Internal.Values.Room as Room exposing (Room)
import Internal.Values.Room as Room exposing (IRoom)
type Credentials
= Credentials
{ access : AccessToken
, baseUrl : String
, rooms : Hashdict Room
type ICredentials
= ICredentials
{ rooms : Hashdict IRoom
, since : Maybe String
, versions : Maybe V.Versions
}
{-| Add a new access token based on prior information.
-}
addAccessToken : String -> Credentials -> Credentials
addAccessToken token (Credentials ({ access } as data)) =
Credentials { data | access = Login.addToken token access }
{-| Add the list of versions that is supported by the homeserver.
-}
addVersions : V.Versions -> Credentials -> Credentials
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
getAccessToken =
getAccessTokenType >> Login.getToken
{-| Get the access token type that stores the Credentials's ways of getting access.
-}
getAccessTokenType : Credentials -> AccessToken
getAccessTokenType (Credentials { access }) =
access
{-| Get the baseUrl that the credentials accesses.
-}
getBaseUrl : Credentials -> String
getBaseUrl (Credentials { baseUrl }) =
baseUrl
{-| Get the versions that the homeserver supports.
-}
getVersions : Credentials -> Maybe V.Versions
getVersions (Credentials { versions }) =
versions
{-| Internal value to be used as a "default" for credentials settings.
-}
defaultCredentials : String -> Credentials
defaultCredentials homeserver =
Credentials
{ 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
fromAccessToken { accessToken, homeserver } =
case defaultCredentials homeserver of
Credentials c ->
Credentials { c | access = AccessToken accessToken }
{-| Create a Credentials type using a username and password.
-}
fromLoginCredentials : { username : String, password : String, homeserver : String } -> Credentials
fromLoginCredentials { username, password, homeserver } =
case defaultCredentials homeserver of
Credentials c ->
Credentials { c | access = UsernameAndPassword { username = username, password = password, token = Nothing } }
addSince : String -> ICredentials -> ICredentials
addSince since (ICredentials data) =
ICredentials { data | since = Just since }
{-| Get a room from the Credentials type by the room's id.
-}
getRoomById : String -> Credentials -> Maybe Room
getRoomById roomId (Credentials cred) =
getRoomById : String -> ICredentials -> Maybe IRoom
getRoomById roomId (ICredentials cred) =
Hashdict.get roomId cred.rooms
{-| Get a list of all synchronised rooms.
-}
getRooms : ICredentials -> List IRoom
getRooms (ICredentials { rooms }) =
Hashdict.values rooms
{-| Get the latest `since` token.
-}
getSince : ICredentials -> Maybe String
getSince (ICredentials { since }) =
since
{-| Create new empty Credentials.
-}
init : ICredentials
init =
ICredentials
{ rooms = Hashdict.empty Room.roomId
, since = Nothing
}
{-| Add a new room to the Credentials type. If a room with this id already exists, it is overwritten.
This function can hence also be used as an update function for rooms.
-}
insertRoom : Room -> Credentials -> Credentials
insertRoom room (Credentials cred) =
Credentials
insertRoom : IRoom -> ICredentials -> ICredentials
insertRoom room (ICredentials cred) =
ICredentials
{ cred | rooms = Hashdict.insert room cred.rooms }
{-| Get a list of all synchronised rooms.
-}
getRooms : Credentials -> List Room
getRooms (Credentials { rooms }) =
Hashdict.values rooms

View File

@ -4,8 +4,8 @@ import Internal.Tools.Timestamp exposing (Timestamp)
import Json.Encode as E
type Event
= Event
type IEvent
= IEvent
{ content : E.Value
, eventId : String
, originServerTs : Timestamp
@ -17,7 +17,7 @@ type Event
Maybe
{ age : Maybe Int
, prevContent : Maybe E.Value
, redactedBecause : Maybe Event
, redactedBecause : Maybe IEvent
, transactionId : Maybe String
}
}
@ -35,68 +35,68 @@ init :
Maybe
{ age : Maybe Int
, prevContent : Maybe E.Value
, redactedBecause : Maybe Event
, redactedBecause : Maybe IEvent
, transactionId : Maybe String
}
}
-> Event
-> IEvent
init =
Event
IEvent
{- GETTER FUNCTIONS -}
content : Event -> E.Value
content (Event e) =
content : IEvent -> E.Value
content (IEvent e) =
e.content
eventId : Event -> String
eventId (Event e) =
eventId : IEvent -> String
eventId (IEvent e) =
e.eventId
originServerTs : Event -> Timestamp
originServerTs (Event e) =
originServerTs : IEvent -> Timestamp
originServerTs (IEvent e) =
e.originServerTs
roomId : Event -> String
roomId (Event e) =
roomId : IEvent -> String
roomId (IEvent e) =
e.roomId
sender : Event -> String
sender (Event e) =
sender : IEvent -> String
sender (IEvent e) =
e.sender
stateKey : Event -> Maybe String
stateKey (Event e) =
stateKey : IEvent -> Maybe String
stateKey (IEvent e) =
e.stateKey
contentType : Event -> String
contentType (Event e) =
contentType : IEvent -> String
contentType (IEvent e) =
e.contentType
age : Event -> Maybe Int
age (Event e) =
age : IEvent -> Maybe Int
age (IEvent e) =
e.unsigned
|> Maybe.andThen .age
redactedBecause : Event -> Maybe Event
redactedBecause (Event e) =
redactedBecause : IEvent -> Maybe IEvent
redactedBecause (IEvent e) =
e.unsigned
|> Maybe.andThen .redactedBecause
transactionId : Event -> Maybe String
transactionId (Event e) =
transactionId : IEvent -> Maybe String
transactionId (IEvent e) =
e.unsigned
|> Maybe.andThen .transactionId

View File

@ -3,17 +3,17 @@ module Internal.Values.Room exposing (..)
import Dict exposing (Dict)
import Internal.Tools.Hashdict as Hashdict exposing (Hashdict)
import Internal.Tools.SpecEnums exposing (SessionDescriptionType(..))
import Internal.Values.Event as Event exposing (BlindEvent, Event)
import Internal.Values.Event exposing (BlindEvent, IEvent)
import Internal.Values.StateManager exposing (StateManager)
import Internal.Values.Timeline as Timeline exposing (Timeline)
import Json.Encode as E
type Room
= Room
type IRoom
= IRoom
{ accountData : Dict String E.Value
, ephemeral : List BlindEvent
, events : Hashdict Event
, events : Hashdict IEvent
, roomId : String
, timeline : Timeline
}
@ -21,23 +21,24 @@ type Room
{-| Add the data of a single event to the hashdict of events.
-}
addEvent : Event -> Room -> Room
addEvent event (Room ({ events } as room)) =
Room { room | events = Hashdict.insert event events }
addEvent : IEvent -> IRoom -> IRoom
addEvent event (IRoom ({ events } as room)) =
IRoom { room | events = Hashdict.insert event events }
{-| Add new events as the most recent events.
-}
addEvents :
{ events : List Event
{ events : List IEvent
, limited : Bool
, nextBatch : String
, prevBatch : String
, stateDelta : Maybe StateManager
}
-> Room
-> Room
addEvents ({ events } as data) (Room room) =
Room
-> IRoom
-> IRoom
addEvents ({ events } as data) (IRoom room) =
IRoom
{ room
| events = List.foldl Hashdict.insert room.events events
, timeline = Timeline.addNewEvents data room.timeline
@ -46,20 +47,20 @@ addEvents ({ events } as data) (Room room) =
{-| Get an event by its id.
-}
getEventById : String -> Room -> Maybe Event
getEventById eventId (Room room) =
getEventById : String -> IRoom -> Maybe IEvent
getEventById eventId (IRoom room) =
Hashdict.get eventId room.events
{-| Get the room's id.
-}
roomId : Room -> String
roomId (Room room) =
roomId : IRoom -> String
roomId (IRoom room) =
room.roomId
{-| Get the most recent events.
-}
mostRecentEvents : Room -> List Event
mostRecentEvents (Room room) =
mostRecentEvents : IRoom -> List IEvent
mostRecentEvents (IRoom room) =
Timeline.mostRecentEvents room.timeline

View File

@ -1,14 +1,14 @@
module Internal.Values.StateManager exposing (..)
import Dict exposing (Dict)
import Internal.Values.Event as Event exposing (Event)
import Internal.Values.Event as Event exposing (IEvent)
type alias StateManager =
Dict ( String, String ) Event
Dict ( String, String ) IEvent
addEvent : Event -> StateManager -> StateManager
addEvent : IEvent -> StateManager -> StateManager
addEvent event oldManager =
case Event.stateKey event of
Just key ->
@ -18,7 +18,7 @@ addEvent event oldManager =
oldManager
getStateEvent : String -> String -> StateManager -> Maybe Event
getStateEvent : String -> String -> StateManager -> Maybe IEvent
getStateEvent eventType stateKey =
Dict.get ( eventType, stateKey )
@ -28,13 +28,13 @@ updateRoomStateWith =
Dict.union
fromEvent : Event -> StateManager
fromEvent : IEvent -> StateManager
fromEvent event =
Dict.empty
|> addEvent event
fromEventList : List Event -> StateManager
fromEventList : List IEvent -> StateManager
fromEventList =
List.foldl addEvent Dict.empty

View File

@ -5,7 +5,7 @@ module Internal.Values.Timeline exposing (..)
import Internal.Config.Leaking as Leaking
import Internal.Tools.Fold as Fold
import Internal.Values.Event as Event exposing (Event)
import Internal.Values.Event as Event exposing (IEvent)
import Internal.Values.StateManager as StateManager exposing (StateManager)
@ -13,7 +13,7 @@ type Timeline
= Timeline
{ prevBatch : String
, nextBatch : String
, events : List Event
, events : List IEvent
, stateAtStart : StateManager
, previous : BeforeTimeline
}
@ -28,16 +28,17 @@ type BeforeTimeline
{-| Add a new batch of events to the front of the timeline.
-}
addNewEvents :
{ events : List Event
{ events : List IEvent
, limited : Bool
, nextBatch : String
, prevBatch : String
, stateDelta : Maybe StateManager
}
-> Timeline
-> Timeline
addNewEvents { events, nextBatch, prevBatch, stateDelta } (Timeline t) =
addNewEvents { events, limited, nextBatch, prevBatch, stateDelta } (Timeline t) =
Timeline
(if prevBatch == t.nextBatch then
(if prevBatch == t.nextBatch || not limited then
{ t
| events = t.events ++ events
, nextBatch = nextBatch
@ -63,7 +64,7 @@ addNewEvents { events, nextBatch, prevBatch, stateDelta } (Timeline t) =
{-| Create a new timeline.
-}
newFromEvents :
{ events : List Event
{ events : List IEvent
, nextBatch : String
, prevBatch : Maybe String
, stateDelta : Maybe StateManager
@ -89,7 +90,7 @@ newFromEvents { events, nextBatch, prevBatch, stateDelta } =
{-| Insert events starting from a known batch token.
-}
insertEvents :
{ events : List Event
{ events : List IEvent
, nextBatch : String
, prevBatch : String
, stateDelta : Maybe StateManager
@ -157,7 +158,7 @@ localSize =
{-| Get a list of the most recent events recorded.
-}
mostRecentEvents : Timeline -> List Event
mostRecentEvents : Timeline -> List IEvent
mostRecentEvents (Timeline t) =
t.events
@ -180,7 +181,7 @@ mostRecentState (Timeline t) =
{-| Get the timeline's room state at any given event. The function returns `Nothing` if the event is not found in the timeline.
-}
stateAtEvent : Event -> Timeline -> Maybe StateManager
stateAtEvent : IEvent -> Timeline -> Maybe StateManager
stateAtEvent event (Timeline t) =
if
t.events