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:" } {-| 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 }