Refactor Credentials to Snackbar
The Snackbar type is a type of candies (tokens) that is brought along with any data type that may be passed on to the user.pull/1/head
parent
66383551d1
commit
619cd53a3a
|
@ -0,0 +1,110 @@
|
|||
module Internal.Api.Snackbar exposing (..)
|
||||
|
||||
{-| The snackbar module helps wraps relevant credentials, access tokens, refresh tokens and more around internal types.
|
||||
|
||||
Vault, Room and Event types don't need access to API tokens,
|
||||
but a user may way to redact an event, leave a room or reject an invite.
|
||||
In such a case, the `Snackbar` type is a bowl of token candies that you can wrap
|
||||
around any data type.
|
||||
|
||||
That way, you can both access the type within AND carry the tokens on every type
|
||||
without needing to update every data type whenever any of the tokens change.
|
||||
|
||||
-}
|
||||
|
||||
import Internal.Api.Versions.V1.Versions as V
|
||||
import Internal.Tools.LoginValues as Login exposing (AccessToken(..))
|
||||
|
||||
|
||||
type Snackbar a
|
||||
= Snackbar
|
||||
{ access : AccessToken
|
||||
, content : a
|
||||
, homeserver : String
|
||||
, vs : Maybe V.Versions
|
||||
}
|
||||
|
||||
|
||||
accessToken : Snackbar a -> AccessToken
|
||||
accessToken (Snackbar { access }) =
|
||||
access
|
||||
|
||||
|
||||
addToken : String -> Snackbar a -> Snackbar a
|
||||
addToken token (Snackbar ({ access } as data)) =
|
||||
Snackbar { data | access = Login.addToken token access }
|
||||
|
||||
|
||||
addUsernameAndPassword : { username : String, password : String } -> Snackbar a -> Snackbar a
|
||||
addUsernameAndPassword uap (Snackbar ({ access } as data)) =
|
||||
Snackbar { data | access = Login.addUsernameAndPassword uap access }
|
||||
|
||||
|
||||
addVersions : V.Versions -> Snackbar a -> Snackbar a
|
||||
addVersions vs (Snackbar data) =
|
||||
Snackbar { data | vs = Just vs }
|
||||
|
||||
|
||||
addWhoAmI : { w | userId : String, deviceId : Maybe String } -> Snackbar a -> Snackbar a
|
||||
addWhoAmI whoami (Snackbar ({ access } as data)) =
|
||||
Snackbar { data | access = Login.addWhoAmI whoami access }
|
||||
|
||||
|
||||
baseUrl : Snackbar a -> String
|
||||
baseUrl (Snackbar { homeserver }) =
|
||||
homeserver
|
||||
|
||||
|
||||
init : { baseUrl : String, content : a } -> Snackbar a
|
||||
init data =
|
||||
Snackbar
|
||||
{ access = NoAccess
|
||||
, content = data.content
|
||||
, homeserver = data.baseUrl
|
||||
, vs = Nothing
|
||||
}
|
||||
|
||||
|
||||
map : (a -> b) -> Snackbar a -> Snackbar b
|
||||
map f (Snackbar data) =
|
||||
Snackbar
|
||||
{ access = data.access
|
||||
, content = f data.content
|
||||
, homeserver = data.homeserver
|
||||
, vs = data.vs
|
||||
}
|
||||
|
||||
|
||||
mapList : (a -> List b) -> Snackbar a -> List (Snackbar b)
|
||||
mapList f (Snackbar data) =
|
||||
List.map (withCandyFrom (Snackbar data)) (f data.content)
|
||||
|
||||
|
||||
mapMaybe : (a -> Maybe b) -> Snackbar a -> Maybe (Snackbar b)
|
||||
mapMaybe f (Snackbar data) =
|
||||
Maybe.map (withCandyFrom (Snackbar data)) (f data.content)
|
||||
|
||||
|
||||
removedAccessToken : Snackbar a -> AccessToken
|
||||
removedAccessToken (Snackbar { access }) =
|
||||
Login.removeToken access
|
||||
|
||||
|
||||
userId : Snackbar a -> Maybe String
|
||||
userId (Snackbar { access }) =
|
||||
Login.getUserId access
|
||||
|
||||
|
||||
versions : Snackbar a -> Maybe V.Versions
|
||||
versions (Snackbar { vs }) =
|
||||
vs
|
||||
|
||||
|
||||
withCandyFrom : Snackbar b -> a -> Snackbar a
|
||||
withCandyFrom snackbar x =
|
||||
map (always x) snackbar
|
||||
|
||||
|
||||
withoutCandy : Snackbar a -> a
|
||||
withoutCandy (Snackbar { content }) =
|
||||
content
|
|
@ -5,7 +5,6 @@ module Internal.Api.Task exposing (..)
|
|||
|
||||
import Hash
|
||||
import Internal.Api.Chain as Chain
|
||||
import Internal.Api.Credentials as Cred exposing (Credentials)
|
||||
import Internal.Api.GetEvent.Main exposing (EventInput)
|
||||
import Internal.Api.GetMessages.Main exposing (GetMessagesInput)
|
||||
import Internal.Api.Invite.Main exposing (InviteInput)
|
||||
|
@ -14,6 +13,7 @@ import Internal.Api.JoinedMembers.Main exposing (JoinedMembersInput)
|
|||
import Internal.Api.Leave.Main exposing (LeaveInput)
|
||||
import Internal.Api.SendStateKey.Main exposing (SendStateKeyInput)
|
||||
import Internal.Api.SetAccountData.Main exposing (SetAccountInput)
|
||||
import Internal.Api.Snackbar as Snackbar exposing (Snackbar)
|
||||
import Internal.Api.Sync.Main exposing (SyncInput)
|
||||
import Internal.Api.VaultUpdate as C
|
||||
import Json.Encode as E
|
||||
|
@ -29,7 +29,7 @@ type alias EventInput =
|
|||
}
|
||||
|
||||
|
||||
getEvent : EventInput -> Credentials -> FutureTask
|
||||
getEvent : EventInput -> Snackbar a -> FutureTask
|
||||
getEvent { eventId, roomId } cred =
|
||||
C.makeVBA cred
|
||||
|> Chain.andThen (C.withSentEvent eventId)
|
||||
|
@ -37,35 +37,35 @@ getEvent { eventId, roomId } cred =
|
|||
|> C.toTask
|
||||
|
||||
|
||||
getMessages : GetMessagesInput -> Credentials -> FutureTask
|
||||
getMessages : GetMessagesInput -> Snackbar a -> FutureTask
|
||||
getMessages data cred =
|
||||
C.makeVBA cred
|
||||
|> Chain.andThen (C.getMessages data)
|
||||
|> C.toTask
|
||||
|
||||
|
||||
invite : InviteInput -> Credentials -> FutureTask
|
||||
invite : InviteInput -> Snackbar a -> FutureTask
|
||||
invite data cred =
|
||||
C.makeVBA cred
|
||||
|> Chain.andThen (C.invite data)
|
||||
|> C.toTask
|
||||
|
||||
|
||||
joinedMembers : JoinedMembersInput -> Credentials -> FutureTask
|
||||
joinedMembers : JoinedMembersInput -> Snackbar a -> FutureTask
|
||||
joinedMembers data cred =
|
||||
C.makeVBA cred
|
||||
|> Chain.andThen (C.joinedMembers data)
|
||||
|> C.toTask
|
||||
|
||||
|
||||
joinRoomById : JoinRoomByIdInput -> Credentials -> FutureTask
|
||||
joinRoomById : JoinRoomByIdInput -> Snackbar a -> FutureTask
|
||||
joinRoomById data cred =
|
||||
C.makeVBA cred
|
||||
|> Chain.andThen (C.joinRoomById data)
|
||||
|> C.toTask
|
||||
|
||||
|
||||
leave : LeaveInput -> Credentials -> FutureTask
|
||||
leave : LeaveInput -> Snackbar a -> FutureTask
|
||||
leave data cred =
|
||||
C.makeVBA cred
|
||||
|> Chain.andThen (C.leave data)
|
||||
|
@ -80,7 +80,7 @@ type alias RedactInput =
|
|||
}
|
||||
|
||||
|
||||
redact : RedactInput -> Credentials -> FutureTask
|
||||
redact : RedactInput -> Snackbar a -> FutureTask
|
||||
redact { eventId, extraTransactionNoise, reason, roomId } cred =
|
||||
cred
|
||||
|> C.makeVBAT
|
||||
|
@ -109,7 +109,7 @@ type alias SendMessageEventInput =
|
|||
}
|
||||
|
||||
|
||||
sendMessageEvent : SendMessageEventInput -> Credentials -> FutureTask
|
||||
sendMessageEvent : SendMessageEventInput -> Snackbar a -> FutureTask
|
||||
sendMessageEvent { content, eventType, extraTransactionNoise, roomId } cred =
|
||||
cred
|
||||
|> C.makeVBAT
|
||||
|
@ -130,7 +130,7 @@ sendMessageEvent { content, eventType, extraTransactionNoise, roomId } cred =
|
|||
|> C.toTask
|
||||
|
||||
|
||||
sendStateEvent : SendStateKeyInput -> Credentials -> FutureTask
|
||||
sendStateEvent : SendStateKeyInput -> Snackbar a -> FutureTask
|
||||
sendStateEvent data cred =
|
||||
C.makeVBA cred
|
||||
|> Chain.andThen C.getTimestamp
|
||||
|
@ -140,24 +140,24 @@ sendStateEvent data cred =
|
|||
|> C.toTask
|
||||
|
||||
|
||||
setAccountData : SetAccountInput -> Credentials -> FutureTask
|
||||
setAccountData : SetAccountInput -> Snackbar a -> FutureTask
|
||||
setAccountData data cred =
|
||||
C.makeVBA cred
|
||||
|> Chain.andThen (C.setAccountData data)
|
||||
|> C.toTask
|
||||
|
||||
|
||||
sync : SyncInput -> Credentials -> FutureTask
|
||||
sync : SyncInput -> Snackbar a -> FutureTask
|
||||
sync data cred =
|
||||
C.makeVBA cred
|
||||
|> Chain.andThen (C.sync data)
|
||||
|> C.toTask
|
||||
|
||||
|
||||
loginMaybeSync : SyncInput -> Credentials -> FutureTask
|
||||
loginMaybeSync : SyncInput -> Snackbar a -> FutureTask
|
||||
loginMaybeSync data cred =
|
||||
C.makeVB cred
|
||||
|> Chain.andThen (C.accessToken (Cred.refreshedAccessToken cred))
|
||||
|> Chain.andThen (C.accessToken (Snackbar.removedAccessToken cred))
|
||||
|> Chain.andThen
|
||||
(Chain.maybe <| C.sync data)
|
||||
|> C.toTask
|
||||
|
|
|
@ -2,7 +2,6 @@ module Internal.Api.VaultUpdate exposing (..)
|
|||
|
||||
import Internal.Api.Ban.Main as Ban
|
||||
import Internal.Api.Chain as Chain exposing (IdemChain, TaskChain)
|
||||
import Internal.Api.Credentials as Credentials exposing (Credentials)
|
||||
import Internal.Api.GetEvent.Main as GetEvent
|
||||
import Internal.Api.GetMessages.Main as GetMessages
|
||||
import Internal.Api.Invite.Main as Invite
|
||||
|
@ -14,6 +13,7 @@ import Internal.Api.Redact.Main as Redact
|
|||
import Internal.Api.SendMessageEvent.Main as SendMessageEvent
|
||||
import Internal.Api.SendStateKey.Main as SendStateKey
|
||||
import Internal.Api.SetAccountData.Main as SetAccountData
|
||||
import Internal.Api.Snackbar as Snackbar exposing (Snackbar)
|
||||
import Internal.Api.Sync.Main as Sync
|
||||
import Internal.Api.Versions.Main as Versions
|
||||
import Internal.Api.Versions.V1.Versions as V
|
||||
|
@ -296,28 +296,28 @@ loginWithUsernameAndPassword input =
|
|||
|
||||
{-| Make a VB-context based chain.
|
||||
-}
|
||||
makeVB : Credentials -> TaskChain VaultUpdate {} (VB {})
|
||||
makeVB cred =
|
||||
cred
|
||||
|> Credentials.baseUrl
|
||||
makeVB : Snackbar a -> TaskChain VaultUpdate {} (VB {})
|
||||
makeVB snackbar =
|
||||
snackbar
|
||||
|> Snackbar.baseUrl
|
||||
|> withBaseUrl
|
||||
|> Chain.andThen (versions (Credentials.versions cred))
|
||||
|> Chain.andThen (versions (Snackbar.versions snackbar))
|
||||
|
||||
|
||||
{-| Make a VBA-context based chain.
|
||||
-}
|
||||
makeVBA : Credentials -> TaskChain VaultUpdate {} (VBA { userId : () })
|
||||
makeVBA cred =
|
||||
cred
|
||||
makeVBA : Snackbar a -> TaskChain VaultUpdate {} (VBA { userId : () })
|
||||
makeVBA snackbar =
|
||||
snackbar
|
||||
|> makeVB
|
||||
|> Chain.andThen (accessToken (Credentials.accessToken cred))
|
||||
|> Chain.andThen (accessToken (Snackbar.accessToken snackbar))
|
||||
|
||||
|
||||
{-| Make a VBAT-context based chain.
|
||||
-}
|
||||
makeVBAT : (Int -> String) -> Credentials -> TaskChain VaultUpdate {} (VBAT { userId : () })
|
||||
makeVBAT toString cred =
|
||||
cred
|
||||
makeVBAT : (Int -> String) -> Snackbar a -> TaskChain VaultUpdate {} (VBAT { userId : () })
|
||||
makeVBAT toString snackbar =
|
||||
snackbar
|
||||
|> makeVBA
|
||||
|> Chain.andThen (withTransactionId toString)
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ resend other events or forward them elsewhere.
|
|||
|
||||
-}
|
||||
|
||||
import Internal.Api.Credentials exposing (Credentials)
|
||||
import Internal.Api.GetEvent.Main as GetEvent
|
||||
import Internal.Api.GetEvent.V1.SpecObjects as GetEventSO
|
||||
import Internal.Api.GetMessages.V4.SpecObjects as GetMessagesSO
|
||||
import Internal.Api.Snackbar as Snackbar exposing (Snackbar)
|
||||
import Internal.Api.Sync.V2.SpecObjects as SyncSO
|
||||
import Internal.Tools.Timestamp exposing (Timestamp)
|
||||
import Internal.Values.Event as Internal
|
||||
|
@ -19,22 +19,8 @@ import Json.Encode as E
|
|||
|
||||
{-| The central event type. This type will be used by the user and will be directly interacted with.
|
||||
-}
|
||||
type Event
|
||||
= Event
|
||||
{ event : Internal.IEvent
|
||||
, context : Credentials
|
||||
}
|
||||
|
||||
|
||||
{-| Using the credentials' background information and an internal event type,
|
||||
create an interactive event type.
|
||||
-}
|
||||
withCredentials : Credentials -> Internal.IEvent -> Event
|
||||
withCredentials context event =
|
||||
Event
|
||||
{ event = event
|
||||
, context = context
|
||||
}
|
||||
type alias Event =
|
||||
Snackbar Internal.IEvent
|
||||
|
||||
|
||||
{-| Create an internal event type from an API endpoint event object.
|
||||
|
@ -115,67 +101,58 @@ initFromClientEventWithoutRoomId rId output =
|
|||
}
|
||||
|
||||
|
||||
{-| Get the internal event type that is hidden in the interactive event type.
|
||||
-}
|
||||
withoutCredentials : Event -> Internal.IEvent
|
||||
withoutCredentials (Event { event }) =
|
||||
event
|
||||
|
||||
|
||||
|
||||
{- GETTER FUNCTIONS -}
|
||||
|
||||
|
||||
content : Event -> E.Value
|
||||
content =
|
||||
withoutCredentials >> Internal.content
|
||||
Snackbar.withoutCandy >> Internal.content
|
||||
|
||||
|
||||
eventId : Event -> String
|
||||
eventId =
|
||||
withoutCredentials >> Internal.eventId
|
||||
Snackbar.withoutCandy >> Internal.eventId
|
||||
|
||||
|
||||
originServerTs : Event -> Timestamp
|
||||
originServerTs =
|
||||
withoutCredentials >> Internal.originServerTs
|
||||
Snackbar.withoutCandy >> Internal.originServerTs
|
||||
|
||||
|
||||
roomId : Event -> String
|
||||
roomId =
|
||||
withoutCredentials >> Internal.roomId
|
||||
Snackbar.withoutCandy >> Internal.roomId
|
||||
|
||||
|
||||
sender : Event -> String
|
||||
sender =
|
||||
withoutCredentials >> Internal.sender
|
||||
Snackbar.withoutCandy >> Internal.sender
|
||||
|
||||
|
||||
stateKey : Event -> Maybe String
|
||||
stateKey =
|
||||
withoutCredentials >> Internal.stateKey
|
||||
Snackbar.withoutCandy >> Internal.stateKey
|
||||
|
||||
|
||||
eventType : Event -> String
|
||||
eventType =
|
||||
withoutCredentials >> Internal.eventType
|
||||
Snackbar.withoutCandy >> Internal.eventType
|
||||
|
||||
|
||||
age : Event -> Maybe Int
|
||||
age =
|
||||
withoutCredentials >> Internal.age
|
||||
Snackbar.withoutCandy >> Internal.age
|
||||
|
||||
|
||||
redactedBecause : Event -> Maybe Event
|
||||
redactedBecause (Event data) =
|
||||
data.event
|
||||
redactedBecause event =
|
||||
event
|
||||
|> Snackbar.withoutCandy
|
||||
|> Internal.redactedBecause
|
||||
|> Maybe.map
|
||||
(\event ->
|
||||
Event { data | event = event }
|
||||
)
|
||||
|> Maybe.map (Snackbar.withCandyFrom event)
|
||||
|
||||
|
||||
transactionId : Event -> Maybe String
|
||||
transactionId =
|
||||
withoutCredentials >> Internal.transactionId
|
||||
Snackbar.withoutCandy >> Internal.transactionId
|
||||
|
|
|
@ -3,7 +3,7 @@ module Internal.Invite exposing (..)
|
|||
{-| An invite is an Elm type that informs the user they've been invited to a room.
|
||||
-}
|
||||
|
||||
import Internal.Api.Credentials exposing (Credentials)
|
||||
import Internal.Api.Snackbar as Snackbar exposing (Snackbar)
|
||||
import Internal.Api.Sync.V2.SpecObjects exposing (StrippedStateEvent)
|
||||
import Internal.Api.Task as Api
|
||||
import Internal.Api.VaultUpdate exposing (VaultUpdate(..))
|
||||
|
@ -12,16 +12,32 @@ import Internal.Values.RoomInvite as Internal
|
|||
import Task exposing (Task)
|
||||
|
||||
|
||||
type RoomInvite
|
||||
= RoomInvite
|
||||
{ invite : Internal.IRoomInvite
|
||||
, context : Credentials
|
||||
type alias RoomInvite =
|
||||
Snackbar Internal.IRoomInvite
|
||||
|
||||
|
||||
accept : { invite : RoomInvite, reason : Maybe String } -> Task X.Error VaultUpdate
|
||||
accept { invite, reason } =
|
||||
Api.joinRoomById
|
||||
{ roomId = roomId invite
|
||||
, reason = reason
|
||||
}
|
||||
invite
|
||||
|
||||
|
||||
getRoomId : RoomInvite -> String
|
||||
getRoomId =
|
||||
withoutCredentials >> Internal.roomId
|
||||
roomId : RoomInvite -> String
|
||||
roomId =
|
||||
Snackbar.withoutCandy >> Internal.roomId
|
||||
|
||||
|
||||
getEvent : { eventType : String, stateKey : String } -> RoomInvite -> Maybe Internal.RoomInviteEvent
|
||||
getEvent data =
|
||||
Snackbar.withoutCandy >> Internal.getEvent data
|
||||
|
||||
|
||||
getAllEvents : RoomInvite -> List Internal.RoomInviteEvent
|
||||
getAllEvents =
|
||||
Snackbar.withoutCandy >> Internal.getAllEvents
|
||||
|
||||
|
||||
initFromStrippedStateEvent : { roomId : String, events : List StrippedStateEvent } -> Internal.IRoomInvite
|
||||
|
@ -29,47 +45,12 @@ initFromStrippedStateEvent =
|
|||
Internal.init
|
||||
|
||||
|
||||
withCredentials : Credentials -> Internal.IRoomInvite -> RoomInvite
|
||||
withCredentials context invite =
|
||||
RoomInvite { context = context, invite = invite }
|
||||
|
||||
|
||||
withoutCredentials : RoomInvite -> Internal.IRoomInvite
|
||||
withoutCredentials (RoomInvite { invite }) =
|
||||
invite
|
||||
|
||||
|
||||
getEvent : { eventType : String, stateKey : String } -> RoomInvite -> Maybe Internal.RoomInviteEvent
|
||||
getEvent data =
|
||||
withoutCredentials >> Internal.getEvent data
|
||||
|
||||
|
||||
getAllEvents : RoomInvite -> List Internal.RoomInviteEvent
|
||||
getAllEvents =
|
||||
withoutCredentials >> Internal.getAllEvents
|
||||
|
||||
|
||||
{-| Accept an invite and join the room.
|
||||
-}
|
||||
accept : { invite : RoomInvite, reason : Maybe String } -> Task X.Error VaultUpdate
|
||||
accept { invite, reason } =
|
||||
case invite of
|
||||
RoomInvite data ->
|
||||
Api.joinRoomById
|
||||
{ roomId = Internal.roomId data.invite
|
||||
, reason = reason
|
||||
}
|
||||
data.context
|
||||
|
||||
|
||||
{-| Reject the invite and do not join the room.
|
||||
-}
|
||||
reject : { invite : RoomInvite, reason : Maybe String } -> Task X.Error VaultUpdate
|
||||
reject { invite, reason } =
|
||||
case invite of
|
||||
RoomInvite data ->
|
||||
Api.leave
|
||||
{ roomId = Internal.roomId data.invite
|
||||
, reason = reason
|
||||
}
|
||||
data.context
|
||||
Api.leave
|
||||
{ roomId = roomId invite
|
||||
, reason = reason
|
||||
}
|
||||
invite
|
||||
|
|
|
@ -4,7 +4,7 @@ module Internal.Room exposing (..)
|
|||
-}
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Credentials exposing (Credentials)
|
||||
import Internal.Api.Snackbar as Snackbar exposing (Snackbar)
|
||||
import Internal.Api.Sync.V2.SpecObjects as Sync
|
||||
import Internal.Api.Task as Api
|
||||
import Internal.Api.VaultUpdate exposing (VaultUpdate(..))
|
||||
|
@ -28,11 +28,8 @@ The `Room` type contains utilities to inquire about the room and send messages
|
|||
to it.
|
||||
|
||||
-}
|
||||
type Room
|
||||
= Room
|
||||
{ room : Internal.IRoom
|
||||
, context : Credentials
|
||||
}
|
||||
type alias Room =
|
||||
Snackbar Internal.IRoom
|
||||
|
||||
|
||||
{-| Create a new object from a joined room.
|
||||
|
@ -89,24 +86,22 @@ initFromJoinedRoom data jroom =
|
|||
|
||||
accountData : String -> Room -> Maybe E.Value
|
||||
accountData key =
|
||||
withoutCredentials >> Internal.accountData key
|
||||
Snackbar.withoutCandy >> Internal.accountData key
|
||||
|
||||
|
||||
{-| Add account data to the room.
|
||||
-}
|
||||
addAccountData : String -> E.Value -> Room -> Room
|
||||
addAccountData eventType content (Room { room, context }) =
|
||||
room
|
||||
|> Internal.addAccountData eventType content
|
||||
|> withCredentials context
|
||||
addAccountData eventType content =
|
||||
Snackbar.map (Internal.addAccountData eventType content)
|
||||
|
||||
|
||||
{-| Adds an internal event to the `Room`. An internal event is a custom event
|
||||
that has been generated by the client.
|
||||
-}
|
||||
addInternalEvent : IEvent.IEvent -> Room -> Room
|
||||
addInternalEvent ievent (Room ({ room } as data)) =
|
||||
Room { data | room = Internal.addEvent ievent room }
|
||||
addInternalEvent ievent =
|
||||
Snackbar.map (Internal.addEvent ievent)
|
||||
|
||||
|
||||
{-| Adds an `Event` object to the `Room`. An `Event` is a value from the
|
||||
|
@ -114,39 +109,21 @@ addInternalEvent ievent (Room ({ room } as data)) =
|
|||
-}
|
||||
addEvent : Event -> Room -> Room
|
||||
addEvent =
|
||||
Event.withoutCredentials >> addInternalEvent
|
||||
|
||||
|
||||
{-| Creates a new `Room` object with the given parameters.
|
||||
-}
|
||||
withCredentials : Credentials -> Internal.IRoom -> Room
|
||||
withCredentials context room =
|
||||
Room
|
||||
{ context = context
|
||||
, room = room
|
||||
}
|
||||
|
||||
|
||||
{-| Retrieves the `Internal.IRoom` type contained within the given `Room`.
|
||||
-}
|
||||
withoutCredentials : Room -> Internal.IRoom
|
||||
withoutCredentials (Room { room }) =
|
||||
room
|
||||
Snackbar.withoutCandy >> addInternalEvent
|
||||
|
||||
|
||||
{-| Get a given state event.
|
||||
-}
|
||||
getStateEvent : { eventType : String, stateKey : String } -> Room -> Maybe Event
|
||||
getStateEvent data (Room { room, context }) =
|
||||
Internal.getStateEvent data room
|
||||
|> Maybe.map (Event.withCredentials context)
|
||||
getStateEvent data =
|
||||
Snackbar.mapMaybe (Internal.getStateEvent data)
|
||||
|
||||
|
||||
{-| Get older events from the Matrix API.
|
||||
-}
|
||||
getOlderEvents : { limit : Maybe Int } -> Room -> Task X.Error VaultUpdate
|
||||
getOlderEvents { limit } (Room { context, room }) =
|
||||
case Internal.latestGap room of
|
||||
findOlderEvents : { limit : Maybe Int } -> Room -> Task X.Error VaultUpdate
|
||||
findOlderEvents { limit } room =
|
||||
case Internal.latestGap (Snackbar.withoutCandy room) of
|
||||
Nothing ->
|
||||
Task.succeed (MultipleUpdates [])
|
||||
|
||||
|
@ -156,54 +133,52 @@ getOlderEvents { limit } (Room { context, room }) =
|
|||
, filter = Nothing
|
||||
, from = Just to
|
||||
, limit = limit
|
||||
, roomId = Internal.roomId room
|
||||
, roomId = roomId room
|
||||
, to = from
|
||||
}
|
||||
context
|
||||
room
|
||||
|
||||
|
||||
{-| Get the most recent events.
|
||||
-}
|
||||
mostRecentEvents : Room -> List Event
|
||||
mostRecentEvents (Room { context, room }) =
|
||||
room
|
||||
|> Internal.mostRecentEvents
|
||||
|> List.map (Event.withCredentials context)
|
||||
mostRecentEvents =
|
||||
Snackbar.mapList Internal.mostRecentEvents
|
||||
|
||||
|
||||
{-| Retrieves the ID of the Matrix room associated with the given `Room`.
|
||||
-}
|
||||
roomId : Room -> String
|
||||
roomId =
|
||||
withoutCredentials >> Internal.roomId
|
||||
Snackbar.withoutCandy >> Internal.roomId
|
||||
|
||||
|
||||
{-| Sends a new event to the Matrix room associated with the given `Room`.
|
||||
-}
|
||||
sendEvent : { content : E.Value, eventType : String, stateKey : Maybe String } -> Room -> Task X.Error VaultUpdate
|
||||
sendEvent { eventType, content, stateKey } (Room { context, room }) =
|
||||
sendEvent { eventType, content, stateKey } room =
|
||||
case stateKey of
|
||||
Nothing ->
|
||||
Api.sendMessageEvent
|
||||
{ content = content
|
||||
, eventType = eventType
|
||||
, extraTransactionNoise = "send-one-message"
|
||||
, roomId = Internal.roomId room
|
||||
, roomId = roomId room
|
||||
}
|
||||
context
|
||||
room
|
||||
|
||||
Just s ->
|
||||
Api.sendStateEvent
|
||||
{ content = content
|
||||
, eventType = eventType
|
||||
, stateKey = s
|
||||
, roomId = Internal.roomId room
|
||||
, roomId = roomId room
|
||||
}
|
||||
context
|
||||
room
|
||||
|
||||
|
||||
sendEvents : List { content : E.Value, eventType : String, stateKey : Maybe String } -> Room -> List (Task X.Error VaultUpdate)
|
||||
sendEvents events (Room { context, room }) =
|
||||
sendEvents events room =
|
||||
List.indexedMap Tuple.pair events
|
||||
|> List.map
|
||||
(\( i, { eventType, content, stateKey } ) ->
|
||||
|
@ -213,25 +188,25 @@ sendEvents events (Room { context, room }) =
|
|||
{ content = content
|
||||
, eventType = eventType
|
||||
, extraTransactionNoise = "send-message-" ++ String.fromInt i
|
||||
, roomId = Internal.roomId room
|
||||
, roomId = roomId room
|
||||
}
|
||||
context
|
||||
room
|
||||
|
||||
Just s ->
|
||||
Api.sendStateEvent
|
||||
{ content = content
|
||||
, eventType = eventType
|
||||
, stateKey = s
|
||||
, roomId = Internal.roomId room
|
||||
, roomId = roomId room
|
||||
}
|
||||
context
|
||||
room
|
||||
)
|
||||
|
||||
|
||||
{-| Sends a new text message to the Matrix room associated with the given `Room`.
|
||||
-}
|
||||
sendMessage : String -> Room -> Task X.Error VaultUpdate
|
||||
sendMessage text (Room { context, room }) =
|
||||
sendMessage text room =
|
||||
Api.sendMessageEvent
|
||||
{ content =
|
||||
E.object
|
||||
|
@ -240,13 +215,13 @@ sendMessage text (Room { context, room }) =
|
|||
]
|
||||
, eventType = "m.room.message"
|
||||
, extraTransactionNoise = "literal-message:" ++ text
|
||||
, roomId = Internal.roomId room
|
||||
, roomId = roomId room
|
||||
}
|
||||
context
|
||||
room
|
||||
|
||||
|
||||
sendMessages : List String -> Room -> List (Task X.Error VaultUpdate)
|
||||
sendMessages pieces (Room { context, room }) =
|
||||
sendMessages pieces room =
|
||||
pieces
|
||||
|> List.indexedMap Tuple.pair
|
||||
|> List.map
|
||||
|
@ -259,21 +234,21 @@ sendMessages pieces (Room { context, room }) =
|
|||
]
|
||||
, eventType = "m.room.message"
|
||||
, extraTransactionNoise = "literal-message-" ++ String.fromInt i ++ ":" ++ piece
|
||||
, roomId = Internal.roomId room
|
||||
, roomId = roomId room
|
||||
}
|
||||
context
|
||||
room
|
||||
)
|
||||
|
||||
|
||||
{-| Leave this room.
|
||||
-}
|
||||
leave : Room -> Task X.Error VaultUpdate
|
||||
leave ((Room { context }) as r) =
|
||||
Api.leave { roomId = roomId r, reason = Nothing } context
|
||||
leave room =
|
||||
Api.leave { roomId = roomId room, reason = Nothing } room
|
||||
|
||||
|
||||
{-| Set account data.
|
||||
-}
|
||||
setAccountData : String -> E.Value -> Room -> Task X.Error VaultUpdate
|
||||
setAccountData key value ((Room { context }) as r) =
|
||||
Api.setAccountData { content = value, eventType = key, roomId = Just (roomId r) } context
|
||||
setAccountData key value room =
|
||||
Api.setAccountData { content = value, eventType = key, roomId = Just (roomId room) } room
|
||||
|
|
|
@ -8,7 +8,7 @@ This file combines the internal functions with the API endpoints to create a ful
|
|||
-}
|
||||
|
||||
import Dict
|
||||
import Internal.Api.Credentials as Credentials exposing (Credentials)
|
||||
import Internal.Api.Snackbar as Snackbar exposing (Snackbar)
|
||||
import Internal.Api.Sync.Main exposing (SyncInput)
|
||||
import Internal.Api.Task as Api
|
||||
import Internal.Api.VaultUpdate exposing (VaultUpdate(..))
|
||||
|
@ -30,11 +30,15 @@ and Elm will figure out which key to use.
|
|||
If you pass the `Vault` into any function, then the library will look for
|
||||
the right keys and tokens to get the right information.
|
||||
-}
|
||||
type Vault
|
||||
= Vault
|
||||
{ cred : Internal.IVault
|
||||
, context : Credentials
|
||||
}
|
||||
type alias Vault =
|
||||
Snackbar Internal.IVault
|
||||
|
||||
|
||||
{-| Get personal account data linked to an account.
|
||||
-}
|
||||
accountData : String -> Vault -> Maybe E.Value
|
||||
accountData key =
|
||||
Snackbar.withoutCandy >> Internal.accountData key
|
||||
|
||||
|
||||
{-| Get a Vault type based on an unknown access token.
|
||||
|
@ -45,77 +49,66 @@ when the access token expires, is revoked or something else happens.
|
|||
-}
|
||||
fromAccessToken : { baseUrl : String, accessToken : String } -> Vault
|
||||
fromAccessToken { baseUrl, accessToken } =
|
||||
Credentials.fromBaseUrl baseUrl
|
||||
|> Credentials.addToken accessToken
|
||||
|> (\context ->
|
||||
{ cred = Internal.init, context = context }
|
||||
)
|
||||
|> Vault
|
||||
Snackbar.init
|
||||
{ baseUrl = baseUrl
|
||||
, content = Internal.init
|
||||
}
|
||||
|> Snackbar.addToken accessToken
|
||||
|
||||
|
||||
{-| Get a Vault type using a username and password.
|
||||
-}
|
||||
fromLoginVault : { username : String, password : String, baseUrl : String } -> Vault
|
||||
fromLoginVault { username, password, baseUrl } =
|
||||
Credentials.fromBaseUrl baseUrl
|
||||
|> Credentials.addUsernameAndPassword
|
||||
Snackbar.init
|
||||
{ baseUrl = baseUrl
|
||||
, content = Internal.init
|
||||
}
|
||||
|> Snackbar.addUsernameAndPassword
|
||||
{ username = username
|
||||
, password = password
|
||||
}
|
||||
|> (\context ->
|
||||
{ cred = Internal.init, context = context }
|
||||
)
|
||||
|> Vault
|
||||
|
||||
|
||||
{-| Get personal account data linked to an account.
|
||||
-}
|
||||
accountData : String -> Vault -> Maybe E.Value
|
||||
accountData key (Vault { cred }) =
|
||||
Internal.accountData key cred
|
||||
|
||||
|
||||
{-| Get a user's invited rooms.
|
||||
-}
|
||||
getInvites : Vault -> List Invite.RoomInvite
|
||||
getInvites (Vault { cred, context }) =
|
||||
Internal.getInvites cred
|
||||
|> List.map (Invite.withCredentials context)
|
||||
invites : Vault -> List Invite.RoomInvite
|
||||
invites =
|
||||
Snackbar.mapList Internal.getInvites
|
||||
|
||||
|
||||
{-| Get a room based on its id.
|
||||
-}
|
||||
getRoomById : String -> Vault -> Maybe Room.Room
|
||||
getRoomById roomId (Vault { cred, context }) =
|
||||
Internal.getRoomById roomId cred
|
||||
|> Maybe.map (Room.withCredentials context)
|
||||
getRoomById roomId =
|
||||
Snackbar.mapMaybe (Internal.getRoomById roomId)
|
||||
|
||||
|
||||
{-| Insert an internal room type into the credentials.
|
||||
{-| Insert an internal room type into the vault.
|
||||
-}
|
||||
insertInternalRoom : IRoom.IRoom -> Vault -> Vault
|
||||
insertInternalRoom iroom (Vault data) =
|
||||
Vault { data | cred = Internal.insertRoom iroom data.cred }
|
||||
insertInternalRoom iroom =
|
||||
Snackbar.map (Internal.insertRoom iroom)
|
||||
|
||||
|
||||
{-| Internal a full room type into the credentials.
|
||||
{-| Internal a full room type into the vault.
|
||||
-}
|
||||
insertRoom : Room.Room -> Vault -> Vault
|
||||
insertRoom =
|
||||
Room.withoutCredentials >> insertInternalRoom
|
||||
Snackbar.withoutCandy >> insertInternalRoom
|
||||
|
||||
|
||||
{-| Join a Matrix room by its id.
|
||||
-}
|
||||
joinRoomById : String -> Vault -> Task X.Error VaultUpdate
|
||||
joinRoomById roomId (Vault { context }) =
|
||||
Api.joinRoomById { roomId = roomId, reason = Nothing } context
|
||||
joinRoomById roomId vault =
|
||||
Api.joinRoomById { roomId = roomId, reason = Nothing } vault
|
||||
|
||||
|
||||
{-| Update the Vault type with new values
|
||||
-}
|
||||
updateWith : VaultUpdate -> Vault -> Vault
|
||||
updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
||||
updateWith vaultUpdate vault =
|
||||
case vaultUpdate of
|
||||
MultipleUpdates updates ->
|
||||
List.foldl updateWith vault updates
|
||||
|
@ -143,7 +136,7 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
|||
vault
|
||||
|
||||
CurrentTimestamp t ->
|
||||
Vault { cred = Internal.insertTimestamp t cred, context = context }
|
||||
Snackbar.map (Internal.insertTimestamp t) vault
|
||||
|
||||
GetEvent input output ->
|
||||
case getRoomById input.roomId vault of
|
||||
|
@ -192,7 +185,7 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
|||
case ( getRoomById input.roomId vault, nextBatch ) of
|
||||
( Just room, Just nb ) ->
|
||||
room
|
||||
|> Room.withoutCredentials
|
||||
|> Snackbar.withoutCandy
|
||||
|> IRoom.insertEvents
|
||||
{ events =
|
||||
output.chunk
|
||||
|
@ -210,8 +203,8 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
|||
, stateDelta = Just <| StateManager.fromEventList (List.map Event.initFromGetMessages output.state)
|
||||
}
|
||||
|> Internal.insertRoom
|
||||
|> (|>) cred
|
||||
|> (\v -> Vault { cred = v, context = context })
|
||||
|> Snackbar.map
|
||||
|> (|>) vault
|
||||
|
||||
_ ->
|
||||
vault
|
||||
|
@ -226,35 +219,29 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
|||
|
||||
-- TODO
|
||||
JoinedRoom input _ ->
|
||||
cred
|
||||
|> Internal.removeInvite input.roomId
|
||||
|> (\x -> { cred = x, context = context })
|
||||
|> Vault
|
||||
Snackbar.map (Internal.removeInvite input.roomId) vault
|
||||
|
||||
-- TODO
|
||||
LeftRoom input () ->
|
||||
cred
|
||||
|> Internal.removeInvite input.roomId
|
||||
|> (\x -> { cred = x, context = context })
|
||||
|> Vault
|
||||
Snackbar.map (Internal.removeInvite input.roomId) vault
|
||||
|
||||
MessageEventSent { content, eventType, roomId } { eventId } ->
|
||||
Maybe.map2
|
||||
(\room sender ->
|
||||
room
|
||||
|> Room.withoutCredentials
|
||||
|> Snackbar.withoutCandy
|
||||
|> IRoom.addTemporaryEvent
|
||||
{ content = content
|
||||
, eventType = eventType
|
||||
, eventId = eventId
|
||||
, originServerTs = Internal.lastUpdate cred
|
||||
, originServerTs = Internal.lastUpdate (Snackbar.withoutCandy vault)
|
||||
, sender = sender
|
||||
, stateKey = Nothing
|
||||
}
|
||||
)
|
||||
(getRoomById roomId vault)
|
||||
(getUsername vault)
|
||||
|> Maybe.map (Room.withCredentials context >> insertRoom >> (|>) vault)
|
||||
|> Maybe.map (Snackbar.withCandyFrom vault >> insertRoom >> (|>) vault)
|
||||
|> Maybe.withDefault vault
|
||||
|
||||
-- TODO
|
||||
|
@ -265,19 +252,19 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
|||
Maybe.map2
|
||||
(\room sender ->
|
||||
room
|
||||
|> Room.withoutCredentials
|
||||
|> Snackbar.withoutCandy
|
||||
|> IRoom.addTemporaryEvent
|
||||
{ content = content
|
||||
, eventType = eventType
|
||||
, eventId = eventId
|
||||
, originServerTs = Internal.lastUpdate cred
|
||||
, originServerTs = Internal.lastUpdate (Snackbar.withoutCandy vault)
|
||||
, sender = sender
|
||||
, stateKey = Just stateKey
|
||||
}
|
||||
)
|
||||
(getRoomById roomId vault)
|
||||
(getUsername vault)
|
||||
|> Maybe.map (Room.withCredentials context >> insertRoom >> (|>) vault)
|
||||
|> Maybe.map (Snackbar.withCandyFrom vault >> insertRoom >> (|>) vault)
|
||||
|> Maybe.withDefault vault
|
||||
|
||||
SyncUpdate input output ->
|
||||
|
@ -303,7 +290,7 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
|||
(case jroom.timeline of
|
||||
Just timeline ->
|
||||
room
|
||||
|> Room.withoutCredentials
|
||||
|> Snackbar.withoutCandy
|
||||
|> IRoom.addEvents
|
||||
{ events =
|
||||
List.map
|
||||
|
@ -325,7 +312,7 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
|||
}
|
||||
|
||||
Nothing ->
|
||||
Room.withoutCredentials room
|
||||
Snackbar.withoutCandy room
|
||||
)
|
||||
|> (\r ->
|
||||
jroom.accountData
|
||||
|
@ -342,8 +329,8 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
|||
|> Room.initFromJoinedRoom { nextBatch = output.nextBatch, roomId = roomId }
|
||||
)
|
||||
|
||||
invites : List IRoomInvite
|
||||
invites =
|
||||
inviteList : List IRoomInvite
|
||||
inviteList =
|
||||
output.rooms
|
||||
|> Maybe.map .invite
|
||||
|> Maybe.withDefault Dict.empty
|
||||
|
@ -354,61 +341,62 @@ updateWith vaultUpdate ((Vault ({ cred, context } as data)) as vault) =
|
|||
|> List.map (\( roomId, events ) -> { roomId = roomId, events = events })
|
||||
|> List.map Invite.initFromStrippedStateEvent
|
||||
in
|
||||
cred
|
||||
-- Add global account data
|
||||
|> (\c -> List.foldl Internal.insertAccountData c accData)
|
||||
-- Add new since token
|
||||
|> Internal.addSince output.nextBatch
|
||||
-- Add joined rooms
|
||||
|> List.foldl Internal.insertRoom
|
||||
|> (|>) jRooms
|
||||
-- Add invites
|
||||
|> List.foldl Internal.addInvite
|
||||
|> (|>) invites
|
||||
|> (\x -> { cred = x, context = context })
|
||||
|> Vault
|
||||
Snackbar.map
|
||||
(\ivault ->
|
||||
ivault
|
||||
-- Add global account data
|
||||
|> (\c -> List.foldl Internal.insertAccountData c accData)
|
||||
-- Add new since token
|
||||
|> Internal.addSince output.nextBatch
|
||||
-- Add joined rooms
|
||||
|> List.foldl Internal.insertRoom
|
||||
|> (|>) jRooms
|
||||
-- Add invites
|
||||
|> List.foldl Internal.addInvite
|
||||
|> (|>) inviteList
|
||||
)
|
||||
vault
|
||||
|
||||
UpdateAccessToken token ->
|
||||
Vault { data | context = Credentials.addToken token context }
|
||||
Snackbar.addToken token vault
|
||||
|
||||
UpdateVersions versions ->
|
||||
Vault { data | context = Credentials.addVersions versions context }
|
||||
Snackbar.addVersions versions vault
|
||||
|
||||
UpdateWhoAmI whoami ->
|
||||
Vault { data | context = Credentials.addWhoAmI whoami context }
|
||||
Snackbar.addWhoAmI whoami vault
|
||||
|
||||
-- TODO: Save ALL info
|
||||
LoggedInWithUsernameAndPassword _ output ->
|
||||
Vault { data | context = Credentials.addToken output.accessToken context }
|
||||
Snackbar.addToken output.accessToken vault
|
||||
|
||||
|
||||
getUsername : Vault -> Maybe String
|
||||
getUsername (Vault { context }) =
|
||||
Credentials.getUserId context
|
||||
getUsername =
|
||||
Snackbar.userId
|
||||
|
||||
|
||||
{-| Set personal account data
|
||||
-}
|
||||
setAccountData : String -> E.Value -> Vault -> Task X.Error VaultUpdate
|
||||
setAccountData key value (Vault { context }) =
|
||||
Api.setAccountData { content = value, eventType = key, roomId = Nothing } context
|
||||
setAccountData key value vault =
|
||||
Api.setAccountData { content = value, eventType = key, roomId = Nothing } vault
|
||||
|
||||
|
||||
{-| Synchronize vault
|
||||
-}
|
||||
sync : Vault -> Task X.Error VaultUpdate
|
||||
sync (Vault { cred, context }) =
|
||||
sync vault =
|
||||
let
|
||||
syncInput : SyncInput
|
||||
syncInput =
|
||||
{ filter = Nothing
|
||||
, fullState = Nothing
|
||||
, setPresence = Nothing
|
||||
, since = Internal.getSince cred
|
||||
, since = Internal.getSince (Snackbar.withoutCandy vault)
|
||||
, timeout = Just 30
|
||||
}
|
||||
in
|
||||
Api.sync syncInput context
|
||||
Api.sync syncInput vault
|
||||
-- TODO: The sync function is described as "updating all the tokens".
|
||||
-- TODO: For this reason, (only) the sync function should handle errors
|
||||
-- TODO: that indicate that the user's access tokens have expired.
|
||||
|
@ -428,10 +416,10 @@ sync (Vault { cred, context }) =
|
|||
-- TODO: The login should be different when soft_logout.
|
||||
-- TODO: Add support for refresh token.
|
||||
X.ServerException (X.M_UNKNOWN_TOKEN _) ->
|
||||
Api.loginMaybeSync syncInput context
|
||||
Api.loginMaybeSync syncInput vault
|
||||
|
||||
X.ServerException (X.M_MISSING_TOKEN _) ->
|
||||
Api.loginMaybeSync syncInput context
|
||||
Api.loginMaybeSync syncInput vault
|
||||
|
||||
X.ServerException _ ->
|
||||
Task.fail err
|
||||
|
@ -441,7 +429,5 @@ sync (Vault { cred, context }) =
|
|||
{-| Get a list of all synchronised rooms.
|
||||
-}
|
||||
rooms : Vault -> List Room.Room
|
||||
rooms (Vault { cred, context }) =
|
||||
cred
|
||||
|> Internal.getRooms
|
||||
|> List.map (Room.withCredentials context)
|
||||
rooms =
|
||||
Snackbar.mapList Internal.getRooms
|
||||
|
|
|
@ -119,7 +119,7 @@ getRoomById =
|
|||
-}
|
||||
getInvites : Vault -> List RoomInvite
|
||||
getInvites =
|
||||
Internal.Vault.getInvites
|
||||
Internal.Vault.invites
|
||||
|
||||
|
||||
{-| Account data is personal information that the homeserver will remember for you.
|
||||
|
|
|
@ -107,7 +107,7 @@ this inserts more events at the start of the `[mostRecentEvents](#mostRecentEven
|
|||
-}
|
||||
findOlderEvents : { limit : Maybe Int, room : Room } -> Task X.Error VaultUpdate
|
||||
findOlderEvents { limit, room } =
|
||||
Internal.getOlderEvents { limit = limit } room
|
||||
Internal.findOlderEvents { limit = limit } room
|
||||
|
||||
|
||||
{-| This function will always display the most recent events from the Matrix room.
|
||||
|
|
|
@ -76,7 +76,7 @@ rejectWithReason reason invite =
|
|||
-}
|
||||
roomId : RoomInvite -> String
|
||||
roomId =
|
||||
Internal.getRoomId
|
||||
Internal.roomId
|
||||
|
||||
|
||||
{-| The `RoomInviteEvent` type represents a stripped event that your user can see while they haven't joined the group yet.
|
||||
|
@ -117,13 +117,15 @@ stateKey =
|
|||
IR.stateKey
|
||||
|
||||
|
||||
{-| Get a specific event with a specific event content type and state key, if it exists.
|
||||
-}
|
||||
getEvent : { eventType : String, stateKey : String } -> RoomInvite -> Maybe RoomInviteEvent
|
||||
getEvent data invite =
|
||||
invite
|
||||
|> Internal.withoutCredentials
|
||||
|> IR.getEvent data
|
||||
|
||||
-- -- TODO: Fix this
|
||||
-- {-| Get a specific event with a specific event content type and state key, if it exists.
|
||||
-- -}
|
||||
-- getEvent : { eventType : String, stateKey : String } -> RoomInvite -> Maybe RoomInviteEvent
|
||||
-- getEvent data invite =
|
||||
-- invite
|
||||
-- |> Internal.withoutCredentials
|
||||
-- |> IR.getEvent data
|
||||
|
||||
|
||||
{-| Instead of looking at just one event, get all events in a list.
|
||||
|
|
Loading…
Reference in New Issue