Add exposed Event module
parent
5065ed05ff
commit
1a819cbe39
1
elm.json
1
elm.json
|
@ -6,6 +6,7 @@
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"exposed-modules": [
|
"exposed-modules": [
|
||||||
"Matrix",
|
"Matrix",
|
||||||
|
"Matrix.Event",
|
||||||
"Matrix.Settings",
|
"Matrix.Settings",
|
||||||
"Internal.Config.Default",
|
"Internal.Config.Default",
|
||||||
"Internal.Config.Leaks",
|
"Internal.Config.Leaks",
|
||||||
|
|
|
@ -66,7 +66,7 @@ type UnsignedData
|
||||||
= UnsignedData
|
= UnsignedData
|
||||||
{ age : Maybe Int
|
{ age : Maybe Int
|
||||||
, prevContent : Maybe E.Value
|
, prevContent : Maybe E.Value
|
||||||
, redactedBecause : Maybe Event
|
, redactedBecause : Maybe IEvent
|
||||||
, transactionId : Maybe String
|
, transactionId : Maybe String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +95,11 @@ content =
|
||||||
-}
|
-}
|
||||||
decoder : D.Decoder Event
|
decoder : D.Decoder Event
|
||||||
decoder =
|
decoder =
|
||||||
|
Envelope.decoder decoderInternal
|
||||||
|
|
||||||
|
|
||||||
|
decoderInternal : D.Decoder IEvent
|
||||||
|
decoderInternal =
|
||||||
D.map8 IEvent
|
D.map8 IEvent
|
||||||
(D.field "content" D.value)
|
(D.field "content" D.value)
|
||||||
(D.field "eventId" D.string)
|
(D.field "eventId" D.string)
|
||||||
|
@ -104,7 +109,6 @@ decoder =
|
||||||
(D.opField "stateKey" D.string)
|
(D.opField "stateKey" D.string)
|
||||||
(D.field "eventType" D.string)
|
(D.field "eventType" D.string)
|
||||||
(D.opField "unsigned" decoderUnsignedData)
|
(D.opField "unsigned" decoderUnsignedData)
|
||||||
|> Envelope.decoder
|
|
||||||
|
|
||||||
|
|
||||||
{-| Decode Unsigned Data from a JSON value.
|
{-| Decode Unsigned Data from a JSON value.
|
||||||
|
@ -114,16 +118,19 @@ decoderUnsignedData =
|
||||||
D.map4 (\a b c d -> UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d })
|
D.map4 (\a b c d -> UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d })
|
||||||
(D.opField "age" D.int)
|
(D.opField "age" D.int)
|
||||||
(D.opField "prevContent" D.value)
|
(D.opField "prevContent" D.value)
|
||||||
(D.opField "redactedBecause" (D.lazy (\_ -> decoder)))
|
(D.opField "redactedBecause" (D.lazy (\_ -> decoderInternal)))
|
||||||
(D.opField "transactionId" D.string)
|
(D.opField "transactionId" D.string)
|
||||||
|
|
||||||
|
|
||||||
{-| Encode an Event into a JSON value.
|
{-| Encode an Event into a JSON value.
|
||||||
-}
|
-}
|
||||||
encode : Event -> E.Value
|
encode : Event -> E.Value
|
||||||
encode envelope =
|
encode =
|
||||||
Envelope.encode
|
Envelope.encode encodeInternal
|
||||||
(\event ->
|
|
||||||
|
|
||||||
|
encodeInternal : IEvent -> E.Value
|
||||||
|
encodeInternal event =
|
||||||
E.maybeObject
|
E.maybeObject
|
||||||
[ ( "content", Just event.content )
|
[ ( "content", Just event.content )
|
||||||
, ( "eventId", Just <| E.string event.eventId )
|
, ( "eventId", Just <| E.string event.eventId )
|
||||||
|
@ -135,8 +142,6 @@ encode envelope =
|
||||||
, ( "unsigned", Maybe.map encodeUnsignedData event.unsigned )
|
, ( "unsigned", Maybe.map encodeUnsignedData event.unsigned )
|
||||||
, ( "version", Just <| E.string Default.currentVersion )
|
, ( "version", Just <| E.string Default.currentVersion )
|
||||||
]
|
]
|
||||||
)
|
|
||||||
envelope
|
|
||||||
|
|
||||||
|
|
||||||
{-| Encode Unsigned Data into a JSON value.
|
{-| Encode Unsigned Data into a JSON value.
|
||||||
|
@ -146,7 +151,7 @@ encodeUnsignedData (UnsignedData data) =
|
||||||
E.maybeObject
|
E.maybeObject
|
||||||
[ ( "age", Maybe.map E.int data.age )
|
[ ( "age", Maybe.map E.int data.age )
|
||||||
, ( "prevContent", data.prevContent )
|
, ( "prevContent", data.prevContent )
|
||||||
, ( "redactedBecause", Maybe.map encode data.redactedBecause )
|
, ( "redactedBecause", Maybe.map encodeInternal data.redactedBecause )
|
||||||
, ( "transactionId", Maybe.map E.string data.transactionId )
|
, ( "transactionId", Maybe.map E.string data.transactionId )
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -204,14 +209,13 @@ prevContent envelope =
|
||||||
redacted it here.
|
redacted it here.
|
||||||
-}
|
-}
|
||||||
redactedBecause : Event -> Maybe Event
|
redactedBecause : Event -> Maybe Event
|
||||||
redactedBecause envelope =
|
redactedBecause =
|
||||||
Envelope.extract
|
Envelope.mapMaybe
|
||||||
(\event ->
|
(\event ->
|
||||||
Maybe.andThen
|
Maybe.andThen
|
||||||
(\(UnsignedData data) -> data.redactedBecause)
|
(\(UnsignedData data) -> data.redactedBecause)
|
||||||
event.unsigned
|
event.unsigned
|
||||||
)
|
)
|
||||||
envelope
|
|
||||||
|
|
||||||
|
|
||||||
{-| Unique id assigned to the Matrix room. You can use this room id to reference
|
{-| Unique id assigned to the Matrix room. You can use this room id to reference
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
module Matrix.Event exposing
|
||||||
|
( Event, content, eventType, stateKey
|
||||||
|
, eventId, originServerTs, roomId, sender
|
||||||
|
, previousContent, redactedBecause
|
||||||
|
)
|
||||||
|
|
||||||
|
{-|
|
||||||
|
|
||||||
|
|
||||||
|
# Matrix Events
|
||||||
|
|
||||||
|
This module contains all the functions necessary to view and manipulate Matrix
|
||||||
|
events.
|
||||||
|
|
||||||
|
|
||||||
|
## Event
|
||||||
|
|
||||||
|
@docs Event, content, eventType, stateKey
|
||||||
|
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
@docs eventId, originServerTs, roomId, sender
|
||||||
|
|
||||||
|
|
||||||
|
## Optional data
|
||||||
|
|
||||||
|
Occasionally, the Event might bring some extra information. Given how this
|
||||||
|
information isn't always applicable, it doesn't always exist.
|
||||||
|
|
||||||
|
@docs previousContent, redactedBecause
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Internal.Values.Event as Internal
|
||||||
|
import Json.Encode
|
||||||
|
import Time
|
||||||
|
import Types exposing (Event(..))
|
||||||
|
|
||||||
|
|
||||||
|
{-| In Matrix, the primary form of communication is to send JSON values to one
|
||||||
|
another. These JSON values, together with their metadata, are bundled into Event
|
||||||
|
types. They contain information like:
|
||||||
|
|
||||||
|
- Who sent the JSON value
|
||||||
|
- How they intend you to decode it
|
||||||
|
- When they sent it
|
||||||
|
- In what room they sent it
|
||||||
|
|
||||||
|
-}
|
||||||
|
type alias Event =
|
||||||
|
Types.Event
|
||||||
|
|
||||||
|
|
||||||
|
{-| Receive the body of an Event, as created by the user that sent it.
|
||||||
|
-}
|
||||||
|
content : Event -> Json.Encode.Value
|
||||||
|
content (Event event) =
|
||||||
|
Internal.content event
|
||||||
|
|
||||||
|
|
||||||
|
{-| Determine the globally unique identifier for an event.
|
||||||
|
-}
|
||||||
|
eventId : Event -> String
|
||||||
|
eventId (Event event) =
|
||||||
|
Internal.eventId event
|
||||||
|
|
||||||
|
|
||||||
|
{-| To give a hint what the event's [content](#content) might look like, users
|
||||||
|
can use this eventType value to hint at how the JSON might be decoded.
|
||||||
|
|
||||||
|
Standard examples of event types are `m.room.message`, `m.room.member` and
|
||||||
|
`me.noordstar.game.chess.move`.
|
||||||
|
|
||||||
|
-}
|
||||||
|
eventType : Event -> String
|
||||||
|
eventType (Event event) =
|
||||||
|
Internal.eventType event
|
||||||
|
|
||||||
|
|
||||||
|
{-| Determine the timestamp of at what time the event was originally received by
|
||||||
|
the original homeserver.
|
||||||
|
|
||||||
|
Generally, this timestamp offers a relatively accurate indicator of when a
|
||||||
|
message was sent. However, this number isn't completely reliable! The timestamp
|
||||||
|
can be far in the past due to long network lag, and a (malicious) homeserver can
|
||||||
|
spoof this number to make it seem like something was sent ridiculously far in
|
||||||
|
the past - or even in the future.
|
||||||
|
|
||||||
|
-}
|
||||||
|
originServerTs : Event -> Time.Posix
|
||||||
|
originServerTs (Event event) =
|
||||||
|
Internal.originServerTs event
|
||||||
|
|
||||||
|
|
||||||
|
{-| Determine the previous `content` value for this event. This field is only a
|
||||||
|
`Just value` if the event is a state event, and the Matrix Vault has permission
|
||||||
|
to see the previous content.
|
||||||
|
-}
|
||||||
|
previousContent : Event -> Maybe Json.Encode.Value
|
||||||
|
previousContent (Event event) =
|
||||||
|
Internal.prevContent event
|
||||||
|
|
||||||
|
|
||||||
|
{-| If the event has been redacted, the homeserver can display the event that
|
||||||
|
redacted it here.
|
||||||
|
-}
|
||||||
|
redactedBecause : Event -> Maybe Event
|
||||||
|
redactedBecause (Event event) =
|
||||||
|
Internal.redactedBecause event
|
||||||
|
|> Maybe.map Event
|
||||||
|
|
||||||
|
|
||||||
|
{-| Unique id assigned to the Matrix room. You can use this room id to reference
|
||||||
|
or look up rooms.
|
||||||
|
-}
|
||||||
|
roomId : Event -> String
|
||||||
|
roomId (Event event) =
|
||||||
|
Internal.roomId event
|
||||||
|
|
||||||
|
|
||||||
|
{-| Determine the fully-qualified ID of the user who sent an event.
|
||||||
|
-}
|
||||||
|
sender : Event -> String
|
||||||
|
sender (Event event) =
|
||||||
|
Internal.sender event
|
||||||
|
|
||||||
|
|
||||||
|
{-| Determine an event's state key.
|
||||||
|
|
||||||
|
It is present if, and only if, the event is a _state_ event. The key makes the
|
||||||
|
piece of state unique in the room. Note that it is often `Just ""`. If it is not
|
||||||
|
present, its value is `Nothing`.
|
||||||
|
|
||||||
|
State keys starting with an `@` are reserved for referencing user IDs, such as
|
||||||
|
room members. With the exception of a few events, state events set with a given
|
||||||
|
user'd ID as the state key can only be set by that user.
|
||||||
|
|
||||||
|
-}
|
||||||
|
stateKey : Event -> Maybe String
|
||||||
|
stateKey (Event event) =
|
||||||
|
Internal.stateKey event
|
Loading…
Reference in New Issue