Add first exposed modules

pull/1/head
Bram van den Heuvel 2023-03-15 15:32:02 +01:00
parent 1d90d300da
commit c9cace695f
3 changed files with 270 additions and 4 deletions

View File

@ -6,11 +6,13 @@ It handles all communication with the homeserver.
import Internal.Tools.Hashdict as Hashdict exposing (Hashdict) import Internal.Tools.Hashdict as Hashdict exposing (Hashdict)
import Internal.Values.Room as Room exposing (IRoom) import Internal.Values.Room as Room exposing (IRoom)
import Internal.Values.RoomInvite as Invite exposing (IRoomInvite)
type IVault type IVault
= IVault = IVault
{ rooms : Hashdict IRoom { invites : List IRoomInvite
, rooms : Hashdict IRoom
, since : Maybe String , since : Maybe String
} }
@ -22,6 +24,20 @@ addSince since (IVault data) =
IVault { data | since = Just since } IVault { data | since = Just since }
{-| Add a new invite.
-}
addInvite : IRoomInvite -> IVault -> IVault
addInvite invite (IVault data) =
IVault { data | invites = List.append data.invites [ invite ] }
{-| Get all the invited rooms of a user.
-}
getInvites : IVault -> List IRoomInvite
getInvites (IVault data) =
data.invites
{-| Get a room from the Credentials type by the room's id. {-| Get a room from the Credentials type by the room's id.
-} -}
getRoomById : String -> IVault -> Maybe IRoom getRoomById : String -> IVault -> Maybe IRoom
@ -48,7 +64,8 @@ getSince (IVault { since }) =
init : IVault init : IVault
init = init =
IVault IVault
{ rooms = Hashdict.empty Room.roomId { invites = []
, rooms = Hashdict.empty Room.roomId
, since = Nothing , since = Nothing
} }
@ -59,6 +76,13 @@ This function can hence also be used as an update function for rooms.
-} -}
insertRoom : IRoom -> IVault -> IVault insertRoom : IRoom -> IVault -> IVault
insertRoom room (IVault cred) = insertRoom room (IVault data) =
IVault IVault
{ cred | rooms = Hashdict.insert room cred.rooms } { data | rooms = Hashdict.insert room data.rooms }
{-| Remove an invite. This is usually done when the invite has been accepted or rejected.
-}
removeInvite : String -> IVault -> IVault
removeInvite roomId (IVault data) =
IVault { data | invites = List.filter (\i -> Invite.roomId i /= roomId) data.invites }

118
src/Matrix.elm Normal file
View File

@ -0,0 +1,118 @@
module Matrix exposing (..)
{-| This is the main module of the SDK. Here, you will find basic functions to
interact with the API.
# Create a new Vault
@docs Vault, fromLoginCredentials, fromAccessToken
# Keeping your Vault up-to-date
@docs sync, VaultUpdate, updateWith
# Exploring your vault
@docs getRooms, getRoomById, accessToken
-}
import Internal.Api.VaultUpdate as Api
import Internal.Invite exposing (RoomInvite)
import Internal.Room exposing (Room)
import Internal.Tools.Exceptions as X
import Internal.Vault
import Task exposing (Task)
{-| The Matrix API requires you to keep track of a lot of tokens, keys, values and more.
Luckily, you don't need to!
You can view the `Vault` as a large box of keys that will help you get
the information that you need. The type also caches information that it receives
from the API, so you can also ask it for information that it has seen before.
-}
type alias Vault =
Internal.Vault.Vault
{-| The `VaultUpdate` is a type that helps you keep your `Vault` type up-to-date.
Sometimes, the API will tell you to change certain tokens, and this SDK will
translate those instructions to a `VaultUpdate` that you can feed to your `Vault`.
-}
type alias VaultUpdate =
Api.VaultUpdate
{-| Create a new vault based on an access token.
Keep in mind that access tokens might eventually be revoked or expire,
so it is better to use login credentials if you're planning to use a Vault long-term.
-}
fromAccessToken : { accessToken : String, baseUrl : String } -> Vault
fromAccessToken =
Internal.Vault.fromAccessToken
{-| Based on a user's username and password, you can create a vault that will automatically
log in if an access token ever happens to run out, expire or lose contact in any other way.
-}
fromLoginCredentials : { baseUrl : String, username : String, password : String } -> Vault
fromLoginCredentials =
Internal.Vault.fromLoginVault
{-| Whenever you're asking the Matrix API for information that your Vault doesn't have,
you will receive a `VaultUpdate` type. This will reorganise your Vault with the newly
gained information.
After having updated your vault, it (usually) has all the information you need.
-}
updateWith : VaultUpdate -> Vault -> Vault
updateWith =
Internal.Vault.updateWith
{-| The Matrix API is always looking for new ways to optimize synchronising events to your client.
Luckily, you don't need to worry about keeping up a connection!
Your vault is always a snapshot of changes since the last time you updated it.
If you'd like to update it once more, simply run this function and the API will make sure that your Vault has the latest changes.
-}
sync : Vault -> Task X.Error VaultUpdate
sync =
Internal.Vault.sync
{-| Get all the rooms your user has joined, according to your vault.
-}
getRooms : Vault -> List Room
getRooms =
Internal.Vault.rooms
{-| Get a Matrix room by its id.
This will only return the room if you have joined the room.
-}
getRoomById : String -> Vault -> Maybe Room
getRoomById =
Internal.Vault.getRoomById
{-| Get all invites that the user is invited to.
-}
getInvites : Vault -> List RoomInvite
getInvites =
Internal.Vault.getInvites
{-| Join a Matrix room based on its room id.
-}
joinRoomById : String -> Vault -> Task X.Error VaultUpdate
joinRoomById =
Internal.Vault.joinRoomById

124
src/Matrix/RoomInvite.elm Normal file
View File

@ -0,0 +1,124 @@
module Matrix.RoomInvite exposing (..)
{-| Sometimes, your user will be invited to a new room!
This module offers you a few simple handles to deal with such invites -
you can accept them, reject them or inspect them for further information.
# Invitations
@docs RoomInvite, accept, reject, acceptWithReason, rejectWithReason
# Exploring invitations
Sometimes, you may want to display information about the room.
Be careful though, anyone can invite you to any room! This means that room invites
may contain offensive, shocking or other unwanted content that the user may not
want to see.
-}
import Internal.Api.VaultUpdate exposing (VaultUpdate)
import Internal.Invite as Internal
import Internal.Room exposing (Room)
import Internal.Tools.Exceptions as X
import Internal.Values.RoomInvite as IR
import Json.Encode as E
import Task exposing (Task)
{-| The `RoomInvite` type serves as an invite to a given room.
-}
type alias RoomInvite =
Internal.RoomInvite
{-| If you would like to join a room, you can accept the offer.
-}
accept : RoomInvite -> Task X.Error VaultUpdate
accept invite =
Internal.accept { invite = invite, reason = Nothing }
{-| If you don't want to join the room, you can reject the offer.
-}
reject : RoomInvite -> Task X.Error VaultUpdate
reject invite =
Internal.reject { invite = invite, reason = Nothing }
{-| If the Matrix server supports it, you can add a reason for accepting an invite.
-}
acceptWithReason : String -> RoomInvite -> Task X.Error VaultUpdate
acceptWithReason reason invite =
Internal.accept { invite = invite, reason = Just reason }
{-| If the Matrix server supports it, you can add a reason for rejecting an invite.
-}
rejectWithReason : String -> RoomInvite -> Task X.Error VaultUpdate
rejectWithReason reason invite =
Internal.reject { invite = invite, reason = Just reason }
{-| Get the room id of the invited room.
-}
roomId : RoomInvite -> String
roomId =
Internal.getRoomId
{-| The `RoomInviteEvent` type represents a stripped event that your user can see while they haven't joined the group yet.
The invite includes a bunch of these events to tell you what the room looks like, who may be part of it,
and other information that will give you a hint of what kind of room it is.
-}
type alias RoomInviteEvent =
IR.RoomInviteEvent
{-| Get the Matrix user that originally sent this event.
-}
sender : RoomInviteEvent -> String
sender =
IR.sender
{-| Get the content of the event.
-}
content : RoomInviteEvent -> E.Value
content =
IR.content
{-| Get the event's content type.
-}
contentType : RoomInviteEvent -> String
contentType =
IR.contentType
{-| Get the event's state key.
-}
stateKey : RoomInviteEvent -> String
stateKey =
IR.stateKey
{-| Get a specific event with a specific event content type and state key, if it exists.
-}
getEvent : { contentType : 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.
-}
getAllEvents : RoomInvite -> List RoomInviteEvent
getAllEvents =
Internal.getAllEvents