Compare commits

..

No commits in common. "a8d879afbb8f3c6e9954b0c1477a4b5aa65605e8" and "c473d601618da7c4f9539f6ebb625e0f6e0ebcd4" have entirely different histories.

34 changed files with 192 additions and 1519 deletions

View File

@ -3,7 +3,7 @@
"name": "noordstar/elm-matrix-sdk-beta", "name": "noordstar/elm-matrix-sdk-beta",
"summary": "Matrix SDK for instant communication. Unstable beta version for testing only.", "summary": "Matrix SDK for instant communication. Unstable beta version for testing only.",
"license": "EUPL-1.1", "license": "EUPL-1.1",
"version": "3.4.0", "version": "3.3.1",
"exposed-modules": [ "exposed-modules": [
"Matrix", "Matrix",
"Matrix.Event", "Matrix.Event",

View File

@ -1,116 +0,0 @@
module Internal.Api.BanUser.Api exposing (Phantom, banUser)
{-|
# Ban user
This module helps to ban users from a room.
@docs Phantom, banUser
-}
import Internal.Api.Api as A
import Internal.Api.Request as R
import Internal.Config.Log exposing (log)
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Values.Envelope as E
import Internal.Values.Room as R
import Internal.Values.User as User exposing (User)
import Internal.Values.Vault as V
banUser : BanUserInput -> A.TaskChain (Phantom a) (Phantom a)
banUser =
A.startWithVersion "r0.0.0" banUserV1
|> A.sameForVersion "r0.0.1"
|> A.sameForVersion "r0.1.0"
|> A.sameForVersion "r0.2.0"
|> A.sameForVersion "r0.2.0"
|> A.sameForVersion "r0.3.0"
|> A.sameForVersion "r0.4.0"
|> A.sameForVersion "r0.5.0"
|> A.sameForVersion "r0.6.0"
|> A.sameForVersion "r0.6.1"
|> A.forVersion "v1.1" banUserV2
|> A.sameForVersion "v1.2"
|> A.sameForVersion "v1.3"
|> A.sameForVersion "v1.4"
|> A.sameForVersion "v1.5"
|> A.sameForVersion "v1.6"
|> A.sameForVersion "v1.7"
|> A.sameForVersion "v1.8"
|> A.sameForVersion "v1.9"
|> A.sameForVersion "v1.10"
|> A.sameForVersion "v1.11"
|> A.versionChain
type alias Phantom a =
{ a | accessToken : (), baseUrl : (), versions : () }
type alias PhantomV1 a =
{ a | accessToken : (), baseUrl : () }
type alias BanUserInput =
{ reason : Maybe String
, roomId : String
, user : User
}
type alias BanUserInputV1 a =
{ a | reason : Maybe String, roomId : String, user : User }
type alias BanUserOutputV1 =
()
banUserV1 : BanUserInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
banUserV1 { reason, roomId, user } =
A.request
{ attributes =
[ R.accessToken
, R.bodyOpString "reason" reason
, R.bodyString "user_id" (User.toString user)
]
, coder = coderV1
, contextChange = always identity
, method = "POST"
, path = [ "_matrix", "client", "r0", "rooms", roomId, "ban" ]
, toUpdate =
\() ->
( E.More []
, []
)
}
banUserV2 : BanUserInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
banUserV2 { reason, roomId, user } =
A.request
{ attributes =
[ R.accessToken
, R.bodyOpString "reason" reason
, R.bodyString "user_id" (User.toString user)
]
, coder = coderV1
, contextChange = always identity
, method = "POST"
, path = [ "_matrix", "client", "v3", "rooms", roomId, "ban" ]
, toUpdate =
\() ->
( E.More []
, []
)
}
coderV1 : Json.Coder BanUserOutputV1
coderV1 =
Json.unit

View File

@ -13,6 +13,7 @@ This module looks for the right homeserver address.
import Internal.Api.Chain as C import Internal.Api.Chain as C
import Internal.Api.Request as R import Internal.Api.Request as R
import Internal.Config.Leaks as L
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.Tools.Json as Json import Internal.Tools.Json as Json

View File

@ -204,7 +204,7 @@ getEventCoderV1 =
[ "UnsignedData as described by the Matrix spec" [ "UnsignedData as described by the Matrix spec"
, "https://spec.matrix.org/v1.10/client-server-api/#get_matrixclientv3roomsroomideventeventid" , "https://spec.matrix.org/v1.10/client-server-api/#get_matrixclientv3roomsroomideventeventid"
] ]
, init = \a b c d -> Event.UnsignedData { age = a, membership = Nothing, prevContent = b, redactedBecause = c, transactionId = d } , init = \a b c d -> Event.UnsignedData { age = a, prevContent = b, redactedBecause = c, transactionId = d }
} }
(Json.field.optional.value (Json.field.optional.value
{ fieldName = "age" { fieldName = "age"

View File

@ -1,4 +1,4 @@
module Internal.Api.InviteUser.Api exposing (InviteInput, Phantom, inviteUser) module Internal.Api.Invite.Api exposing (InviteInput, Phantom, invite)
{-| {-|
@ -14,7 +14,7 @@ room.
If the user was invited to the room, the homeserver will append a m.room.member If the user was invited to the room, the homeserver will append a m.room.member
event to the room. event to the room.
@docs InviteInput, Phantom, inviteUser @docs InviteInput, Phantom, invite
-} -}
@ -31,8 +31,8 @@ import Internal.Values.Vault as V
{-| Invite a user to a room. {-| Invite a user to a room.
-} -}
inviteUser : InviteInput -> A.TaskChain (Phantom ph1) (Phantom ph1) invite : InviteInput -> A.TaskChain (Phantom ph1) (Phantom ph1)
inviteUser = invite =
A.startWithVersion "r0.0.0" inviteV1 A.startWithVersion "r0.0.0" inviteV1
|> A.sameForVersion "r0.0.1" |> A.sameForVersion "r0.0.1"
|> A.sameForVersion "r0.1.0" |> A.sameForVersion "r0.1.0"

View File

@ -1,178 +0,0 @@
module Internal.Api.KickUser.Api exposing (Phantom, kickUser)
{-|
# Kick user
This module helps to kick users from a room.
@docs Phantom, kickUser
-}
import Internal.Api.Api as A
import Internal.Api.Request as R
import Internal.Config.Log exposing (log)
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Values.Envelope as E
import Internal.Values.Room as R
import Internal.Values.User as User exposing (User)
import Internal.Values.Vault as V
kickUser : KickUserInput -> A.TaskChain (Phantom a) (Phantom a)
kickUser =
A.startWithVersion "r0.0.0" kickUserV1
|> A.sameForVersion "r0.0.1"
-- NOTE: Kicking a user was first added in r0.1.0
|> A.forVersion "r0.1.0" kickUserV2
|> A.sameForVersion "r0.2.0"
|> A.sameForVersion "r0.2.0"
|> A.sameForVersion "r0.3.0"
|> A.sameForVersion "r0.4.0"
|> A.sameForVersion "r0.5.0"
|> A.sameForVersion "r0.6.0"
|> A.sameForVersion "r0.6.1"
|> A.forVersion "v1.1" kickUserV3
|> A.sameForVersion "v1.2"
|> A.sameForVersion "v1.3"
|> A.sameForVersion "v1.4"
|> A.sameForVersion "v1.5"
|> A.sameForVersion "v1.6"
|> A.sameForVersion "v1.7"
|> A.sameForVersion "v1.8"
|> A.sameForVersion "v1.9"
|> A.sameForVersion "v1.10"
|> A.sameForVersion "v1.11"
|> A.versionChain
type alias Phantom a =
{ a | accessToken : (), baseUrl : (), versions : () }
type alias PhantomV1 a =
{ a | accessToken : (), baseUrl : () }
type alias KickUserInput =
{ avatarUrl : Maybe String
, displayname : Maybe String
, reason : Maybe String
, roomId : String
, user : User
}
type alias KickUserInputV1 a =
{ a
| avatarUrl : Maybe String
, displayname : Maybe String
, reason : Maybe String
, roomId : String
, user : User
}
type alias KickUserInputV2 a =
{ a | reason : Maybe String, roomId : String, user : User }
type alias KickUserOutputV1 =
{ eventId : Maybe String }
type alias KickUserOutputV2 =
()
kickUserV1 : KickUserInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
kickUserV1 { avatarUrl, displayname, reason, roomId, user } =
A.request
{ attributes =
[ R.accessToken
, R.bodyString "membership" "kick"
, R.bodyOpString "avatar_url" avatarUrl
, R.bodyOpString "displayname" displayname
, R.bodyOpString "reason" reason
]
, coder = coderV1
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "r0", "rooms", roomId, "state", "m.room.member", User.toString user ]
, toUpdate =
\out ->
( E.More []
, [ "The kick API endpoint does not exist before spec version r0.1.0 - falling back to sending state event directly."
|> log.debug
, out.eventId
|> Text.logs.sendEvent
|> log.debug
]
)
}
kickUserV2 : KickUserInputV2 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
kickUserV2 { reason, roomId, user } =
A.request
{ attributes =
[ R.accessToken
, R.bodyOpString "reason" reason
, R.bodyString "user_id" (User.toString user)
]
, coder = coderV2
, contextChange = always identity
, method = "POST"
, path = [ "_matrix", "client", "r0", "rooms", roomId, "kick" ]
, toUpdate =
\() ->
( E.More []
, []
)
}
kickUserV3 : KickUserInputV2 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
kickUserV3 { reason, roomId, user } =
A.request
{ attributes =
[ R.accessToken
, R.bodyOpString "reason" reason
, R.bodyString "user_id" (User.toString user)
]
, coder = coderV2
, contextChange = always identity
, method = "POST"
, path = [ "_matrix", "client", "v3", "rooms", roomId, "kick" ]
, toUpdate =
\() ->
( E.More []
, []
)
}
coderV1 : Json.Coder KickUserOutputV1
coderV1 =
Json.object1
{ name = "EventResponse"
, description =
[ "This object is returned after a state event has been sent."
]
, init = KickUserOutputV1
}
(Json.field.optional.value
{ fieldName = "event_id"
, toField = .eventId
, description = [ "A unique identifier for the event." ]
, coder = Json.string
}
)
coderV2 : Json.Coder KickUserOutputV2
coderV2 =
Json.unit

View File

@ -13,6 +13,7 @@ This module allows the user to log in using a username and password.
import Internal.Api.Api as A import Internal.Api.Api as A
import Internal.Api.Request as R import Internal.Api.Request as R
import Internal.Config.Leaks as L
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.Tools.Json as Json import Internal.Tools.Json as Json
@ -191,7 +192,7 @@ loginWithUsernameAndPasswordV1 { username, password } =
} }
, E.RemovePasswordIfNecessary , E.RemovePasswordIfNecessary
, out.user , out.user
|> Maybe.map E.SetUser |> Maybe.map (V.SetUser >> E.ContentUpdate)
|> E.Optional |> E.Optional
] ]
, Text.logs.loggedInAs username , Text.logs.loggedInAs username
@ -233,7 +234,7 @@ loginWithUsernameAndPasswordV2 { deviceId, initialDeviceDisplayName, username, p
} }
, E.RemovePasswordIfNecessary , E.RemovePasswordIfNecessary
, out.user , out.user
|> Maybe.map E.SetUser |> Maybe.map (V.SetUser >> E.ContentUpdate)
|> E.Optional |> E.Optional
, out.deviceId , out.deviceId
|> Maybe.map E.SetDeviceId |> Maybe.map E.SetDeviceId
@ -285,7 +286,7 @@ loginWithUsernameAndPasswordV3 { deviceId, initialDeviceDisplayName, username, p
} }
, E.RemovePasswordIfNecessary , E.RemovePasswordIfNecessary
, out.user , out.user
|> Maybe.map E.SetUser |> Maybe.map (V.SetUser >> E.ContentUpdate)
|> E.Optional |> E.Optional
, out.deviceId , out.deviceId
|> Maybe.map E.SetDeviceId |> Maybe.map E.SetDeviceId
@ -337,7 +338,7 @@ loginWithUsernameAndPasswordV4 { deviceId, initialDeviceDisplayName, username, p
} }
, E.RemovePasswordIfNecessary , E.RemovePasswordIfNecessary
, out.user , out.user
|> Maybe.map E.SetUser |> Maybe.map (V.SetUser >> E.ContentUpdate)
|> E.Optional |> E.Optional
, out.wellKnown , out.wellKnown
|> Maybe.map (.homeserver >> .baseUrl) |> Maybe.map (.homeserver >> .baseUrl)
@ -393,7 +394,7 @@ loginWithUsernameAndPasswordV5 { deviceId, initialDeviceDisplayName, username, p
} }
, E.RemovePasswordIfNecessary , E.RemovePasswordIfNecessary
, out.user , out.user
|> Maybe.map E.SetUser |> Maybe.map (V.SetUser >> E.ContentUpdate)
|> E.Optional |> E.Optional
, out.wellKnown , out.wellKnown
|> Maybe.map (.homeserver >> .baseUrl) |> Maybe.map (.homeserver >> .baseUrl)
@ -450,7 +451,7 @@ loginWithUsernameAndPasswordV6 { deviceId, enableRefreshToken, initialDeviceDisp
} }
, E.RemovePasswordIfNecessary , E.RemovePasswordIfNecessary
, out.user , out.user
|> Maybe.map E.SetUser |> Maybe.map (V.SetUser >> E.ContentUpdate)
|> E.Optional |> E.Optional
, out.wellKnown , out.wellKnown
|> Maybe.map (.homeserver >> .baseUrl) |> Maybe.map (.homeserver >> .baseUrl)
@ -506,7 +507,7 @@ loginWithUsernameAndPasswordV7 { deviceId, enableRefreshToken, initialDeviceDisp
, value = out.accessToken , value = out.accessToken
} }
, E.RemovePasswordIfNecessary , E.RemovePasswordIfNecessary
, E.SetUser out.user , E.ContentUpdate (V.SetUser out.user)
, out.wellKnown , out.wellKnown
|> Maybe.map (.homeserver >> .baseUrl) |> Maybe.map (.homeserver >> .baseUrl)
|> Maybe.map E.SetBaseUrl |> Maybe.map E.SetBaseUrl

View File

@ -1,6 +1,6 @@
module Internal.Api.Main exposing module Internal.Api.Main exposing
( Msg ( Msg
, banUser, inviteUser, kickUser, sendMessageEvent, sendStateEvent, setAccountData, setRoomAccountData, sync , sendMessageEvent, sync
) )
{-| {-|
@ -18,7 +18,7 @@ This module is used as reference for getting
## Actions ## Actions
@docs banUser, inviteUser, kickUser, sendMessageEvent, sendStateEvent, setAccountData, setRoomAccountData, sync @docs sendMessageEvent, sync
-} -}
@ -26,8 +26,6 @@ import Internal.Api.Task as ITask exposing (Backpack)
import Internal.Tools.Json as Json import Internal.Tools.Json as Json
import Internal.Values.Context as Context import Internal.Values.Context as Context
import Internal.Values.Envelope as E import Internal.Values.Envelope as E
import Internal.Values.User as User exposing (User)
import Internal.Values.Vault as V
{-| Update message type that is being returned. {-| Update message type that is being returned.
@ -36,77 +34,6 @@ type alias Msg =
Backpack Backpack
{-| Ban a user from a room.
-}
banUser :
E.Envelope a
->
{ reason : Maybe String
, roomId : String
, toMsg : Msg -> msg
, user : User
}
-> Cmd msg
banUser env data =
ITask.run
data.toMsg
(ITask.banUser
{ reason = data.reason
, roomId = data.roomId
, user = data.user
}
)
(Context.apiFormat env.context)
{-| Invite a user to a room.
-}
inviteUser :
E.Envelope a
->
{ reason : Maybe String
, roomId : String
, toMsg : Msg -> msg
, user : User
}
-> Cmd msg
inviteUser env data =
ITask.run
data.toMsg
(ITask.inviteUser
{ reason = data.reason
, roomId = data.roomId
, user = data.user
}
)
(Context.apiFormat env.context)
{-| Kick a user from a room.
-}
kickUser :
E.Envelope a
->
{ reason : Maybe String
, roomId : String
, toMsg : Msg -> msg
, user : User
}
-> Cmd msg
kickUser env data =
ITask.run
data.toMsg
(ITask.kickUser
{ avatarUrl = Nothing
, displayname = Nothing
, reason = data.reason
, roomId = data.roomId
, user = data.user
}
)
(Context.apiFormat env.context)
{-| Send a message event. {-| Send a message event.
-} -}
sendMessageEvent : sendMessageEvent :
@ -132,91 +59,6 @@ sendMessageEvent env data =
(Context.apiFormat env.context) (Context.apiFormat env.context)
{-| Send a state event to a room.
-}
sendStateEvent :
E.Envelope a
->
{ content : Json.Value
, eventType : String
, roomId : String
, stateKey : String
, toMsg : Msg -> msg
}
-> Cmd msg
sendStateEvent env data =
ITask.run
data.toMsg
(ITask.sendStateEvent
{ content = data.content
, eventType = data.eventType
, roomId = data.roomId
, stateKey = data.stateKey
}
)
(Context.apiFormat env.context)
{-| Set global account data.
-}
setAccountData :
E.Envelope a
->
{ content : Json.Value
, eventType : String
, toMsg : Msg -> msg
}
-> Cmd msg
setAccountData env data =
case env.context.user of
Just u ->
ITask.run
data.toMsg
(ITask.setAccountData
{ content = data.content
, eventType = data.eventType
, userId = User.toString u
}
)
(Context.apiFormat env.context)
Nothing ->
Cmd.none
{-| Set the account data for a Matrix room.
-}
setRoomAccountData :
E.Envelope a
->
{ content : Json.Value
, eventType : String
, roomId : String
, toMsg : Msg -> msg
}
-> Cmd msg
setRoomAccountData env data =
case env.context.user of
Just u ->
ITask.run
data.toMsg
(ITask.setRoomAccountData
{ content = data.content
, eventType = data.eventType
, roomId = data.roomId
, userId = User.toString u
}
)
(Context.apiFormat env.context)
Nothing ->
Cmd.none
-- TODO: Return error about lacking user capabilities
{-| Sync with the Matrix API to stay up-to-date. {-| Sync with the Matrix API to stay up-to-date.
-} -}
sync : sync :

View File

@ -13,6 +13,7 @@ This module helps send message events to rooms on the Matrix API.
import Internal.Api.Api as A import Internal.Api.Api as A
import Internal.Api.Request as R import Internal.Api.Request as R
import Internal.Config.Leaks as L
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.Tools.Json as Json import Internal.Tools.Json as Json

View File

@ -1,176 +0,0 @@
module Internal.Api.SendStateEvent.Api exposing (..)
{-|
# Send state event
This module sends state events to Matrix rooms.
@docs Phantom, sendStateEvent
-}
import Internal.Api.Api as A
import Internal.Api.Request as R
import Internal.Config.Log exposing (log)
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Values.Envelope as E
{-| Send a state event to a Matrix room.
-}
sendStateEvent : SendStateEventInput -> A.TaskChain (Phantom a) (Phantom a)
sendStateEvent =
A.startWithVersion "r0.0.0" sendStateEventV1
|> A.sameForVersion "r0.0.1"
|> A.sameForVersion "r0.1.0"
|> A.sameForVersion "r0.2.0"
|> A.sameForVersion "r0.3.0"
|> A.sameForVersion "r0.4.0"
|> A.sameForVersion "r0.5.0"
|> A.sameForVersion "r0.6.0"
|> A.forVersion "r0.6.1" sendStateEventV2
|> A.forVersion "v1.1" sendStateEventV3
|> A.sameForVersion "v1.2"
|> A.sameForVersion "v1.3"
|> A.sameForVersion "v1.4"
|> A.sameForVersion "v1.5"
|> A.sameForVersion "v1.6"
|> A.sameForVersion "v1.7"
|> A.sameForVersion "v1.8"
|> A.sameForVersion "v1.9"
|> A.sameForVersion "v1.10"
|> A.sameForVersion "v1.11"
|> A.versionChain
{-| Context needed for sending a state event
-}
type alias Phantom a =
{ a | accessToken : (), baseUrl : (), versions : () }
type alias PhantomV1 a =
{ a | accessToken : (), baseUrl : () }
type alias SendStateEventInput =
{ content : Json.Value
, eventType : String
, roomId : String
, stateKey : String
}
type alias SendStateEventInputV1 a =
{ a
| content : Json.Value
, eventType : String
, roomId : String
, stateKey : String
}
type alias SendStateEventOutputV1 =
{ eventId : Maybe String }
type alias SendStateEventOutputV2 =
{ eventId : String }
sendStateEventV1 : SendStateEventInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
sendStateEventV1 { content, eventType, roomId, stateKey } =
A.request
{ attributes = [ R.accessToken, R.fullBody content ]
, coder = coderV1
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "r0", "rooms", roomId, "state", eventType, stateKey ]
, toUpdate =
\out ->
( E.More []
, out.eventId
|> Text.logs.sendEvent
|> log.debug
|> List.singleton
)
}
sendStateEventV2 : SendStateEventInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
sendStateEventV2 { content, eventType, roomId, stateKey } =
A.request
{ attributes = [ R.accessToken, R.fullBody content ]
, coder = coderV2
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "r0", "rooms", roomId, "state", eventType, stateKey ]
, toUpdate =
\out ->
( E.More []
, out.eventId
|> Maybe.Just
|> Text.logs.sendEvent
|> log.debug
|> List.singleton
)
}
sendStateEventV3 : SendStateEventInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
sendStateEventV3 { content, eventType, roomId, stateKey } =
A.request
{ attributes = [ R.accessToken, R.fullBody content ]
, coder = coderV2
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "v3", "rooms", roomId, "state", eventType, stateKey ]
, toUpdate =
\out ->
( E.More []
, out.eventId
|> Maybe.Just
|> Text.logs.sendEvent
|> log.debug
|> List.singleton
)
}
coderV1 : Json.Coder SendStateEventOutputV1
coderV1 =
Json.object1
{ name = "EventResponse"
, description =
[ "This object is returned after a state event has been sent."
]
, init = SendStateEventOutputV1
}
(Json.field.optional.value
{ fieldName = "event_id"
, toField = .eventId
, description = [ "A unique identifier for the event." ]
, coder = Json.string
}
)
coderV2 : Json.Coder SendStateEventOutputV2
coderV2 =
Json.object1
{ name = "EventResponse"
, description =
[ "This object is returned after a state event has been sent."
]
, init = SendStateEventOutputV2
}
(Json.field.required
{ fieldName = "event_id"
, toField = .eventId
, description = [ "A unique identifier for the event." ]
, coder = Json.string
}
)

View File

@ -1,107 +0,0 @@
module Internal.Api.SetAccountData.Api exposing (Phantom, setAccountData)
{-|
# Set Account Data
This module allows the developer to set global account data.
@docs Phantom, setAccountData
-}
import Internal.Api.Api as A
import Internal.Api.Request as R
import Internal.Config.Log exposing (log)
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Values.Envelope as E
import Internal.Values.Room as R
import Internal.Values.Vault as V
setAccountData : SetAccountDataInput -> A.TaskChain (Phantom a) (Phantom a)
setAccountData =
A.startWithVersion "r0.0.0" setAccountDataV1
|> A.sameForVersion "r0.0.1"
|> A.sameForVersion "r0.1.0"
|> A.sameForVersion "r0.2.0"
|> A.sameForVersion "r0.3.0"
|> A.sameForVersion "r0.4.0"
|> A.sameForVersion "r0.5.0"
|> A.sameForVersion "r0.6.0"
|> A.sameForVersion "r0.6.1"
|> A.forVersion "v1.1" setAccountDataV2
|> A.sameForVersion "v1.2"
|> A.sameForVersion "v1.3"
|> A.sameForVersion "v1.4"
|> A.sameForVersion "v1.5"
|> A.sameForVersion "v1.6"
|> A.sameForVersion "v1.7"
|> A.sameForVersion "v1.8"
|> A.sameForVersion "v1.9"
|> A.sameForVersion "v1.10"
|> A.sameForVersion "v1.11"
|> A.versionChain
{-| Context needed for setting global account data.
-}
type alias Phantom a =
{ a | accessToken : (), baseUrl : (), versions : () }
type alias PhantomV1 a =
{ a | accessToken : (), baseUrl : () }
type alias SetAccountDataInput =
{ content : Json.Value, eventType : String, userId : String }
type alias SetAccountDataInputV1 a =
{ a | content : Json.Value, eventType : String, userId : String }
type alias SetAccountDataOutput =
()
setAccountDataV1 : SetAccountDataInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
setAccountDataV1 { content, eventType, userId } =
A.request
{ attributes = [ R.accessToken, R.fullBody content ]
, coder = coderV1
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "r0", "user", userId, "account_data", eventType ]
, toUpdate =
\() ->
( V.SetAccountData eventType content
|> E.ContentUpdate
, []
)
}
setAccountDataV2 : SetAccountDataInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
setAccountDataV2 { content, eventType, userId } =
A.request
{ attributes = [ R.accessToken, R.fullBody content ]
, coder = coderV1
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "v3", "user", userId, "account_data", eventType ]
, toUpdate =
\() ->
( V.SetAccountData eventType content
|> E.ContentUpdate
, []
)
}
coderV1 : Json.Coder SetAccountDataOutput
coderV1 =
Json.unit

View File

@ -1,111 +0,0 @@
module Internal.Api.SetRoomAccountData.Api exposing (..)
{-|
# Set Room Account Data
This module allows the developer to set account data to a Matrix room.
@docs Phantom, setRoomAccountData
-}
import Internal.Api.Api as A
import Internal.Api.Request as R
import Internal.Config.Log exposing (log)
import Internal.Config.Text as Text
import Internal.Tools.Json as Json
import Internal.Values.Envelope as E
import Internal.Values.Room as R
import Internal.Values.Vault as V
{-| Set account data to a Matrix room.
-}
setRoomAccountData : SetRoomAccountDataInput -> A.TaskChain (Phantom a) (Phantom a)
setRoomAccountData =
A.startWithVersion "r0.0.0" setRoomAccountDataV1
|> A.sameForVersion "r0.0.1"
|> A.sameForVersion "r0.1.0"
|> A.sameForVersion "r0.2.0"
|> A.sameForVersion "r0.3.0"
|> A.sameForVersion "r0.4.0"
|> A.sameForVersion "r0.5.0"
|> A.sameForVersion "r0.6.0"
|> A.sameForVersion "r0.6.1"
|> A.forVersion "v1.1" setRoomAccountDataV2
|> A.sameForVersion "v1.2"
|> A.sameForVersion "v1.3"
|> A.sameForVersion "v1.4"
|> A.sameForVersion "v1.5"
|> A.sameForVersion "v1.6"
|> A.sameForVersion "v1.7"
|> A.sameForVersion "v1.8"
|> A.sameForVersion "v1.9"
|> A.sameForVersion "v1.10"
|> A.sameForVersion "v1.11"
|> A.versionChain
{-| Context needed for setting account data on a room.
-}
type alias Phantom a =
{ a | accessToken : (), baseUrl : (), versions : () }
type alias PhantomV1 a =
{ a | accessToken : (), baseUrl : () }
type alias SetRoomAccountDataInput =
{ content : Json.Value, eventType : String, roomId : String, userId : String }
type alias SetRoomAccountDataInputV1 a =
{ a | content : Json.Value, eventType : String, roomId : String, userId : String }
type alias SetRoomAccountDataOutputV1 =
()
setRoomAccountDataV1 : SetRoomAccountDataInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
setRoomAccountDataV1 { content, eventType, roomId, userId } =
A.request
{ attributes = [ R.accessToken, R.fullBody content ]
, coder = coderV1
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "r0", "user", userId, "rooms", roomId, "account_data", eventType ]
, toUpdate =
\() ->
( R.SetAccountData eventType content
|> V.MapRoom roomId
|> E.ContentUpdate
, []
)
}
setRoomAccountDataV2 : SetRoomAccountDataInputV1 i -> A.TaskChain (PhantomV1 a) (PhantomV1 a)
setRoomAccountDataV2 { content, eventType, roomId, userId } =
A.request
{ attributes = [ R.accessToken, R.fullBody content ]
, coder = coderV1
, contextChange = always identity
, method = "PUT"
, path = [ "_matrix", "client", "v3", "user", userId, "rooms", roomId, "account_data", eventType ]
, toUpdate =
\() ->
( R.SetAccountData eventType content
|> V.MapRoom roomId
|> E.ContentUpdate
, []
)
}
coderV1 : Json.Coder SetRoomAccountDataOutputV1
coderV1 =
Json.unit

View File

@ -106,7 +106,7 @@ syncV1 data =
, method = "GET" , method = "GET"
, path = [ "_matrix", "client", "v3", "sync" ] , path = [ "_matrix", "client", "v3", "sync" ]
, toUpdate = , toUpdate =
V1.updateSyncResponse { filter = Filter.pass, since = data.since } Debug.log "Handling output v1" >> V1.updateSyncResponse { filter = Filter.pass, since = data.since } >> Debug.log "Received"
} }
@ -128,7 +128,7 @@ syncV2 data =
, method = "GET" , method = "GET"
, path = [ "_matrix", "client", "v3", "sync" ] , path = [ "_matrix", "client", "v3", "sync" ]
, toUpdate = , toUpdate =
V2.updateSyncResponse { filter = Filter.pass, since = data.since } Debug.log "Handling output v2" >> V2.updateSyncResponse { filter = Filter.pass, since = data.since } >> Debug.log "Received"
} }
@ -150,7 +150,7 @@ syncV3 data =
, method = "GET" , method = "GET"
, path = [ "_matrix", "client", "v3", "sync" ] , path = [ "_matrix", "client", "v3", "sync" ]
, toUpdate = , toUpdate =
V3.updateSyncResponse { filter = Filter.pass, since = data.since } Debug.log "Handling output v3" >> V3.updateSyncResponse { filter = Filter.pass, since = data.since } >> Debug.log "Received"
} }
@ -172,5 +172,5 @@ syncV4 data =
, method = "GET" , method = "GET"
, path = [ "_matrix", "client", "v3", "sync" ] , path = [ "_matrix", "client", "v3", "sync" ]
, toUpdate = , toUpdate =
V4.updateSyncResponse { filter = Filter.pass, since = data.since } Debug.log "Handling output v4" >> V4.updateSyncResponse { filter = Filter.pass, since = data.since } >> Debug.log "Received"
} }

View File

@ -12,6 +12,7 @@ This API module represents the /sync endpoint on Matrix spec version v1.11.
-} -}
import FastDict as Dict exposing (Dict) import FastDict as Dict exposing (Dict)
import Internal.Api.Sync.V3 as PV
import Internal.Config.Log exposing (Log, log) import Internal.Config.Log exposing (Log, log)
import Internal.Config.Text as Text import Internal.Config.Text as Text
import Internal.Filter.Timeline exposing (Filter) import Internal.Filter.Timeline exposing (Filter)

View File

@ -1,6 +1,6 @@
module Internal.Api.Task exposing module Internal.Api.Task exposing
( Task, run, Backpack ( Task, run, Backpack
, banUser, inviteUser, kickUser, sendMessageEvent, sendStateEvent, setAccountData, setRoomAccountData, sync , sendMessageEvent, sync
) )
{-| {-|
@ -23,22 +23,16 @@ up-to-date.
## Tasks ## Tasks
@docs banUser, inviteUser, kickUser, sendMessageEvent, sendStateEvent, setAccountData, setRoomAccountData, sync @docs sendMessageEvent, sync
-} -}
import Internal.Api.BanUser.Api
import Internal.Api.BaseUrl.Api import Internal.Api.BaseUrl.Api
import Internal.Api.Chain as C import Internal.Api.Chain as C
import Internal.Api.InviteUser.Api
import Internal.Api.KickUser.Api
import Internal.Api.LoginWithUsernameAndPassword.Api import Internal.Api.LoginWithUsernameAndPassword.Api
import Internal.Api.Now.Api import Internal.Api.Now.Api
import Internal.Api.Request as Request import Internal.Api.Request as Request
import Internal.Api.SendMessageEvent.Api import Internal.Api.SendMessageEvent.Api
import Internal.Api.SendStateEvent.Api
import Internal.Api.SetAccountData.Api
import Internal.Api.SetRoomAccountData.Api
import Internal.Api.Sync.Api import Internal.Api.Sync.Api
import Internal.Api.Versions.Api import Internal.Api.Versions.Api
import Internal.Config.Log exposing (Log, log) import Internal.Config.Log exposing (Log, log)
@ -47,7 +41,6 @@ import Internal.Tools.Json as Json
import Internal.Values.Context as Context exposing (APIContext) import Internal.Values.Context as Context exposing (APIContext)
import Internal.Values.Envelope as E exposing (EnvelopeUpdate(..)) import Internal.Values.Envelope as E exposing (EnvelopeUpdate(..))
import Internal.Values.Room exposing (RoomUpdate(..)) import Internal.Values.Room exposing (RoomUpdate(..))
import Internal.Values.User exposing (User)
import Internal.Values.Vault exposing (VaultUpdate(..)) import Internal.Values.Vault exposing (VaultUpdate(..))
import Task import Task
@ -72,15 +65,6 @@ type alias UFTask a b =
C.TaskChain Request.Error (EnvelopeUpdate VaultUpdate) a b C.TaskChain Request.Error (EnvelopeUpdate VaultUpdate) a b
{-| Ban a user from a room.
-}
banUser : { reason : Maybe String, roomId : String, user : User } -> Task
banUser input =
makeVBA
|> C.andThen (Internal.Api.BanUser.Api.banUser input)
|> finishTask
{-| Get an access token to talk to the Matrix API {-| Get an access token to talk to the Matrix API
-} -}
getAccessToken : UFTask { a | baseUrl : (), now : (), versions : () } { a | accessToken : (), baseUrl : (), now : (), versions : () } getAccessToken : UFTask { a | baseUrl : (), now : (), versions : () } { a | accessToken : (), baseUrl : (), now : (), versions : () }
@ -220,31 +204,6 @@ finishTask uftask =
) )
{-| Invite a user to a room.
-}
inviteUser : { reason : Maybe String, roomId : String, user : User } -> Task
inviteUser input =
makeVBA
|> C.andThen (Internal.Api.InviteUser.Api.inviteUser input)
|> finishTask
{-| Kick a user from a room.
-}
kickUser :
{ avatarUrl : Maybe String
, displayname : Maybe String
, reason : Maybe String
, roomId : String
, user : User
}
-> Task
kickUser input =
makeVBA
|> C.andThen (Internal.Api.KickUser.Api.kickUser input)
|> finishTask
{-| Establish a Task Chain context where the base URL and supported list of {-| Establish a Task Chain context where the base URL and supported list of
versions are known. versions are known.
-} -}
@ -273,33 +232,6 @@ sendMessageEvent input =
|> finishTask |> finishTask
{-| Send a state event to a room.
-}
sendStateEvent : { content : Json.Value, eventType : String, roomId : String, stateKey : String } -> Task
sendStateEvent input =
makeVBA
|> C.andThen (Internal.Api.SendStateEvent.Api.sendStateEvent input)
|> finishTask
{-| Set global account data.
-}
setAccountData : { content : Json.Value, eventType : String, userId : String } -> Task
setAccountData input =
makeVBA
|> C.andThen (Internal.Api.SetAccountData.Api.setAccountData input)
|> finishTask
{-| Set account data for a Matrix room.
-}
setRoomAccountData : { content : Json.Value, eventType : String, roomId : String, userId : String } -> Task
setRoomAccountData input =
makeVBA
|> C.andThen (Internal.Api.SetRoomAccountData.Api.setRoomAccountData input)
|> finishTask
{-| Sync with the Matrix API to stay up-to-date. {-| Sync with the Matrix API to stay up-to-date.
-} -}
sync : { fullState : Maybe Bool, presence : Maybe String, since : Maybe String, timeout : Maybe Int } -> Task sync : { fullState : Maybe Bool, presence : Maybe String, since : Maybe String, timeout : Maybe Int } -> Task

View File

@ -29,7 +29,7 @@ will assume until overriden by the user.
-} -}
currentVersion : String currentVersion : String
currentVersion = currentVersion =
"beta 3.4.0" "beta 3.3.1"
{-| The default device name that is being communicated with the Matrix API. {-| The default device name that is being communicated with the Matrix API.

View File

@ -278,7 +278,6 @@ fields :
, serverName : Desc , serverName : Desc
, suggestedAccessToken : Desc , suggestedAccessToken : Desc
, transaction : Desc , transaction : Desc
, user : Desc
, versions : Desc , versions : Desc
} }
, envelope : , envelope :
@ -410,9 +409,6 @@ fields =
, transaction = , transaction =
[ "A unique identifier for a transaction initiated by the user." [ "A unique identifier for a transaction initiated by the user."
] ]
, user =
[ "The Matrix user the Vault is representing."
]
, versions = , versions =
[ "The versions of the Matrix protocol that are supported by the server." [ "The versions of the Matrix protocol that are supported by the server."
] ]

View File

@ -189,20 +189,21 @@ ipv6RightParser n =
|. P.symbol ":" |. P.symbol ":"
{-| Convert an IPv6 address to a readable string format
-}
ipv6ToString : IPv6Address -> String
ipv6ToString { front, back } =
(if List.length front == 8 then
front
-- {-| Convert an IPv6 address to a readable string format else if List.length back == 8 then
-- -} back
-- ipv6ToString : IPv6Address -> String
-- ipv6ToString { front, back } = else
-- (if List.length front == 8 then List.concat [ front, [ "" ], back ]
-- front )
-- else if List.length back == 8 then |> List.intersperse ":"
-- back |> String.concat
-- else
-- List.concat [ front, [ "" ], back ]
-- )
-- |> List.intersperse ":"
-- |> String.concat
portParser : Parser Int portParser : Parser Int

View File

@ -1,6 +1,6 @@
module Internal.Tools.DecodeExtra exposing module Internal.Tools.DecodeExtra exposing
( opField, opFieldWithDefault ( opField, opFieldWithDefault
, map9, map10, map11, map12, map13 , map9, map10, map11, map12
) )
{-| {-|
@ -18,7 +18,7 @@ This module contains helper functions that help decode JSON.
## Extended map functions ## Extended map functions
@docs map9, map10, map11, map12, map13 @docs map9, map10, map11, map12
-} -}
@ -185,36 +185,3 @@ map12 func da db dc dd de df dg dh di dj dk dl =
(D.map2 Tuple.pair dg dh) (D.map2 Tuple.pair dg dh)
(D.map2 Tuple.pair di dj) (D.map2 Tuple.pair di dj)
(D.map2 Tuple.pair dk dl) (D.map2 Tuple.pair dk dl)
{-| Try 12 decoders and combine the result.
-}
map13 :
(a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m -> value)
-> D.Decoder a
-> D.Decoder b
-> D.Decoder c
-> D.Decoder d
-> D.Decoder e
-> D.Decoder f
-> D.Decoder g
-> D.Decoder h
-> D.Decoder i
-> D.Decoder j
-> D.Decoder k
-> D.Decoder l
-> D.Decoder m
-> D.Decoder value
map13 func da db dc dd de df dg dh di dj dk dl dm =
D.map8
(\a b c ( d, e ) ( f, g ) ( h, i ) ( j, k ) ( l, m ) ->
func a b c d e f g h i j k l m
)
da
db
dc
(D.map2 Tuple.pair dd de)
(D.map2 Tuple.pair df dg)
(D.map2 Tuple.pair dh di)
(D.map2 Tuple.pair dj dk)
(D.map2 Tuple.pair dl dm)

View File

@ -1,11 +1,11 @@
module Internal.Tools.Json exposing module Internal.Tools.Json exposing
( Coder, string, bool, int, float, value, unit ( Coder, string, bool, int, float, value
, Encoder, encode, Decoder, decode, Value , Encoder, encode, Decoder, decode, Value
, succeed, fail, andThen, lazy, map , succeed, fail, andThen, lazy, map
, Docs(..), RequiredField(..), toDocs , Docs(..), RequiredField(..), toDocs
, list, listWithOne, slowDict, fastDict, fastIntDict, set, iddict, maybe , list, listWithOne, slowDict, fastDict, fastIntDict, set, iddict, maybe
, Field, field, parser , Field, field, parser
, object1, object2, object3, object4, object5, object6, object7, object8, object9, object10, object11, object12, object13 , object1, object2, object3, object4, object5, object6, object7, object8, object9, object10, object11, object12
) )
{-| {-|
@ -29,7 +29,7 @@ data types. Because this module uses dynamic builder types, this also means it
is relatively easy to write documentation for any data type that uses this is relatively easy to write documentation for any data type that uses this
module to build its encoders and decoders. module to build its encoders and decoders.
@docs Coder, string, bool, int, float, value, unit @docs Coder, string, bool, int, float, value
## JSON Coding ## JSON Coding
@ -62,7 +62,7 @@ first.
Once all fields are constructed, the user can create JSON objects. Once all fields are constructed, the user can create JSON objects.
@docs object1, object2, object3, object4, object5, object6, object7, object8, object9, object10, object11, object12, object13 @docs object1, object2, object3, object4, object5, object6, object7, object8, object9, object10, object11, object12
-} -}
@ -165,7 +165,6 @@ type Docs
| DocsRiskyMap (Descriptive { content : Docs, failure : List String }) | DocsRiskyMap (Descriptive { content : Docs, failure : List String })
| DocsSet Docs | DocsSet Docs
| DocsString | DocsString
| DocsUnit
| DocsValue | DocsValue
@ -478,14 +477,13 @@ iddict (Coder old) =
Coder Coder
{ encoder = Iddict.encode old.encoder { encoder = Iddict.encode old.encoder
, decoder = , decoder =
Iddict.decoder old.decoder D.andThen
|> D.map (\( out, logs ) ->
(\out -> D.succeed out
( Iddict.map (always Tuple.first) out |> Iddict.decoder
, Iddict.values out |> D.map (\o -> ( o, logs ))
|> List.concatMap Tuple.second
)
) )
old.decoder
, docs = DocsIddict old.docs , docs = DocsIddict old.docs
} }
@ -1273,85 +1271,6 @@ object12 { name, description, init } fa fb fc fd fe ff fg fh fi fj fk fl =
} }
{-| Define an object with 13 keys
-}
object13 :
Descriptive { init : a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m -> object }
-> Field a object
-> Field b object
-> Field c object
-> Field d object
-> Field e object
-> Field f object
-> Field g object
-> Field h object
-> Field i object
-> Field j object
-> Field k object
-> Field l object
-> Field m object
-> Coder object
object13 { name, description, init } fa fb fc fd fe ff fg fh fi fj fk fl fm =
Coder
{ encoder =
objectEncoder
[ toEncodeField fa
, toEncodeField fb
, toEncodeField fc
, toEncodeField fd
, toEncodeField fe
, toEncodeField ff
, toEncodeField fg
, toEncodeField fh
, toEncodeField fi
, toEncodeField fj
, toEncodeField fk
, toEncodeField fl
, toEncodeField fm
]
, decoder =
D.map13
(\( a, la ) ( b, lb ) ( c, lc ) ( d, ld ) ( e, le ) ( f, lf ) ( g, lg ) ( h, lh ) ( i, li ) ( j, lj ) ( k, lk ) ( l, ll ) ( m, lm ) ->
( init a b c d e f g h i j k l m
, List.concat [ la, lb, lc, ld, le, lf, lg, lh, li, lj, lk, ll, lm ]
)
)
(toDecoderField fa)
(toDecoderField fb)
(toDecoderField fc)
(toDecoderField fd)
(toDecoderField fe)
(toDecoderField ff)
(toDecoderField fg)
(toDecoderField fh)
(toDecoderField fi)
(toDecoderField fj)
(toDecoderField fk)
(toDecoderField fl)
(toDecoderField fm)
, docs =
DocsObject
{ name = name
, description = description
, keys =
[ toDocsField fa
, toDocsField fb
, toDocsField fc
, toDocsField fd
, toDocsField fe
, toDocsField ff
, toDocsField fg
, toDocsField fh
, toDocsField fi
, toDocsField fj
, toDocsField fk
, toDocsField fl
, toDocsField fm
]
}
}
{-| Define a parser that converts a string into a custom Elm type. {-| Define a parser that converts a string into a custom Elm type.
-} -}
parser : { name : String, p : P.Parser ( a, List Log ), toString : a -> String } -> Coder a parser : { name : String, p : P.Parser ( a, List Log ), toString : a -> String } -> Coder a
@ -1463,18 +1382,6 @@ toEncodeField (Field data) =
( data.fieldName, data.toField >> data.encoder ) ( data.fieldName, data.toField >> data.encoder )
{-| Completely ignore whatever needs to be encoded, and simply return a unit
value.
-}
unit : Coder ()
unit =
Coder
{ encoder = \() -> E.object []
, decoder = D.succeed ( (), [] )
, docs = DocsUnit
}
{-| Do not do anything useful with a JSON value, just bring it to Elm as a {-| Do not do anything useful with a JSON value, just bring it to Elm as a
JavaScript value. JavaScript value.
-} -}

View File

@ -71,7 +71,7 @@ import Internal.Config.Text as Text
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.Tools.Timestamp as Timestamp exposing (Timestamp) import Internal.Tools.Timestamp as Timestamp exposing (Timestamp)
import Internal.Values.User as User exposing (User) import Json.Encode as E
import Set exposing (Set) import Set exposing (Set)
import Time import Time
@ -102,7 +102,6 @@ type alias Context =
, serverName : String , serverName : String
, suggestedAccessToken : Maybe String , suggestedAccessToken : Maybe String
, transaction : Maybe String , transaction : Maybe String
, user : Maybe User
, username : Maybe String , username : Maybe String
, versions : Maybe Versions , versions : Maybe Versions
} }
@ -154,7 +153,7 @@ fromApiFormat (APIContext c) =
-} -}
coder : Json.Coder Context coder : Json.Coder Context
coder = coder =
Json.object13 Json.object12
{ name = Text.docs.context.name { name = Text.docs.context.name
, description = Text.docs.context.description , description = Text.docs.context.description
, init = Context , init = Context
@ -229,13 +228,6 @@ coder =
, coder = Json.string , coder = Json.string
} }
) )
(Json.field.optional.value
{ fieldName = "user"
, toField = .user
, description = Text.fields.context.user
, coder = User.coder
}
)
(Json.field.optional.value (Json.field.optional.value
{ fieldName = "username" { fieldName = "username"
, toField = .username , toField = .username
@ -314,8 +306,8 @@ encode =
{-| A basic, untouched version of the Context, containing no information. {-| A basic, untouched version of the Context, containing no information.
-} -}
init : String -> Maybe User -> Context init : String -> Context
init sn mu = init sn =
{ accessTokens = Hashdict.empty .value { accessTokens = Hashdict.empty .value
, baseUrl = Nothing , baseUrl = Nothing
, deviceId = Nothing , deviceId = Nothing
@ -326,7 +318,6 @@ init sn mu =
, serverName = sn , serverName = sn
, suggestedAccessToken = Nothing , suggestedAccessToken = Nothing
, transaction = Nothing , transaction = Nothing
, user = mu
, username = Nothing , username = Nothing
, versions = Nothing , versions = Nothing
} }

View File

@ -56,9 +56,6 @@ import Internal.Tools.Json as Json
import Internal.Tools.Timestamp exposing (Timestamp) import Internal.Tools.Timestamp exposing (Timestamp)
import Internal.Values.Context as Context exposing (AccessToken, Context, Versions) import Internal.Values.Context as Context exposing (AccessToken, Context, Versions)
import Internal.Values.Settings as Settings import Internal.Values.Settings as Settings
import Internal.Values.User exposing (User)
import Recursion
import Recursion.Fold
{-| There are lots of different data types in the Elm SDK, and many of them {-| There are lots of different data types in the Elm SDK, and many of them
@ -88,7 +85,6 @@ type EnvelopeUpdate a
| SetNextBatch String | SetNextBatch String
| SetNow Timestamp | SetNow Timestamp
| SetRefreshToken String | SetRefreshToken String
| SetUser User
| SetVersions Versions | SetVersions Versions
@ -190,10 +186,10 @@ getContent =
{-| Create a new enveloped data type. All settings are set to default values {-| Create a new enveloped data type. All settings are set to default values
from the [Internal.Config.Default](Internal-Config-Default) module. from the [Internal.Config.Default](Internal-Config-Default) module.
-} -}
init : { content : a, serverName : String, user : Maybe User } -> Envelope a init : { serverName : String, content : a } -> Envelope a
init data = init data =
{ content = data.content { content = data.content
, context = Context.init data.serverName data.user , context = Context.init data.serverName
, settings = Settings.init , settings = Settings.init
} }
@ -296,97 +292,50 @@ toMaybe data =
{-| Updates the Envelope with a given EnvelopeUpdate value. {-| Updates the Envelope with a given EnvelopeUpdate value.
-} -}
update : (au -> a -> a) -> EnvelopeUpdate au -> Envelope a -> Envelope a update : (au -> a -> a) -> EnvelopeUpdate au -> Envelope a -> Envelope a
update updateContent eu startData = update updateContent eu ({ context } as data) =
Recursion.runRecursion case eu of
(\updt ->
case updt of
ContentUpdate v -> ContentUpdate v ->
Recursion.base
(\data ->
{ data | content = updateContent v data.content } { data | content = updateContent v data.content }
)
HttpRequest _ -> HttpRequest _ ->
Recursion.base identity data
More items -> More items ->
Recursion.Fold.foldList (<<) identity items List.foldl (update updateContent) data items
Optional (Just u) -> Optional (Just u) ->
Recursion.recurse u update updateContent u data
Optional Nothing -> Optional Nothing ->
Recursion.base identity data
RemoveAccessToken token -> RemoveAccessToken token ->
Recursion.base { data | context = { context | accessTokens = Hashdict.removeKey token context.accessTokens } }
(\({ context } as data) ->
{ data
| context =
{ context
| accessTokens =
Hashdict.removeKey token context.accessTokens
}
}
)
RemovePasswordIfNecessary -> RemovePasswordIfNecessary ->
Recursion.base
(\({ context } as data) ->
if data.settings.removePasswordOnLogin then if data.settings.removePasswordOnLogin then
{ data | context = { context | password = Nothing } } { data | context = { context | password = Nothing } }
else else
data data
)
SetAccessToken a -> SetAccessToken a ->
Recursion.base
(\({ context } as data) ->
{ data | context = { context | accessTokens = Hashdict.insert a context.accessTokens } } { data | context = { context | accessTokens = Hashdict.insert a context.accessTokens } }
)
SetBaseUrl b -> SetBaseUrl b ->
Recursion.base
(\({ context } as data) ->
{ data | context = { context | baseUrl = Just b } } { data | context = { context | baseUrl = Just b } }
)
SetDeviceId d -> SetDeviceId d ->
Recursion.base
(\({ context } as data) ->
{ data | context = { context | deviceId = Just d } } { data | context = { context | deviceId = Just d } }
)
SetNextBatch nextBatch -> SetNextBatch nextBatch ->
Recursion.base
(\({ context } as data) ->
{ data | context = { context | nextBatch = Just nextBatch } } { data | context = { context | nextBatch = Just nextBatch } }
)
SetNow n -> SetNow n ->
Recursion.base
(\({ context } as data) ->
{ data | context = { context | now = Just n } } { data | context = { context | now = Just n } }
)
SetRefreshToken r -> SetRefreshToken r ->
Recursion.base
(\({ context } as data) ->
{ data | context = { context | refreshToken = Just r } } { data | context = { context | refreshToken = Just r } }
)
SetUser u ->
Recursion.base
(\({ context } as data) ->
{ data | context = { context | user = Just u } }
)
SetVersions vs -> SetVersions vs ->
Recursion.base
(\({ context } as data) ->
{ data | context = { context | versions = Just vs } } { data | context = { context | versions = Just vs } }
)
)
eu
startData

View File

@ -58,8 +58,7 @@ import Internal.Values.Event as Event exposing (Event)
import Internal.Values.StateManager as StateManager exposing (StateManager) import Internal.Values.StateManager as StateManager exposing (StateManager)
import Internal.Values.Timeline as Timeline exposing (Timeline) import Internal.Values.Timeline as Timeline exposing (Timeline)
import Internal.Values.User exposing (User) import Internal.Values.User exposing (User)
import Recursion import Json.Encode as E
import Recursion.Fold
{-| The Batch is a group of new events from somewhere in the timeline. {-| The Batch is a group of new events from somewhere in the timeline.
@ -256,35 +255,30 @@ setAccountData key value room =
{-| Update the Room based on given instructions. {-| Update the Room based on given instructions.
-} -}
update : RoomUpdate -> Room -> Room update : RoomUpdate -> Room -> Room
update roomUpdate startRoom = update ru room =
Recursion.runRecursion
(\ru ->
case ru of case ru of
AddEvent _ -> AddEvent _ ->
-- TODO: Add event -- TODO: Add event
Recursion.base identity room
AddSync batch -> AddSync batch ->
Recursion.base (addSync batch) addSync batch room
Invite _ -> Invite _ ->
-- TODO: Invite user -- TODO: Invite user
Recursion.base identity room
More items -> More items ->
Recursion.Fold.foldList (<<) identity items List.foldl update room items
Optional (Just u) -> Optional (Just u) ->
Recursion.recurse u update u room
Optional Nothing -> Optional Nothing ->
Recursion.base identity room
SetAccountData key value -> SetAccountData key value ->
Recursion.base (setAccountData key value) setAccountData key value room
SetEphemeral eph -> SetEphemeral eph ->
Recursion.base (\room -> { room | ephemeral = eph }) { room | ephemeral = eph }
)
roomUpdate
startRoom

View File

@ -678,21 +678,20 @@ mostRecentFrom filter timeline ptr =
{ ptr = ptr, visited = Set.empty } { ptr = ptr, visited = Set.empty }
{-| Recount the Timeline's amount of filled batches. Since the Timeline
-- {-| Recount the Timeline's amount of filled batches. Since the Timeline automatically tracks the count on itself, this is generally exclusively used in
-- automatically tracks the count on itself, this is generally exclusively used in specific scenarios like decoding JSON values.
-- specific scenarios like decoding JSON values. -}
-- -} recountFilledBatches : Timeline -> Timeline
-- recountFilledBatches : Timeline -> Timeline recountFilledBatches (Timeline tl) =
-- recountFilledBatches (Timeline tl) = Timeline
-- Timeline { tl
-- { tl | filledBatches =
-- | filledBatches = tl.batches
-- tl.batches |> Iddict.values
-- |> Iddict.values |> List.filter (\v -> v.events /= [])
-- |> List.filter (\v -> v.events /= []) |> List.length
-- |> List.length }
-- }
{-| Create a timeline with a single batch inserted. This batch is considered the {-| Create a timeline with a single batch inserted. This batch is considered the

View File

@ -1,9 +1,8 @@
module Internal.Values.Vault exposing module Internal.Values.Vault exposing
( Vault, init ( Vault, init
, VaultUpdate(..), update , VaultUpdate(..), update
, rooms, fromRoomId, mapRoom, updateRoom , fromRoomId, mapRoom, updateRoom
, getAccountData, setAccountData , getAccountData, setAccountData
, coder
) )
{-| This module hosts the Vault module. The Vault is the data type storing all {-| This module hosts the Vault module. The Vault is the data type storing all
@ -24,18 +23,13 @@ To update the Vault, one uses VaultUpdate types.
Rooms are environments where people can have a conversation with each other. Rooms are environments where people can have a conversation with each other.
@docs rooms, fromRoomId, mapRoom, updateRoom @docs fromRoomId, mapRoom, updateRoom
## Account data ## Account data
@docs getAccountData, setAccountData @docs getAccountData, setAccountData
## JSON
@docs coder
-} -}
import FastDict as Dict exposing (Dict) import FastDict as Dict exposing (Dict)
@ -44,8 +38,6 @@ import Internal.Tools.Hashdict as Hashdict exposing (Hashdict)
import Internal.Tools.Json as Json import Internal.Tools.Json as Json
import Internal.Values.Room as Room exposing (Room) import Internal.Values.Room as Room exposing (Room)
import Internal.Values.User as User exposing (User) import Internal.Values.User as User exposing (User)
import Recursion
import Recursion.Fold
{-| This is the Vault type. {-| This is the Vault type.
@ -54,6 +46,7 @@ type alias Vault =
{ accountData : Dict String Json.Value { accountData : Dict String Json.Value
, nextBatch : Maybe String , nextBatch : Maybe String
, rooms : Hashdict Room , rooms : Hashdict Room
, user : Maybe User
} }
@ -67,13 +60,12 @@ type VaultUpdate
| Optional (Maybe VaultUpdate) | Optional (Maybe VaultUpdate)
| SetAccountData String Json.Value | SetAccountData String Json.Value
| SetNextBatch String | SetNextBatch String
| SetUser User
{-| Convert a Vault to and from a JSON object.
-}
coder : Json.Coder Vault coder : Json.Coder Vault
coder = coder =
Json.object3 Json.object4
{ name = Text.docs.vault.name { name = Text.docs.vault.name
, description = Text.docs.vault.description , description = Text.docs.vault.description
, init = Vault , init = Vault
@ -99,6 +91,13 @@ coder =
, coder = Hashdict.coder .roomId Room.coder , coder = Hashdict.coder .roomId Room.coder
} }
) )
(Json.field.optional.value
{ fieldName = "user"
, toField = .user
, description = Text.fields.vault.user
, coder = User.coder
}
)
{-| Get a given room by its room id. {-| Get a given room by its room id.
@ -117,11 +116,12 @@ getAccountData key vault =
{-| Initiate a new Vault type. {-| Initiate a new Vault type.
-} -}
init : Vault init : Maybe User -> Vault
init = init mUser =
{ accountData = Dict.empty { accountData = Dict.empty
, nextBatch = Nothing , nextBatch = Nothing
, rooms = Hashdict.empty .roomId , rooms = Hashdict.empty .roomId
, user = mUser
} }
@ -133,13 +133,6 @@ mapRoom roomId f vault =
{ vault | rooms = Hashdict.map roomId f vault.rooms } { vault | rooms = Hashdict.map roomId f vault.rooms }
{-| Get a list of all joined rooms present in the vault.
-}
rooms : Vault -> List Room
rooms vault =
Hashdict.values vault.rooms
{-| Set a piece of account data as information in the global vault data. {-| Set a piece of account data as information in the global vault data.
-} -}
setAccountData : String -> Json.Value -> Vault -> Vault setAccountData : String -> Json.Value -> Vault -> Vault
@ -157,35 +150,30 @@ updateRoom roomId f vault =
{-| Update the Vault using a VaultUpdate type. {-| Update the Vault using a VaultUpdate type.
-} -}
update : VaultUpdate -> Vault -> Vault update : VaultUpdate -> Vault -> Vault
update vaultUpdate startVault = update vu vault =
Recursion.runRecursion
(\vu ->
case vu of case vu of
CreateRoomIfNotExists roomId -> CreateRoomIfNotExists roomId ->
updateRoom roomId
(Maybe.withDefault (Room.init roomId) >> Maybe.Just) (Maybe.withDefault (Room.init roomId) >> Maybe.Just)
|> updateRoom roomId vault
|> Recursion.base
MapRoom roomId ru -> MapRoom roomId ru ->
Recursion.base (mapRoom roomId (Room.update ru)) mapRoom roomId (Room.update ru) vault
More items -> More items ->
Recursion.Fold.foldList (<<) identity items List.foldl update vault items
Optional (Just u) -> Optional (Just u) ->
Recursion.recurse u update u vault
Optional Nothing -> Optional Nothing ->
Recursion.base identity vault
SetAccountData key value -> SetAccountData key value ->
Recursion.base (setAccountData key value) setAccountData key value vault
SetNextBatch nb -> SetNextBatch nb ->
Recursion.base
(\vault ->
{ vault | nextBatch = Just nb } { vault | nextBatch = Just nb }
)
) SetUser user ->
vaultUpdate { vault | user = Just user }
startVault

View File

@ -1,8 +1,6 @@
module Matrix exposing module Matrix exposing
( Vault, fromUserId, fromUsername ( Vault, fromUserId, fromUsername
, VaultUpdate, update, sync, logs , VaultUpdate, update, sync, logs
, rooms, fromRoomId
, getAccountData, setAccountData
, addAccessToken, sendMessageEvent , addAccessToken, sendMessageEvent
) )
@ -29,16 +27,6 @@ support a monolithic public registry. (:
@docs VaultUpdate, update, sync, logs @docs VaultUpdate, update, sync, logs
## Exploring the Vault
@docs rooms, fromRoomId
## Account data
@docs getAccountData, setAccountData
## Debugging ## Debugging
@docs addAccessToken, sendMessageEvent @docs addAccessToken, sendMessageEvent
@ -78,21 +66,6 @@ addAccessToken token (Vault vault) =
|> Vault |> Vault
{-| Get a room based on its room ID, if the user is a member of that room.
-}
fromRoomId : String -> Vault -> Maybe Types.Room
fromRoomId roomId (Vault vault) =
Envelope.mapMaybe (Internal.fromRoomId roomId) vault
|> Maybe.map Types.Room
{-| Get global account data.
-}
getAccountData : String -> Vault -> Maybe E.Value
getAccountData key (Vault vault) =
Envelope.extract (Internal.getAccountData key) vault
{-| Use a fully-fledged Matrix ID to connect. {-| Use a fully-fledged Matrix ID to connect.
case Matrix.fromUserId "@alice:example.org" of case Matrix.fromUserId "@alice:example.org" of
@ -110,9 +83,8 @@ fromUserId uid =
|> Maybe.map |> Maybe.map
(\u -> (\u ->
Envelope.init Envelope.init
{ content = Internal.init { serverName = "https://" ++ User.domain u
, serverName = "https://" ++ User.domain u , content = Internal.init (Just u)
, user = Just u
} }
|> Envelope.mapContext (\c -> { c | username = Just uid }) |> Envelope.mapContext (\c -> { c | username = Just uid })
) )
@ -127,28 +99,19 @@ you can either insert `alice` or `@alice:example.org`.
-} -}
fromUsername : { username : String, host : String, port_ : Maybe Int } -> Vault fromUsername : { username : String, host : String, port_ : Maybe Int } -> Vault
fromUsername { username, host, port_ } = fromUsername { username, host, port_ } =
{ content = Internal.init { serverName =
, serverName =
port_ port_
|> Maybe.map String.fromInt |> Maybe.map String.fromInt
|> Maybe.map ((++) ":") |> Maybe.map ((++) ":")
|> Maybe.withDefault "" |> Maybe.withDefault ""
|> (++) host |> (++) host
, user = User.fromString username , content = Internal.init (User.fromString username)
} }
|> Envelope.init |> Envelope.init
|> Envelope.mapContext (\c -> { c | username = Just username }) |> Envelope.mapContext (\c -> { c | username = Just username })
|> Vault |> Vault
{-| Get a list of all the rooms that the user has joined.
-}
rooms : Vault -> List Types.Room
rooms (Vault vault) =
Envelope.mapList Internal.rooms vault
|> List.map Types.Room
{-| The VaultUpdate is a complex type that helps update the Vault. However, {-| The VaultUpdate is a complex type that helps update the Vault. However,
it also contains a human output! it also contains a human output!
@ -212,25 +175,6 @@ sendMessageEvent data =
} }
{-| Set global account data.
-}
setAccountData :
{ content : E.Value
, eventType : String
, room : Vault
, toMsg : Types.VaultUpdate -> msg
}
-> Cmd msg
setAccountData data =
case data.room of
Vault vault ->
Api.setAccountData vault
{ content = data.content
, eventType = data.eventType
, toMsg = Types.VaultUpdate >> data.toMsg
}
{-| Synchronize the Vault with the Matrix API. {-| Synchronize the Vault with the Matrix API.
Effectively, this task asks the Matrix API to provide the latest information, Effectively, this task asks the Matrix API to provide the latest information,

View File

@ -1,8 +1,6 @@
module Matrix.Room exposing module Matrix.Room exposing
( Room, mostRecentEvents, roomId ( Room, mostRecentEvents
, getAccountData, setAccountData , getAccountData
, sendMessageEvent, sendStateEvent
, invite, kick, ban
) )
{-| {-|
@ -14,7 +12,7 @@ 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 other platforms, the term used in Matrix is a "room". A room is a conversation
where a group of users talk to each other. where a group of users talk to each other.
@docs Room, mostRecentEvents, roomId @docs Room, mostRecentEvents
This module exposes various functions that help you inspect various aspects of This module exposes various functions that help you inspect various aspects of
a room. a room.
@ -35,26 +33,10 @@ 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 data too, as the server synchronizes it, but the server shouldn´t show it to
other users. other users.
@docs getAccountData, setAccountData @docs getAccountData
## Sending events
Besides reading the latest events, one can also send new events to the Matrix
room. These events are JSON objects that can be shaped in any way or form that
you like. To help other users with decoding your JSON objects, you pass an
`eventType` string which helps them figure out the nature of your JSON object.
@docs inviteUser, sendMessageEvent, sendStateEvent
## Moderating users
@docs invite, kick, ban
-} -}
import Internal.Api.Main as Api
import Internal.Values.Envelope as Envelope import Internal.Values.Envelope as Envelope
import Internal.Values.Room as Internal import Internal.Values.Room as Internal
import Json.Encode as E import Json.Encode as E
@ -67,26 +49,6 @@ type alias Room =
Types.Room Types.Room
{-| Ban a user from a room.
-}
ban :
{ reason : Maybe String
, room : Room
, toMsg : Types.VaultUpdate -> msg
, user : Types.User
}
-> Cmd msg
ban data =
case ( data.room, data.user ) of
( Room room, Types.User user ) ->
Api.kickUser room
{ reason = data.reason
, roomId = roomId data.room
, toMsg = Types.VaultUpdate >> data.toMsg
, user = Envelope.getContent user
}
{-| Get a piece of account data linked to a certain string key. {-| Get a piece of account data linked to a certain string key.
-} -}
getAccountData : String -> Room -> Maybe E.Value getAccountData : String -> Room -> Maybe E.Value
@ -94,121 +56,9 @@ getAccountData key (Room room) =
Envelope.extract (Internal.getAccountData key) room Envelope.extract (Internal.getAccountData key) room
{-| Invite a user to a room.
-}
invite :
{ reason : Maybe String
, room : Room
, toMsg : Types.VaultUpdate -> msg
, user : Types.User
}
-> Cmd msg
invite data =
case ( data.room, data.user ) of
( Room room, Types.User user ) ->
Api.inviteUser room
{ reason = data.reason
, roomId = roomId data.room
, toMsg = Types.VaultUpdate >> data.toMsg
, user = Envelope.getContent user
}
{-| Kick a user from a room.
-}
kick :
{ reason : Maybe String
, room : Room
, toMsg : Types.VaultUpdate -> msg
, user : Types.User
}
-> Cmd msg
kick data =
case ( data.room, data.user ) of
( Room room, Types.User user ) ->
Api.kickUser room
{ reason = data.reason
, roomId = roomId data.room
, toMsg = Types.VaultUpdate >> data.toMsg
, user = Envelope.getContent user
}
{-| Get a room's room id. This is an opaque string that distinguishes rooms from
each other.
-}
roomId : Room -> String
roomId (Room room) =
Envelope.extract .roomId room
{-| Get a list of the most recent events sent in the room. {-| Get a list of the most recent events sent in the room.
-} -}
mostRecentEvents : Room -> List Types.Event mostRecentEvents : Room -> List Types.Event
mostRecentEvents (Room room) = mostRecentEvents (Room room) =
Envelope.mapList Internal.mostRecentEvents room Envelope.mapList Internal.mostRecentEvents room
|> List.map Types.Event |> List.map Types.Event
{-| Send a message event to a given room.
-}
sendMessageEvent :
{ content : E.Value
, eventType : String
, room : Room
, toMsg : Types.VaultUpdate -> msg
, transactionId : String
}
-> Cmd msg
sendMessageEvent data =
case data.room of
Room room ->
Api.sendMessageEvent room
{ content = data.content
, eventType = data.eventType
, roomId = roomId data.room
, toMsg = Types.VaultUpdate >> data.toMsg
, transactionId = data.transactionId
}
{-| Send a state event to a given room.
-}
sendStateEvent :
{ content : E.Value
, eventType : String
, room : Room
, stateKey : String
, toMsg : Types.VaultUpdate -> msg
}
-> Cmd msg
sendStateEvent data =
case data.room of
Room room ->
Api.sendStateEvent room
{ content = data.content
, eventType = data.eventType
, roomId = roomId data.room
, stateKey = data.stateKey
, toMsg = Types.VaultUpdate >> data.toMsg
}
{-| Set account data to a Matrix room.
-}
setAccountData :
{ content : E.Value
, eventType : String
, room : Room
, toMsg : Types.VaultUpdate -> msg
}
-> Cmd msg
setAccountData data =
case data.room of
Room room ->
Api.setRoomAccountData room
{ content = data.content
, eventType = data.eventType
, roomId = roomId data.room
, toMsg = Types.VaultUpdate >> data.toMsg
}

View File

@ -5,10 +5,11 @@ import Fuzz exposing (Fuzzer)
import Internal.Config.Leaks as Leaks import Internal.Config.Leaks as Leaks
import Internal.Tools.Hashdict as Hashdict import Internal.Tools.Hashdict as Hashdict
import Internal.Values.Context as Context exposing (Context, Versions) import Internal.Values.Context as Context exposing (Context, Versions)
import Json.Decode as D
import Json.Encode as E
import Set import Set
import Test exposing (..) import Test exposing (..)
import Test.Tools.Timestamp as TestTimestamp import Test.Tools.Timestamp as TestTimestamp
import Test.Values.User as TestUser
fuzzer : Fuzzer Context fuzzer : Fuzzer Context
@ -18,25 +19,19 @@ fuzzer =
maybeString = maybeString =
Fuzz.maybe Fuzz.string Fuzz.maybe Fuzz.string
in in
Fuzz.map8 (\a b c ( d, e ) ( f, g ) ( h, i ) ( j, k ) ( l, m ) -> Context a b c d e f g h i j k l m) Fuzz.map8 (\a b c d e ( f, g ) ( h, i ) ( j, k ) -> Context a b c d e f g h i j k)
(Fuzz.constant <| Hashdict.empty .value) (Fuzz.constant <| Hashdict.empty .value)
maybeString maybeString
maybeString
(Fuzz.pair
maybeString maybeString
(Fuzz.maybe TestTimestamp.fuzzer) (Fuzz.maybe TestTimestamp.fuzzer)
) maybeString
(Fuzz.pair (Fuzz.pair
maybeString maybeString
maybeString
)
(Fuzz.pair
Fuzz.string Fuzz.string
maybeString
) )
(Fuzz.pair (Fuzz.pair
maybeString maybeString
(Fuzz.maybe TestUser.fuzzer) maybeString
) )
(Fuzz.pair (Fuzz.pair
maybeString maybeString

View File

@ -3,7 +3,10 @@ module Test.Values.Envelope exposing (..)
import Expect import Expect
import Fuzz exposing (Fuzzer) import Fuzz exposing (Fuzzer)
import Internal.Config.Default as Default import Internal.Config.Default as Default
import Internal.Tools.Json as Json
import Internal.Values.Envelope as Envelope exposing (Envelope) import Internal.Values.Envelope as Envelope exposing (Envelope)
import Json.Decode as D
import Json.Encode as E
import Test exposing (..) import Test exposing (..)
import Test.Values.Context as TestContext import Test.Values.Context as TestContext
import Test.Values.Settings as TestSettings import Test.Values.Settings as TestSettings
@ -25,7 +28,7 @@ suite =
[ fuzz Fuzz.string [ fuzz Fuzz.string
"currentVersion" "currentVersion"
(\s -> (\s ->
{ content = s, serverName = "", user = Nothing } { content = s, serverName = "" }
|> Envelope.init |> Envelope.init
|> Envelope.extractSettings .currentVersion |> Envelope.extractSettings .currentVersion
|> Expect.equal Default.currentVersion |> Expect.equal Default.currentVersion
@ -33,7 +36,7 @@ suite =
, fuzz Fuzz.string , fuzz Fuzz.string
"deviceName" "deviceName"
(\s -> (\s ->
{ content = s, serverName = "", user = Nothing } { content = s, serverName = "" }
|> Envelope.init |> Envelope.init
|> Envelope.extractSettings .deviceName |> Envelope.extractSettings .deviceName
|> Expect.equal Default.deviceName |> Expect.equal Default.deviceName
@ -41,7 +44,7 @@ suite =
, fuzz Fuzz.string , fuzz Fuzz.string
"syncTime" "syncTime"
(\s -> (\s ->
{ content = s, serverName = "", user = Nothing } { content = s, serverName = "" }
|> Envelope.init |> Envelope.init
|> Envelope.extractSettings .syncTime |> Envelope.extractSettings .syncTime
|> Expect.equal Default.syncTime |> Expect.equal Default.syncTime

View File

@ -41,18 +41,16 @@ fuzzerState =
unsignedDataFuzzer : Fuzzer Event.UnsignedData unsignedDataFuzzer : Fuzzer Event.UnsignedData
unsignedDataFuzzer = unsignedDataFuzzer =
Fuzz.map5 Fuzz.map4
(\age memb prev redact trans -> (\age prev redact trans ->
Event.UnsignedData Event.UnsignedData
{ age = age { age = age
, membership = memb
, prevContent = prev , prevContent = prev
, redactedBecause = redact , redactedBecause = redact
, transactionId = trans , transactionId = trans
} }
) )
(Fuzz.maybe Fuzz.int) (Fuzz.maybe Fuzz.int)
(Fuzz.maybe Fuzz.string)
(Fuzz.maybe valueFuzzer) (Fuzz.maybe valueFuzzer)
(Fuzz.maybe <| Fuzz.lazy (\_ -> fuzzer)) (Fuzz.maybe <| Fuzz.lazy (\_ -> fuzzer))
(Fuzz.maybe Fuzz.string) (Fuzz.maybe Fuzz.string)

View File

@ -4,6 +4,8 @@ import Fuzz exposing (Fuzzer)
import Internal.Values.Room as Room exposing (Room) import Internal.Values.Room as Room exposing (Room)
import Json.Encode as E import Json.Encode as E
import Test exposing (..) import Test exposing (..)
import Test.Filter.Timeline as TestFilter
import Test.Values.Event as TestEvent
placeholderValue : E.Value placeholderValue : E.Value

View File

@ -11,7 +11,7 @@ import Test exposing (..)
fuzzer : Fuzzer Settings fuzzer : Fuzzer Settings
fuzzer = fuzzer =
Fuzz.map5 Settings Fuzz.map4 Settings
(Fuzz.oneOf (Fuzz.oneOf
[ Fuzz.constant Default.currentVersion [ Fuzz.constant Default.currentVersion
, Fuzz.string , Fuzz.string
@ -22,7 +22,6 @@ fuzzer =
, Fuzz.string , Fuzz.string
] ]
) )
(Fuzz.maybe Fuzz.string)
(Fuzz.oneOf (Fuzz.oneOf
[ Fuzz.constant Default.removePasswordOnLogin [ Fuzz.constant Default.removePasswordOnLogin
, Fuzz.bool , Fuzz.bool

View File

@ -6,7 +6,6 @@ import Internal.Filter.Timeline as Filter
import Internal.Tools.Json as Json import Internal.Tools.Json as Json
import Internal.Values.Timeline as Timeline exposing (Batch, Timeline) import Internal.Values.Timeline as Timeline exposing (Batch, Timeline)
import Json.Decode as D import Json.Decode as D
import Json.Encode as E
import Test exposing (..) import Test exposing (..)
import Test.Filter.Timeline as TestFilter import Test.Filter.Timeline as TestFilter
@ -251,8 +250,7 @@ suite =
(\timeline -> (\timeline ->
timeline timeline
|> Json.encode Timeline.coder |> Json.encode Timeline.coder
|> E.encode 0 |> D.decodeValue (Json.decode Timeline.coder)
|> D.decodeString (Json.decode Timeline.coder)
|> Result.map Tuple.first |> Result.map Tuple.first
|> Result.map (Timeline.mostRecentEvents Filter.pass) |> Result.map (Timeline.mostRecentEvents Filter.pass)
|> Expect.equal (Ok <| Timeline.mostRecentEvents Filter.pass timeline) |> Expect.equal (Ok <| Timeline.mostRecentEvents Filter.pass timeline)

View File

@ -7,11 +7,12 @@ import Internal.Values.Vault exposing (Vault)
import Test exposing (..) import Test exposing (..)
import Test.Tools.Hashdict as TestHashdict import Test.Tools.Hashdict as TestHashdict
import Test.Values.Room as TestRoom import Test.Values.Room as TestRoom
import Test.Values.User as TestUser
vault : Fuzzer Vault vault : Fuzzer Vault
vault = vault =
Fuzz.map3 Vault Fuzz.map4 Vault
(Fuzz.string (Fuzz.string
|> Fuzz.map (\k -> ( k, Json.encode Json.int 0 )) |> Fuzz.map (\k -> ( k, Json.encode Json.int 0 ))
|> Fuzz.list |> Fuzz.list
@ -19,3 +20,4 @@ vault =
) )
(Fuzz.maybe Fuzz.string) (Fuzz.maybe Fuzz.string)
(TestHashdict.fuzzer .roomId TestRoom.fuzzer) (TestHashdict.fuzzer .roomId TestRoom.fuzzer)
(Fuzz.maybe TestUser.fuzzer)