179 lines
5.8 KiB
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
|
|
}
|