Compare commits
No commits in common. "3b927dc46008a062ef9903be8b93225325cd2e69" and "7c7e05d42a9fbf582538cefe16239cfdcd78c2bd" have entirely different histories.
3b927dc460
...
7c7e05d42a
|
@ -2,5 +2,3 @@
|
||||||
elm-stuff
|
elm-stuff
|
||||||
# elm-repl generated files
|
# elm-repl generated files
|
||||||
repl-temp-*
|
repl-temp-*
|
||||||
# VScode settings
|
|
||||||
.vscode/
|
|
||||||
|
|
|
@ -32,8 +32,3 @@ elm install noordstar/elm-matrix-sdk-beta
|
||||||
Keep in mind that the beta versions are intended to develop rapidly. You should
|
Keep in mind that the beta versions are intended to develop rapidly. You should
|
||||||
not expect the versions to remain reliable for years! If you need a stable
|
not expect the versions to remain reliable for years! If you need a stable
|
||||||
version, please wait around for a full version.
|
version, please wait around for a full version.
|
||||||
|
|
||||||
## Contribute
|
|
||||||
|
|
||||||
If you wish to contribute, please read the
|
|
||||||
[contribution guide](docs/CONTRIBUTING.md).
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
# Contributing to elm-matrix-sdk-beta
|
|
||||||
|
|
||||||
Welcome to the elm-matrix-sdk-beta repository! We appreciate your interest in
|
|
||||||
contributing. Please take a moment to review the following guidelines.
|
|
||||||
|
|
||||||
## Table of Contents
|
|
||||||
|
|
||||||
1. [How to Contribute](#how-to-contribute)
|
|
||||||
2. [Bug Reports](#bug-reports)
|
|
||||||
3. [Code Contributions](#code-contributions)
|
|
||||||
4. [Documentation Improvements](#documentation-improvements)
|
|
||||||
5. [Feedback and Tips](#feedback-and-tips)
|
|
||||||
6. [Development Environment](#development-environment)
|
|
||||||
7. [Pull Requests](#pull-requests)
|
|
||||||
8. [Communication](#communication)
|
|
||||||
9. [License](#license)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## How to Contribute
|
|
||||||
|
|
||||||
We welcome various forms of contributions, including bug reports, code
|
|
||||||
contributions through pull requests from forks, suggestions for documentation
|
|
||||||
improvement, and helpful tips and feedback based on user experience.
|
|
||||||
|
|
||||||
## Bug Reports
|
|
||||||
|
|
||||||
When reporting bugs, please provide as much detail as possible, including steps
|
|
||||||
to reproduce, expected behavior, actual behavior, and details about your
|
|
||||||
environment.
|
|
||||||
|
|
||||||
## Code Contributions
|
|
||||||
|
|
||||||
1. Fork the repository.
|
|
||||||
2. Create a new branch from the `develop` branch.
|
|
||||||
3. Write your code and commit changes.
|
|
||||||
4. Push your branch to your fork.
|
|
||||||
5. Submit a pull request to the `develop` branch.
|
|
||||||
|
|
||||||
## Documentation Improvements
|
|
||||||
|
|
||||||
Feel free to suggest improvements to the documentation. Ensure that your
|
|
||||||
suggestions are clear and concise.
|
|
||||||
|
|
||||||
## Feedback and Tips
|
|
||||||
|
|
||||||
We appreciate feedback, tips, and suggestions based on user experience. Share
|
|
||||||
your thoughts to help us enhance the project.
|
|
||||||
|
|
||||||
## Development Environment
|
|
||||||
|
|
||||||
To set up your development environment:
|
|
||||||
|
|
||||||
1. Install Elm.
|
|
||||||
2. Use `elm-format` to format your Elm code.
|
|
||||||
3. Run `elm make --docs=docs.json` to generate documentation.
|
|
||||||
4. View documentation using an Elm documentation viewer (e.g., [elm-doc-preview](https://elm-doc-preview.netlify.app/)).
|
|
||||||
5. Expose modules in `elm.json` for documentation.
|
|
||||||
|
|
||||||
## Pull Requests
|
|
||||||
|
|
||||||
Create a fork, write your code, and submit a pull request to the `develop` branch.
|
|
||||||
|
|
||||||
## Communication
|
|
||||||
|
|
||||||
- Mastodon: [@elm_matrix_sdk@social.noordstar.me](https://social.noordstar.me/@elm_matrix_sdk)
|
|
||||||
- Matrix: [#elm-sdk:matrix.org](https://matrix.to/#/#elm-sdk:matrix.org)
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is licensed under the [EUPL-v1.2](LICENSE). Please review the license file for more details.
|
|
|
@ -1,29 +0,0 @@
|
||||||
# Before merging to main
|
|
||||||
|
|
||||||
⚠️ **Hold up!** Before you merge that pull request, make sure to follow this checklist!
|
|
||||||
|
|
||||||
## Any branch to `develop`
|
|
||||||
|
|
||||||
If you wish to merge your branch to the `develop` branch, make sure to follow this checklist:
|
|
||||||
|
|
||||||
- [ ] Run `elm-format` to ensure the correct formatting of the Elm files.
|
|
||||||
- [ ] Use `elm-doc-preview` to verify whether the documentation is up to standards.
|
|
||||||
|
|
||||||
## The `develop` branch to `main`
|
|
||||||
|
|
||||||
The `develop` branch is the only branch that's allowed to merge to `main`. Once the branch merges to `main`, that indicates a new release on the Elm registry.
|
|
||||||
|
|
||||||
Before that is being done, however, the following tasks should be done:
|
|
||||||
|
|
||||||
- [ ] Run `elm-format` to ensure the correct formatting of the Elm files.
|
|
||||||
- [ ] Use `elm-doc-preview` to verify whether the documentation is up to standards.
|
|
||||||
- [ ] Remove exposed modules from `elm.json` that do not need to be exposed modules in the release.
|
|
||||||
- [ ] Run `elm bump` to update the library's version number
|
|
||||||
- [ ] Update the version name in the [default values config file](../src/Internal/Config/Default.elm).
|
|
||||||
|
|
||||||
## Any branch to any other branch
|
|
||||||
|
|
||||||
There are no limitations to merging other branches towards one another, although it is important to keep in mind that:
|
|
||||||
|
|
||||||
- Contributors are advised to merge the `develop` branch into their branches regularly to avoid any merge conflicts.
|
|
||||||
- Merging with branches that haven't been accepted (yet) might result in your branch ending up with code that will not be accepted.
|
|
8
elm.json
8
elm.json
|
@ -6,18 +6,12 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"exposed-modules": [
|
"exposed-modules": [
|
||||||
"Matrix",
|
"Matrix",
|
||||||
"Matrix.Settings",
|
|
||||||
"Internal.Config.Default",
|
"Internal.Config.Default",
|
||||||
"Internal.Config.Text",
|
"Internal.Config.Text",
|
||||||
"Internal.Tools.Decode",
|
|
||||||
"Internal.Tools.Encode",
|
|
||||||
"Internal.Tools.Hashdict",
|
"Internal.Tools.Hashdict",
|
||||||
"Internal.Tools.Iddict",
|
"Internal.Tools.Iddict",
|
||||||
"Internal.Tools.Timestamp",
|
"Internal.Tools.Timestamp",
|
||||||
"Internal.Tools.VersionControl",
|
"Internal.Tools.VersionControl"
|
||||||
"Internal.Values.Envelope",
|
|
||||||
"Internal.Values.Vault",
|
|
||||||
"Types"
|
|
||||||
],
|
],
|
||||||
"elm-version": "0.19.0 <= v < 0.20.0",
|
"elm-version": "0.19.0 <= v < 0.20.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -42,7 +42,7 @@ the Elm SDK tolerates being held on hold.
|
||||||
|
|
||||||
- ↗️ A high value is good because it significantly reduces traffic between the
|
- ↗️ A high value is good because it significantly reduces traffic between the
|
||||||
user and the homeserver.
|
user and the homeserver.
|
||||||
- ↘️ A low value is good because it reduces the risk of
|
- ↘️ A low value is good because it refuces the risk of
|
||||||
the connection ending abruptly or unexpectedly.
|
the connection ending abruptly or unexpectedly.
|
||||||
|
|
||||||
Nowadays, most libraries use 30 seconds as the standard, as does the Elm SDK.
|
Nowadays, most libraries use 30 seconds as the standard, as does the Elm SDK.
|
||||||
|
|
|
@ -1,155 +0,0 @@
|
||||||
module Internal.Tools.Decode exposing
|
|
||||||
( opField, opFieldWithDefault
|
|
||||||
, map9, map10, map11
|
|
||||||
)
|
|
||||||
|
|
||||||
{-|
|
|
||||||
|
|
||||||
|
|
||||||
# Decode module
|
|
||||||
|
|
||||||
This module contains helper functions that help decode JSON.
|
|
||||||
|
|
||||||
|
|
||||||
## Optional field decoders
|
|
||||||
|
|
||||||
@docs opField, opFieldWithDefault
|
|
||||||
|
|
||||||
|
|
||||||
## Extended map functions
|
|
||||||
|
|
||||||
@docs map9, map10, map11
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
import Json.Decode as D
|
|
||||||
|
|
||||||
|
|
||||||
{-| Add an optional field decoder. If the field exists, the decoder will fail
|
|
||||||
if the field doesn't decode properly.
|
|
||||||
|
|
||||||
This decoder standard out from `D.maybe <| D.field fieldName decoder` because
|
|
||||||
that will decode into a `Nothing` if the `decoder` fails. This function will
|
|
||||||
only decode into a `Nothing` if the field doesn't exist, and will fail if
|
|
||||||
`decoder` fails.
|
|
||||||
|
|
||||||
The function also returns Nothing if the field exists but it is null.
|
|
||||||
|
|
||||||
-}
|
|
||||||
opField : String -> D.Decoder a -> D.Decoder (Maybe a)
|
|
||||||
opField fieldName decoder =
|
|
||||||
D.value
|
|
||||||
|> D.field fieldName
|
|
||||||
|> D.maybe
|
|
||||||
|> D.andThen
|
|
||||||
(\v ->
|
|
||||||
case v of
|
|
||||||
Just _ ->
|
|
||||||
D.oneOf
|
|
||||||
[ D.null Nothing
|
|
||||||
, D.map Just decoder
|
|
||||||
]
|
|
||||||
|> D.field fieldName
|
|
||||||
|
|
||||||
Nothing ->
|
|
||||||
D.succeed Nothing
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Add an optional field decoder. If the field is not given, the decoder will
|
|
||||||
return a default value. If the field exists, the decoder will fail if the field
|
|
||||||
doesn't decode properly.
|
|
||||||
-}
|
|
||||||
opFieldWithDefault : String -> a -> D.Decoder a -> D.Decoder a
|
|
||||||
opFieldWithDefault fieldName default decoder =
|
|
||||||
opField fieldName decoder |> D.map (Maybe.withDefault default)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Try 9 decoders and combine the result.
|
|
||||||
-}
|
|
||||||
map9 :
|
|
||||||
(a -> b -> c -> d -> e -> f -> g -> h -> i -> 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 value
|
|
||||||
map9 func da db dc dd de df dg dh di =
|
|
||||||
D.map8
|
|
||||||
(\a b c d e f g ( h, i ) ->
|
|
||||||
func a b c d e f g h i
|
|
||||||
)
|
|
||||||
da
|
|
||||||
db
|
|
||||||
dc
|
|
||||||
dd
|
|
||||||
de
|
|
||||||
df
|
|
||||||
dg
|
|
||||||
(D.map2 Tuple.pair dh di)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Try 10 decoders and combine the result.
|
|
||||||
-}
|
|
||||||
map10 :
|
|
||||||
(a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> 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 value
|
|
||||||
map10 func da db dc dd de df dg dh di dj =
|
|
||||||
D.map8
|
|
||||||
(\a b c d e f ( g, h ) ( i, j ) ->
|
|
||||||
func a b c d e f g h i j
|
|
||||||
)
|
|
||||||
da
|
|
||||||
db
|
|
||||||
dc
|
|
||||||
dd
|
|
||||||
de
|
|
||||||
df
|
|
||||||
(D.map2 Tuple.pair dg dh)
|
|
||||||
(D.map2 Tuple.pair di dj)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Try 11 decoders and combine the result.
|
|
||||||
-}
|
|
||||||
map11 :
|
|
||||||
(a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> 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 value
|
|
||||||
map11 func da db dc dd de df dg dh di dj dk =
|
|
||||||
D.map8
|
|
||||||
(\a b c d e ( f, g ) ( h, i ) ( j, k ) ->
|
|
||||||
func a b c d e f g h i j k
|
|
||||||
)
|
|
||||||
da
|
|
||||||
db
|
|
||||||
dc
|
|
||||||
dd
|
|
||||||
de
|
|
||||||
(D.map2 Tuple.pair df dg)
|
|
||||||
(D.map2 Tuple.pair dh di)
|
|
||||||
(D.map2 Tuple.pair dj dk)
|
|
|
@ -1,52 +0,0 @@
|
||||||
module Internal.Tools.Encode exposing (maybeObject)
|
|
||||||
|
|
||||||
{-|
|
|
||||||
|
|
||||||
|
|
||||||
# Encode module
|
|
||||||
|
|
||||||
This module contains helper functions that help decode JSON.
|
|
||||||
|
|
||||||
|
|
||||||
# Optional body object
|
|
||||||
|
|
||||||
@docs maybeObject
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
import Json.Encode as E
|
|
||||||
|
|
||||||
|
|
||||||
{-| Create a body object based on optionally provided values.
|
|
||||||
|
|
||||||
In other words, the following two variables create the same JSON value:
|
|
||||||
|
|
||||||
value1 : Json.Encode.Value
|
|
||||||
value1 =
|
|
||||||
maybeObject
|
|
||||||
[ ( "name", Just (Json.Encode.string "Alice") )
|
|
||||||
, ( "age", Nothing )
|
|
||||||
, ( "height", Just (Json.Encode.float 1.61) )
|
|
||||||
, ( "weight", Nothing )
|
|
||||||
]
|
|
||||||
|
|
||||||
value2 : Json.Encode.Value
|
|
||||||
value2 =
|
|
||||||
Json.Encode.object
|
|
||||||
[ ( "name", Json.Encode.string "Alice" )
|
|
||||||
, ( "height", Json.Encode.float 1.61 )
|
|
||||||
]
|
|
||||||
|
|
||||||
-}
|
|
||||||
maybeObject : List ( String, Maybe E.Value ) -> E.Value
|
|
||||||
maybeObject =
|
|
||||||
List.filterMap
|
|
||||||
(\( name, value ) ->
|
|
||||||
case value of
|
|
||||||
Just v ->
|
|
||||||
Just ( name, v )
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
Nothing
|
|
||||||
)
|
|
||||||
>> E.object
|
|
|
@ -1,250 +0,0 @@
|
||||||
module Internal.Values.Envelope exposing
|
|
||||||
( Envelope, init
|
|
||||||
, map, mapMaybe
|
|
||||||
, Settings, mapSettings, extractSettings
|
|
||||||
, getContent, extract
|
|
||||||
, encode, decoder
|
|
||||||
)
|
|
||||||
|
|
||||||
{-| The Envelope module wraps existing data types with lots of values and
|
|
||||||
settings that can be adjusted manually.
|
|
||||||
|
|
||||||
|
|
||||||
## Create
|
|
||||||
|
|
||||||
@docs Envelope, init
|
|
||||||
|
|
||||||
|
|
||||||
## Manipulate
|
|
||||||
|
|
||||||
@docs map, mapMaybe
|
|
||||||
|
|
||||||
|
|
||||||
## Settings
|
|
||||||
|
|
||||||
@docs Settings, mapSettings, extractSettings
|
|
||||||
|
|
||||||
|
|
||||||
## Extract
|
|
||||||
|
|
||||||
@docs getContent, extract
|
|
||||||
|
|
||||||
|
|
||||||
## JSON coders
|
|
||||||
|
|
||||||
@docs encode, decoder
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
import Internal.Config.Default as Default
|
|
||||||
import Internal.Tools.Decode as D
|
|
||||||
import Internal.Tools.Encode as E
|
|
||||||
import Json.Decode as D
|
|
||||||
import Json.Encode as E
|
|
||||||
|
|
||||||
|
|
||||||
{-| There are lots of different data types in the Elm SDK, and many of them
|
|
||||||
need the same values. The Envelope type wraps settings, tokens and values around
|
|
||||||
each data type so they can all enjoy those values without needing to explicitly
|
|
||||||
define them in their type.
|
|
||||||
-}
|
|
||||||
type Envelope a
|
|
||||||
= Envelope
|
|
||||||
{ content : a
|
|
||||||
, settings : Settings
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Custom settings that can be manipulated by the user. These serve as a
|
|
||||||
configuration for how the Elm SDK should behave.
|
|
||||||
|
|
||||||
Custom settings are always part of the Envelope, allowing all functions to
|
|
||||||
behave under the user's preferred settings.
|
|
||||||
|
|
||||||
-}
|
|
||||||
type alias Settings =
|
|
||||||
{ currentVersion : String
|
|
||||||
, deviceName : String
|
|
||||||
, syncTime : Int
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Decode an enveloped type from a JSON value. The decoder also imports any
|
|
||||||
potential tokens, values and settings included in the JSON.
|
|
||||||
-}
|
|
||||||
decoder : D.Decoder a -> D.Decoder (Envelope a)
|
|
||||||
decoder xDecoder =
|
|
||||||
D.map2 (\a b -> Envelope { content = a, settings = b })
|
|
||||||
(D.field "content" xDecoder)
|
|
||||||
(D.field "settings" decoderSettings)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Decode settings from a JSON value.
|
|
||||||
-}
|
|
||||||
decoderSettings : D.Decoder Settings
|
|
||||||
decoderSettings =
|
|
||||||
D.map3 Settings
|
|
||||||
(D.opFieldWithDefault "currentVersion" Default.currentVersion D.string)
|
|
||||||
(D.opFieldWithDefault "deviceName" Default.deviceName D.string)
|
|
||||||
(D.opFieldWithDefault "syncTime" Default.syncTime D.int)
|
|
||||||
|
|
||||||
|
|
||||||
{-| Encode an enveloped type into a JSON value. The function encodes all
|
|
||||||
non-standard settings, tokens and values.
|
|
||||||
-}
|
|
||||||
encode : (a -> E.Value) -> Envelope a -> E.Value
|
|
||||||
encode encodeX (Envelope data) =
|
|
||||||
E.object
|
|
||||||
[ ( "content", encodeX data.content )
|
|
||||||
, ( "settings", encodeSettings data.settings )
|
|
||||||
, ( "version", E.string Default.currentVersion )
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
{-| Encode the settings into a JSON value.
|
|
||||||
-}
|
|
||||||
encodeSettings : Settings -> E.Value
|
|
||||||
encodeSettings settings =
|
|
||||||
let
|
|
||||||
differentFrom : b -> b -> Maybe b
|
|
||||||
differentFrom defaultValue currentValue =
|
|
||||||
if currentValue == defaultValue then
|
|
||||||
Nothing
|
|
||||||
|
|
||||||
else
|
|
||||||
Just currentValue
|
|
||||||
in
|
|
||||||
E.maybeObject
|
|
||||||
[ ( "currentVersion"
|
|
||||||
, settings.currentVersion
|
|
||||||
|> differentFrom Default.currentVersion
|
|
||||||
|> Maybe.map E.string
|
|
||||||
)
|
|
||||||
, ( "deviceName"
|
|
||||||
, settings.deviceName
|
|
||||||
|> differentFrom Default.deviceName
|
|
||||||
|> Maybe.map E.string
|
|
||||||
)
|
|
||||||
, ( "syncTime"
|
|
||||||
, settings.syncTime
|
|
||||||
|> differentFrom Default.syncTime
|
|
||||||
|> Maybe.map E.int
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
{-| Map a function, then get its content. This is useful for getting information
|
|
||||||
from a data type inside an Envelope.
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ name : String, age : Int }
|
|
||||||
|
|
||||||
getName : Envelope User -> String
|
|
||||||
getName =
|
|
||||||
Envelope.extract .name
|
|
||||||
|
|
||||||
-}
|
|
||||||
extract : (a -> b) -> Envelope a -> b
|
|
||||||
extract f (Envelope data) =
|
|
||||||
f data.content
|
|
||||||
|
|
||||||
|
|
||||||
{-| Map a function on the settings, effectively getting data that way.
|
|
||||||
|
|
||||||
This can be helpful if you have a UI that displays custom settings to a user.
|
|
||||||
|
|
||||||
-}
|
|
||||||
extractSettings : (Settings -> b) -> Envelope a -> b
|
|
||||||
extractSettings f (Envelope data) =
|
|
||||||
f data.settings
|
|
||||||
|
|
||||||
|
|
||||||
{-| Get the original item that is stored inside an Envelope.
|
|
||||||
|
|
||||||
Make sure that you're only using this if you're interested in the actual value!
|
|
||||||
If you'd like to get the content, run a function on it, and put it back in an
|
|
||||||
Envelope, consider using [map](#map) instead.
|
|
||||||
|
|
||||||
-}
|
|
||||||
getContent : Envelope a -> a
|
|
||||||
getContent =
|
|
||||||
extract identity
|
|
||||||
|
|
||||||
|
|
||||||
{-| Create a new enveloped data type. All settings are set to default values
|
|
||||||
from the [Internal.Config.Default](Internal-Config-Default) module.
|
|
||||||
-}
|
|
||||||
init : a -> Envelope a
|
|
||||||
init x =
|
|
||||||
Envelope
|
|
||||||
{ content = x
|
|
||||||
, settings =
|
|
||||||
{ currentVersion = Default.currentVersion
|
|
||||||
, deviceName = Default.deviceName
|
|
||||||
, syncTime = Default.syncTime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Map a function on the content of the Envelope.
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ name : String, age : Int }
|
|
||||||
|
|
||||||
getName : Envelope User -> Envelope String
|
|
||||||
getName =
|
|
||||||
Envelope.map .name
|
|
||||||
|
|
||||||
-}
|
|
||||||
map : (a -> b) -> Envelope a -> Envelope b
|
|
||||||
map f (Envelope data) =
|
|
||||||
Envelope
|
|
||||||
{ content = f data.content
|
|
||||||
, settings = data.settings
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Update the settings in the Envelope.
|
|
||||||
|
|
||||||
setDeviceName : String -> Envelope a -> Envelope a
|
|
||||||
setDeviceName name envelope =
|
|
||||||
mapSettings
|
|
||||||
(\settings ->
|
|
||||||
{ settings | deviceName = name }
|
|
||||||
)
|
|
||||||
envelope
|
|
||||||
|
|
||||||
-}
|
|
||||||
mapSettings : (Settings -> Settings) -> Envelope a -> Envelope a
|
|
||||||
mapSettings f (Envelope data) =
|
|
||||||
Envelope
|
|
||||||
{ content = data.content
|
|
||||||
, settings = f data.settings
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
{-| Map the contents of a function, where the result is wrapped in a `Maybe`
|
|
||||||
type. This can be useful when you are not guaranteed to find the value you're
|
|
||||||
looking for.
|
|
||||||
|
|
||||||
type alias User =
|
|
||||||
{ name : String, age : Int }
|
|
||||||
|
|
||||||
type alias UserDatabase =
|
|
||||||
List User
|
|
||||||
|
|
||||||
getFirstUser : Envelope UserDatabase -> Maybe (Envelope User)
|
|
||||||
getFirstUser envelope =
|
|
||||||
mapMaybe List.head envelope
|
|
||||||
|
|
||||||
-}
|
|
||||||
mapMaybe : (a -> Maybe b) -> Envelope a -> Maybe (Envelope b)
|
|
||||||
mapMaybe f =
|
|
||||||
map f >> toMaybe
|
|
||||||
|
|
||||||
|
|
||||||
toMaybe : Envelope (Maybe a) -> Maybe (Envelope a)
|
|
||||||
toMaybe (Envelope data) =
|
|
||||||
Maybe.map
|
|
||||||
(\content -> map (always content) (Envelope data))
|
|
||||||
data.content
|
|
|
@ -1,15 +0,0 @@
|
||||||
module Internal.Values.Vault exposing (Vault)
|
|
||||||
|
|
||||||
{-| This module hosts the Vault module.
|
|
||||||
|
|
||||||
@docs Vault
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
import Internal.Values.Envelope as Envelope
|
|
||||||
|
|
||||||
|
|
||||||
{-| This is the Vault type.
|
|
||||||
-}
|
|
||||||
type alias Vault =
|
|
||||||
Envelope.Envelope {}
|
|
|
@ -1,9 +1,5 @@
|
||||||
module Matrix exposing (Vault)
|
module Matrix exposing (Vault)
|
||||||
|
{-| # Matrix SDK
|
||||||
{-|
|
|
||||||
|
|
||||||
|
|
||||||
# Matrix SDK
|
|
||||||
|
|
||||||
This first version forms a mere basis from which we will create iterative builds
|
This first version forms a mere basis from which we will create iterative builds
|
||||||
that slowly improve the codebase.
|
that slowly improve the codebase.
|
||||||
|
@ -12,20 +8,13 @@ It is generally quite unusual to regularly publish iterative beta versions on
|
||||||
the public registry, but it is also generally quite unusual to exclusively
|
the public registry, but it is also generally quite unusual to exclusively
|
||||||
support a monolithic public registry. (:
|
support a monolithic public registry. (:
|
||||||
|
|
||||||
|
|
||||||
## Vault
|
## Vault
|
||||||
|
|
||||||
@docs Vault
|
@docs Vault
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Types
|
|
||||||
|
|
||||||
|
|
||||||
{-| The Vault type stores all relevant information about the Matrix API.
|
{-| The Vault type stores all relevant information about the Matrix API.
|
||||||
|
|
||||||
It currently supports no functionality and it will just stay here - for fun.
|
It currently supports no functionality and it will just stay here - for fun.
|
||||||
|
|
||||||
-}
|
-}
|
||||||
type alias Vault =
|
type Vault = Vault
|
||||||
Types.Vault
|
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
module Matrix.Settings exposing
|
|
||||||
( getDeviceName, setDeviceName
|
|
||||||
, getSyncTime, setSyncTime
|
|
||||||
)
|
|
||||||
|
|
||||||
{-| The Matrix Vault has lots of configurable variables that you rarely want to
|
|
||||||
interact with. Usually, you configure these variables only when creating a new
|
|
||||||
Vault, or when a user explicitly changes one of their preferred settings.
|
|
||||||
|
|
||||||
|
|
||||||
## Device name
|
|
||||||
|
|
||||||
The default device name that is being communicated with the Matrix API.
|
|
||||||
|
|
||||||
This is mostly useful for users who are logged in with multiple sessions. They
|
|
||||||
will see device names like "Element for Android" or "Element on iOS". For the
|
|
||||||
Elm SDK, they will by default see the Elm SDK with its version included. If you
|
|
||||||
are writing a custom client, however, you are free to change this to something
|
|
||||||
more meaningful to the user.
|
|
||||||
|
|
||||||
@docs getDeviceName, setDeviceName
|
|
||||||
|
|
||||||
|
|
||||||
## Sync time
|
|
||||||
|
|
||||||
Whenever the Matrix API has nothing new to report, the Elm SDK is kept on
|
|
||||||
hold until something new happens. The `syncTime` indicates a timeout to how long
|
|
||||||
the Elm SDK tolerates being held on hold.
|
|
||||||
|
|
||||||
- ↗️ A high value is good because it significantly reduces traffic between the
|
|
||||||
user and the homeserver.
|
|
||||||
- ↘️ A low value is good because it reduces the risk of
|
|
||||||
the connection ending abruptly or unexpectedly.
|
|
||||||
|
|
||||||
Nowadays, most libraries use 30 seconds as the standard, as does the Elm SDK.
|
|
||||||
The value is in miliseconds, so it is set at 30,000.
|
|
||||||
|
|
||||||
@docs getSyncTime, setSyncTime
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
import Internal.Values.Envelope as Envelope
|
|
||||||
import Types exposing (Vault(..))
|
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the device name.
|
|
||||||
-}
|
|
||||||
getDeviceName : Vault -> String
|
|
||||||
getDeviceName (Vault vault) =
|
|
||||||
Envelope.extractSettings .deviceName vault
|
|
||||||
|
|
||||||
|
|
||||||
{-| Override the device name.
|
|
||||||
-}
|
|
||||||
setDeviceName : String -> Vault -> Vault
|
|
||||||
setDeviceName name (Vault vault) =
|
|
||||||
Vault <| Envelope.mapSettings (\s -> { s | deviceName = name }) vault
|
|
||||||
|
|
||||||
|
|
||||||
{-| Determine the sync timeout value.
|
|
||||||
-}
|
|
||||||
getSyncTime : Vault -> Int
|
|
||||||
getSyncTime (Vault vault) =
|
|
||||||
Envelope.extractSettings .syncTime vault
|
|
||||||
|
|
||||||
|
|
||||||
{-| Override the sync timeout value.
|
|
||||||
-}
|
|
||||||
setSyncTime : Int -> Vault -> Vault
|
|
||||||
setSyncTime time (Vault vault) =
|
|
||||||
Vault <| Envelope.mapSettings (\s -> { s | syncTime = time }) vault
|
|
|
@ -1,25 +0,0 @@
|
||||||
module Types exposing (Vault(..))
|
|
||||||
|
|
||||||
{-| 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)
|
|
||||||
highly recommend using opaque types in order to avoid breaking everyone's code
|
|
||||||
in a future major release.
|
|
||||||
|
|
||||||
This module forms as a protective layer between the internal modules and the
|
|
||||||
exposed modules, hiding all exposed types behind opaque types so the user cannot
|
|
||||||
access their content directly.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
@docs Vault
|
|
||||||
|
|
||||||
-}
|
|
||||||
|
|
||||||
import Internal.Values.Vault as Vault
|
|
||||||
|
|
||||||
|
|
||||||
{-| Opaque type for Matrix Vault
|
|
||||||
-}
|
|
||||||
type Vault
|
|
||||||
= Vault Vault.Vault
|
|
Loading…
Reference in New Issue