Add Matrix.Room

3-room
Bram 2024-04-26 11:31:35 +02:00
parent c309461602
commit df71779620
5 changed files with 152 additions and 20 deletions

View File

@ -9,6 +9,7 @@
"Internal.Values.Timeline", "Internal.Values.Timeline",
"Matrix", "Matrix",
"Matrix.Event", "Matrix.Event",
"Matrix.Room",
"Matrix.Settings", "Matrix.Settings",
"Matrix.User" "Matrix.User"
], ],

View File

@ -1,7 +1,8 @@
module Internal.Values.Room exposing module Internal.Values.Room exposing
( Room, init ( Room, init
, Batch, addBatch, addSync, addEvents , Batch, addBatch, addSync, addEvents, mostRecentEvents
, getAccountData, setAccountData , getAccountData, setAccountData
, coder, encode, decode
) )
{-| {-|
@ -26,19 +27,24 @@ room state reflect the homeserver state of the room.
## Timeline ## Timeline
@docs Batch, addBatch, addSync, addEvents @docs Batch, addBatch, addSync, addEvents, mostRecentEvents
## Account data ## Account data
@docs getAccountData, setAccountData @docs getAccountData, setAccountData
## JSON coding
@docs coder, encode, decode
-} -}
import FastDict as Dict exposing (Dict) import FastDict as Dict exposing (Dict)
import Internal.Config.Log exposing (log) import Internal.Config.Log exposing (log)
import Internal.Config.Text as Text import Internal.Config.Text as Text
import Internal.Filter.Timeline exposing (Filter) import Internal.Filter.Timeline as Filter exposing (Filter)
import Internal.Tools.Hashdict as Hashdict exposing (Hashdict) import Internal.Tools.Hashdict as Hashdict exposing (Hashdict)
import Internal.Tools.Json as Json import Internal.Tools.Json as Json
import Internal.Values.Event as Event exposing (Event) import Internal.Values.Event as Event exposing (Event)
@ -166,6 +172,20 @@ coder =
) )
{-| Decode a Room from JSON format.
-}
decode : Json.Decoder Room
decode =
Json.decode coder
{-| Encode a Room into JSON format.
-}
encode : Json.Encoder Room
encode =
Json.encode coder
{-| Get a piece of account data as information from the room. {-| Get a piece of account data as information from the room.
-} -}
getAccountData : String -> Room -> Maybe Json.Value getAccountData : String -> Room -> Maybe Json.Value
@ -185,6 +205,19 @@ init roomId =
} }
{-| Get the most recent events from the timeline.
-}
mostRecentEvents : Room -> List Event
mostRecentEvents room =
room.timeline
|> Timeline.mostRecentEvents Filter.pass
|> List.map (List.filterMap (\e -> Hashdict.get e room.events))
|> List.sortBy List.length
-- Get the largest list of events
|> List.head
|> Maybe.withDefault []
{-| Set a piece of account data as information about the room. {-| Set a piece of account data as information about the room.
-} -}
setAccountData : String -> Json.Value -> Room -> Room setAccountData : String -> Json.Value -> Room -> Room

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

@ -0,0 +1,64 @@
module Matrix.Room exposing
( Room, mostRecentEvents
, getAccountData
)
{-|
# Room
What is usually called a chat, a channel, a conversation or a group chat on
other platforms, the term used in Matrix is a "room". A room is a conversation
where a group of users talk to each other.
@docs Room, mostRecentEvents
This module exposes various functions that help you inspect various aspects of
a room.
## Account data
Account data is personal information that the user stores about this Matrix
room. This may include information like:
- What type of room this is
- A list of members in the room to ignore
- A list of currently ongoing chess matches in the room
- Personal notes the user may be taking
You may consider the account data as a `Dict String Json.Value` type. Account
data is linked to the user account: other logged in devices can see the account
data too, as the server synchronizes it, but the server shouldn´t show it to
other users.
@docs getAccountData
-}
import Internal.Values.Envelope as Envelope
import Internal.Values.Room as Internal
import Json.Encode as E
import Types exposing (Room(..))
{-| The Matrix Room type representing a room that the Matrix user has joined.
-}
type alias Room =
Types.Room
{-| Get a piece of account data linked to a certain string key.
-}
getAccountData : String -> Room -> Maybe E.Value
getAccountData key (Room room) =
Envelope.extract (Internal.getAccountData key) room
{-| Get a list of the most recent events sent in the room.
-}
mostRecentEvents : Room -> List Types.Event
mostRecentEvents (Room room) =
Envelope.mapList Internal.mostRecentEvents room
|> List.map Types.Event

View File

@ -1,4 +1,4 @@
module Types exposing (Vault(..), Event(..), User(..)) module Types exposing (Vault(..), Event(..), Room(..), User(..))
{-| The Elm SDK uses a lot of records and values that are easy to manipulate. {-| The Elm SDK uses a lot of records and values that are easy to manipulate.
Yet, the [Elm design guidelines](https://package.elm-lang.org/help/design-guidelines#keep-tags-and-record-constructors-secret) Yet, the [Elm design guidelines](https://package.elm-lang.org/help/design-guidelines#keep-tags-and-record-constructors-secret)
@ -12,12 +12,13 @@ access their content directly.
The opaque types are placed in a central module so all exposed modules can The opaque types are placed in a central module so all exposed modules can
safely access all exposed data types without risking to create circular imports. safely access all exposed data types without risking to create circular imports.
@docs Vault, Event, User @docs Vault, Event, Room, User
-} -}
import Internal.Values.Envelope as Envelope import Internal.Values.Envelope as Envelope
import Internal.Values.Event as Event import Internal.Values.Event as Event
import Internal.Values.Room as Room
import Internal.Values.User as User import Internal.Values.User as User
import Internal.Values.Vault as Vault import Internal.Values.Vault as Vault
@ -28,6 +29,12 @@ type Event
= Event (Envelope.Envelope Event.Event) = Event (Envelope.Envelope Event.Event)
{-| Opaque type for Matrix Room
-}
type Room
= Room (Envelope.Envelope Room.Room)
{-| Opaque type for Matrix User {-| Opaque type for Matrix User
-} -}
type User type User

View File

@ -1,16 +1,19 @@
module Test.Values.Room exposing (..) module Test.Values.Room exposing (..)
import Test exposing (..) import Expect
import Fuzz exposing (Fuzzer) import Fuzz exposing (Fuzzer)
import Internal.Values.Room as Room exposing (Room) import Internal.Values.Room as Room exposing (Room)
import Test.Values.Event as TestEvent
import Test.Filter.Timeline as TestFilter
import Json.Encode as E
import Json.Decode as D import Json.Decode as D
import Expect import Json.Encode as E
import Test exposing (..)
import Test.Filter.Timeline as TestFilter
import Test.Values.Event as TestEvent
placeholderValue : E.Value placeholderValue : E.Value
placeholderValue = E.string "foo bar baz" placeholderValue =
E.string "foo bar baz"
fuzzer : Fuzzer Room fuzzer : Fuzzer Room
fuzzer = fuzzer =
@ -18,17 +21,24 @@ fuzzer =
|> Fuzz.map Room.init |> Fuzz.map Room.init
|> addAFewTimes Fuzz.string (\key -> Room.setAccountData key placeholderValue) |> addAFewTimes Fuzz.string (\key -> Room.setAccountData key placeholderValue)
|> addAFewTimes (Fuzz.list TestEvent.fuzzer) Room.addEvents |> addAFewTimes (Fuzz.list TestEvent.fuzzer) Room.addEvents
|> add4AFewTimes (Fuzz.list TestEvent.fuzzer) TestFilter.fuzzer (Fuzz.maybe Fuzz.string) Fuzz.string |> add4AFewTimes (Fuzz.list TestEvent.fuzzer)
TestFilter.fuzzer
(Fuzz.maybe Fuzz.string)
Fuzz.string
(\a b c d -> (\a b c d ->
Room.Batch a b c d Room.Batch a b c d
|> Room.addBatch |> Room.addBatch
) )
|> add4AFewTimes (Fuzz.list TestEvent.fuzzer) TestFilter.fuzzer (Fuzz.maybe Fuzz.string) Fuzz.string |> add4AFewTimes (Fuzz.list TestEvent.fuzzer)
TestFilter.fuzzer
(Fuzz.maybe Fuzz.string)
Fuzz.string
(\a b c d -> (\a b c d ->
Room.Batch a b c d Room.Batch a b c d
|> Room.addSync |> Room.addSync
) )
addAFewTimes : Fuzzer a -> (a -> Room -> Room) -> Fuzzer Room -> Fuzzer Room addAFewTimes : Fuzzer a -> (a -> Room -> Room) -> Fuzzer Room -> Fuzzer Room
addAFewTimes fuzz f roomFuzzer = addAFewTimes fuzz f roomFuzzer =
Fuzz.map2 Fuzz.map2
@ -36,6 +46,7 @@ addAFewTimes fuzz f roomFuzzer =
(Fuzz.list fuzz) (Fuzz.list fuzz)
roomFuzzer roomFuzzer
add2AFewTimes : Fuzzer a -> Fuzzer b -> (a -> b -> Room -> Room) -> Fuzzer Room -> Fuzzer Room add2AFewTimes : Fuzzer a -> Fuzzer b -> (a -> b -> Room -> Room) -> Fuzzer Room -> Fuzzer Room
add2AFewTimes fuzz1 fuzz2 f roomFuzzer = add2AFewTimes fuzz1 fuzz2 f roomFuzzer =
Fuzz.map2 Fuzz.map2
@ -43,6 +54,7 @@ add2AFewTimes fuzz1 fuzz2 f roomFuzzer =
(Fuzz.list <| Fuzz.pair fuzz1 fuzz2) (Fuzz.list <| Fuzz.pair fuzz1 fuzz2)
roomFuzzer roomFuzzer
add3AFewTimes : Fuzzer a -> Fuzzer b -> Fuzzer c -> (a -> b -> c -> Room -> Room) -> Fuzzer Room -> Fuzzer Room add3AFewTimes : Fuzzer a -> Fuzzer b -> Fuzzer c -> (a -> b -> c -> Room -> Room) -> Fuzzer Room -> Fuzzer Room
add3AFewTimes fuzz1 fuzz2 fuzz3 f roomFuzzer = add3AFewTimes fuzz1 fuzz2 fuzz3 f roomFuzzer =
Fuzz.map2 Fuzz.map2
@ -50,6 +62,7 @@ add3AFewTimes fuzz1 fuzz2 fuzz3 f roomFuzzer =
(Fuzz.list <| Fuzz.triple fuzz1 fuzz2 fuzz3) (Fuzz.list <| Fuzz.triple fuzz1 fuzz2 fuzz3)
roomFuzzer roomFuzzer
add4AFewTimes : Fuzzer a -> Fuzzer b -> Fuzzer c -> Fuzzer d -> (a -> b -> c -> d -> Room -> Room) -> Fuzzer Room -> Fuzzer Room add4AFewTimes : Fuzzer a -> Fuzzer b -> Fuzzer c -> Fuzzer d -> (a -> b -> c -> d -> Room -> Room) -> Fuzzer Room -> Fuzzer Room
add4AFewTimes fuzz1 fuzz2 fuzz3 fuzz4 f roomFuzzer = add4AFewTimes fuzz1 fuzz2 fuzz3 fuzz4 f roomFuzzer =
Fuzz.map2 Fuzz.map2
@ -57,10 +70,14 @@ add4AFewTimes fuzz1 fuzz2 fuzz3 fuzz4 f roomFuzzer =
(Fuzz.list <| Fuzz.pair (Fuzz.pair fuzz1 fuzz2) (Fuzz.pair fuzz3 fuzz4)) (Fuzz.list <| Fuzz.pair (Fuzz.pair fuzz1 fuzz2) (Fuzz.pair fuzz3 fuzz4))
roomFuzzer roomFuzzer
suite : Test suite : Test
suite = suite =
describe "Room" describe "Room"
[ fuzz3 fuzzer Fuzz.string Fuzz.string "JSON Account Data can be overridden" [ fuzz3 fuzzer
Fuzz.string
Fuzz.string
"JSON Account Data can be overridden"
(\room key text -> (\room key text ->
room room
|> Room.setAccountData key (E.string text) |> Room.setAccountData key (E.string text)
@ -69,4 +86,14 @@ suite =
|> Maybe.andThen Result.toMaybe |> Maybe.andThen Result.toMaybe
|> Expect.equal (Just text) |> Expect.equal (Just text)
) )
, fuzz fuzzer
"Room -> JSON -> Room is equal"
(\room ->
room
|> Room.encode
|> D.decodeValue Room.decode
|> Result.toMaybe
|> Maybe.map Tuple.first
|> Expect.equal (Just room)
)
] ]