Refactor public types
parent
caab0ae0bb
commit
9dec58b3d4
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue