Add exposed Room type

pull/1/head
Bram van den Heuvel 2023-03-15 19:39:48 +01:00
parent c9cace695f
commit d03aea1f3f
3 changed files with 194 additions and 12 deletions

View File

@ -136,21 +136,58 @@ roomId =
{-| Sends a new event to the Matrix room associated with the given `Room`. {-| Sends a new event to the Matrix room associated with the given `Room`.
-} -}
sendEvent : Room -> { eventType : String, content : E.Value } -> Task X.Error VaultUpdate sendEvent : { content : E.Value, eventType : String, stateKey : Maybe String } -> Room -> Task X.Error VaultUpdate
sendEvent (Room { context, room }) { eventType, content } = sendEvent { eventType, content, stateKey } (Room { context, room }) =
case stateKey of
Nothing ->
Api.sendMessageEvent Api.sendMessageEvent
{ content = content { content = content
, eventType = eventType , eventType = eventType
, extraTransactionNoise = "content-value:<object>" , extraTransactionNoise = "send-one-message"
, roomId = Internal.roomId room
}
context
Just s ->
Api.sendStateEvent
{ content = content
, eventType = eventType
, stateKey = s
, roomId = Internal.roomId room , roomId = Internal.roomId room
} }
context context
sendEvents : List { content : E.Value, eventType : String, stateKey : Maybe String } -> Room -> List (Task X.Error VaultUpdate)
sendEvents events (Room { context, room }) =
List.indexedMap Tuple.pair events
|> List.map
(\( i, { eventType, content, stateKey } ) ->
case stateKey of
Nothing ->
Api.sendMessageEvent
{ content = content
, eventType = eventType
, extraTransactionNoise = "send-message-" ++ String.fromInt i
, roomId = Internal.roomId room
}
context
Just s ->
Api.sendStateEvent
{ content = content
, eventType = eventType
, stateKey = s
, roomId = Internal.roomId room
}
context
)
{-| Sends a new text message to the Matrix room associated with the given `Room`. {-| Sends a new text message to the Matrix room associated with the given `Room`.
-} -}
sendMessage : Room -> String -> Task X.Error VaultUpdate sendMessage : String -> Room -> Task X.Error VaultUpdate
sendMessage (Room { context, room }) text = sendMessage text (Room { context, room }) =
Api.sendMessageEvent Api.sendMessageEvent
{ content = { content =
E.object E.object
@ -162,3 +199,30 @@ sendMessage (Room { context, room }) text =
, roomId = Internal.roomId room , roomId = Internal.roomId room
} }
context context
sendMessages : List String -> Room -> List (Task X.Error VaultUpdate)
sendMessages pieces (Room { context, room }) =
pieces
|> List.indexedMap Tuple.pair
|> List.map
(\( i, piece ) ->
Api.sendMessageEvent
{ content =
E.object
[ ( "msgtype", E.string "m.text" )
, ( "body", E.string piece )
]
, eventType = "m.room.message"
, extraTransactionNoise = "literal-message-" ++ String.fromInt i ++ ":" ++ piece
, roomId = Internal.roomId room
}
context
)
{-| Leave this room.
-}
leave : Room -> Task X.Error VaultUpdate
leave ((Room { context }) as r) =
Api.leave { roomId = roomId r, reason = Nothing } context

119
src/Matrix/Room.elm Normal file
View File

@ -0,0 +1,119 @@
module Matrix.Room exposing (..)
{-| -}
import Internal.Api.VaultUpdate exposing (VaultUpdate)
import Internal.Event as Event
import Internal.Room as Internal
import Internal.Tools.Exceptions as X
import Json.Encode as E
import Task exposing (Task)
{-| The `Room` type represents a Matrix Room that the user has joined.
It contains context information that allows the retrieval of new information from
the Matrix API if necessary.
-}
type alias Room =
Internal.Room
{-| Get the most recent events from this room.
-}
mostRecentEvents : Room -> List Event.Event
mostRecentEvents =
Internal.mostRecentEvents
{-| Get the Matrix room id of a room.
-}
roomId : Room -> String
roomId =
Internal.roomId
{-| Send an unformatted text message to a room.
task =
room
|> sendMessage "Hello, world!"
|> Task.attempt toMsg
**Hint:** are you trying to send multiple messages at the same time? You might want to use `sendMessages` instead.
-}
sendMessage : String -> Room -> Task X.Error VaultUpdate
sendMessage =
Internal.sendMessage
{-| Send multiple unformatted text messages to a room.
**Why this function?** If you send the same message too quickly again, the Matrix API might get confused and think it's the same message.
This way, you will lose messages!
If you're intending to send the same message multiple times, this function will emphasize that these messages are not the same.
-- SAFE
Task.sequence [ sendMessage "Hello, world!", sendMessage "hi mom!" ]
-- NOT SAFE
Task.sequence [ sendMessage "Hello, world!", sendMessage "Hello world!" ]
-- SAFE
Task.sequence <| sendMessages [ "Hello, world!", "hi mom!" ]
Task.sequence <| sendMessages [ "Hello, world!", "Hello, world!" ]
-}
sendMessages : List String -> Room -> List (Task X.Error VaultUpdate)
sendMessages =
Internal.sendMessages
{-| Send a custom event to the Matrix room.
Keep in mind that this function is not safe to use if you're sending exactly the same messages multiple times:
-- SAFE
Task.sequence
[ sendOneEvent { content = E.object [], eventType = "com.example.foo", stateKey = Nothing } room
, sendOneEvent { content = E.int 0, eventType = "com.example.foo", stateKey = Nothing } room
]
-- NOT SAFE
Task.sequence
[ sendOneEvent { content = E.object [], eventType = "com.example.foo", stateKey = Nothing } room
, sendOneEvent { content = E.object [], eventType = "com.example.foo", stateKey = Nothing } room
]
-}
sendOneEvent : { content : E.Value, eventType : String, stateKey : Maybe String } -> Room -> Task X.Error VaultUpdate
sendOneEvent =
Internal.sendEvent
{-| Send multiple events to the same room.
If you send the same event twice to the same room too close together, the Matrix API will sometimes think that it's the same event.
This function ensures that every messages is treated separately.
Keep in mind that this function doesn't send the events in order, it just makes them safe to send at the same time.
-- NOT SAFE
[ sendOneEvent { content = E.object [], eventType = "com.example.foo", stateKey = Nothing } room
, sendOneEvent { content = E.object [], eventType = "com.example.foo", stateKey = Nothing } room
]
|> Task.sequence
-- SAFE
[ { content = E.object [], eventType = "com.example.foo", stateKey = Nothing } room
, { content = E.object [], eventType = "com.example.foo", stateKey = Nothing } room
]
|> sendMultipleEvents
|> Task.sequence
-}
sendMultipleEvents : List { content : E.Value, eventType : String, stateKey : Maybe String } -> Room -> List (Task X.Error VaultUpdate)
sendMultipleEvents =
Internal.sendEvents

View File

@ -22,7 +22,6 @@ want to see.
import Internal.Api.VaultUpdate exposing (VaultUpdate) import Internal.Api.VaultUpdate exposing (VaultUpdate)
import Internal.Invite as Internal import Internal.Invite as Internal
import Internal.Room exposing (Room)
import Internal.Tools.Exceptions as X import Internal.Tools.Exceptions as X
import Internal.Values.RoomInvite as IR import Internal.Values.RoomInvite as IR
import Json.Encode as E import Json.Encode as E