elm-matrix-sdk-alpha/src/Internal/Room.elm

179 lines
5.8 KiB
Elm

module Internal.Room exposing (..)
{-| The `Room` type represents a Matrix Room. In here, you will find utilities to ask information about a room.
-}
import Dict
import Internal.Api.All as Api
import Internal.Api.PreApi.Objects.Versions as V
import Internal.Api.Sync.V2.SpecObjects as Sync
import Internal.Event as Event exposing (Event)
import Internal.Tools.Exceptions as X
import Internal.Tools.Hashdict as Hashdict
import Internal.Tools.LoginValues exposing (AccessToken)
import Internal.Values.Event as IEvent
import Internal.Values.Room as Internal
import Internal.Values.StateManager as StateManager
import Internal.Values.Timeline as Timeline
import Json.Encode as E
import Task exposing (Task)
{-| The `Room` type represents a Matrix Room. It contains context information
such as the `accessToken` that allows the retrieval of new information from
the Matrix API if necessary.
The `Room` type contains utilities to inquire about the room and send messages
to it.
-}
type Room
= Room
{ room : Internal.Room
, accessToken : AccessToken
, baseUrl : String
, versions : Maybe V.Versions
}
{-| Create a new object from a joined room.
-}
initFromJoinedRoom : { roomId : String, nextBatch : String } -> Sync.JoinedRoom -> Internal.Room
initFromJoinedRoom data jroom =
Internal.Room
{ accountData =
jroom.accountData
|> Maybe.map .events
|> Maybe.withDefault []
|> List.map (\{ contentType, content } -> ( contentType, content ))
|> Dict.fromList
, ephemeral =
jroom.ephemeral
|> Maybe.map .events
|> Maybe.withDefault []
|> List.map IEvent.BlindEvent
, events =
jroom.timeline
|> Maybe.map .events
|> Maybe.withDefault []
|> List.map (Event.initFromClientEventWithoutRoomId data.roomId)
|> Hashdict.fromList IEvent.eventId
, roomId = data.roomId
, timeline =
jroom.timeline
|> Maybe.map
(\timeline ->
Timeline.newFromEvents
{ events = List.map (Event.initFromClientEventWithoutRoomId data.roomId) timeline.events
, nextBatch = data.nextBatch
, prevBatch = timeline.prevBatch
, stateDelta =
jroom.state
|> Maybe.map
(.events
>> List.map (Event.initFromClientEventWithoutRoomId data.roomId)
>> StateManager.fromEventList
)
}
)
|> Maybe.withDefault
(Timeline.newFromEvents
{ events = []
, nextBatch = data.nextBatch
, prevBatch = Nothing
, stateDelta = Nothing
}
)
}
{-| Adds an internal event to the `Room`. An internal event is a custom event
that has been generated by the client.
-}
addInternalEvent : IEvent.Event -> Room -> Room
addInternalEvent ievent (Room ({ room } as data)) =
Room { data | room = Internal.addEvent ievent room }
{-| Adds an `Event` object to the `Room`. An `Event` is a value from the
`Internal.Event` module that is used to represent an event in a Matrix room.
-}
addEvent : Event -> Room -> Room
addEvent =
Event.internalValue >> 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 =
Room
{ accessToken = accessToken
, baseUrl = baseUrl
, room = room
, versions = versions
}
{-| Retrieves the `Internal.Room` type contained within the given `Room`.
-}
internalValue : Room -> Internal.Room
internalValue (Room { room }) =
room
{-| Get the most recent events.
-}
mostRecentEvents : Room -> List Event
mostRecentEvents (Room data) =
data.room
|> Internal.mostRecentEvents
|> List.map
(Event.init
{ accessToken = data.accessToken
, baseUrl = data.baseUrl
, versions = data.versions
}
)
{-| Retrieves the ID of the Matrix room associated with the given `Room`.
-}
roomId : Room -> String
roomId =
internalValue >> 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 } =
Api.sendMessageEvent
{ accessToken = accessToken
, baseUrl = baseUrl
, content = content
, eventType = eventType
, roomId = Internal.roomId room
, versions = versions
, extraTransactionNoise = "content-value:<object>"
}
{-| 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 =
Api.sendMessageEvent
{ accessToken = accessToken
, baseUrl = baseUrl
, content =
E.object
[ ( "msgtype", E.string "m.text" )
, ( "body", E.string text )
]
, eventType = "m.room.message"
, roomId = Internal.roomId room
, versions = versions
, extraTransactionNoise = "literal-message:" ++ text
}