Begin working on Http requests.
This commit is contained in:
parent
c292a4c29b
commit
3656b0f3f0
3
elm.json
3
elm.json
|
@ -10,10 +10,13 @@
|
||||||
"elm/browser": "1.0.1",
|
"elm/browser": "1.0.1",
|
||||||
"elm/core": "1.0.2",
|
"elm/core": "1.0.2",
|
||||||
"elm/html": "1.0.0",
|
"elm/html": "1.0.0",
|
||||||
|
"elm/http": "2.0.0",
|
||||||
"elm/json": "1.1.2",
|
"elm/json": "1.1.2",
|
||||||
"elm/url": "1.0.0"
|
"elm/url": "1.0.0"
|
||||||
},
|
},
|
||||||
"indirect": {
|
"indirect": {
|
||||||
|
"elm/bytes": "1.0.7",
|
||||||
|
"elm/file": "1.0.1",
|
||||||
"elm/time": "1.0.0",
|
"elm/time": "1.0.0",
|
||||||
"elm/virtual-dom": "1.0.2"
|
"elm/virtual-dom": "1.0.2"
|
||||||
}
|
}
|
||||||
|
|
16
src/Main.elm
16
src/Main.elm
|
@ -1,28 +1,22 @@
|
||||||
import Browser exposing (application)
|
import Browser exposing (application)
|
||||||
import Browser.Navigation as Nav
|
import Browser.Navigation as Nav
|
||||||
|
import Scylla.Sync exposing (..)
|
||||||
|
import Scylla.Model exposing (..)
|
||||||
|
import Scylla.Http exposing (..)
|
||||||
import Url exposing (Url)
|
import Url exposing (Url)
|
||||||
import Html exposing (div)
|
import Html exposing (div, text)
|
||||||
|
|
||||||
type alias Flags =
|
type alias Flags =
|
||||||
{ token : Maybe String
|
{ token : Maybe String
|
||||||
}
|
}
|
||||||
|
|
||||||
type alias Model =
|
|
||||||
{ key : Nav.Key
|
|
||||||
, token : Maybe String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Msg =
|
|
||||||
None
|
|
||||||
| TryUrl Browser.UrlRequest
|
|
||||||
| ChangeUrl Url
|
|
||||||
|
|
||||||
init : Flags -> Url -> Nav.Key -> (Model, Cmd Msg)
|
init : Flags -> Url -> Nav.Key -> (Model, Cmd Msg)
|
||||||
init flags url key =
|
init flags url key =
|
||||||
let
|
let
|
||||||
model =
|
model =
|
||||||
{ key = key
|
{ key = key
|
||||||
, token = flags.token
|
, token = flags.token
|
||||||
|
, apiUrl = "https://matrix.org"
|
||||||
}
|
}
|
||||||
cmd = case flags.token of
|
cmd = case flags.token of
|
||||||
Just _ -> Cmd.none
|
Just _ -> Cmd.none
|
||||||
|
|
15
src/Scylla/Api.elm
Normal file
15
src/Scylla/Api.elm
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
module Scylla.Api exposing (..)
|
||||||
|
import Http exposing (Header, header)
|
||||||
|
import Json.Encode as Encode
|
||||||
|
|
||||||
|
type alias ApiToken = String
|
||||||
|
type alias ApiUrl = String
|
||||||
|
|
||||||
|
basicHeaders : List Header
|
||||||
|
basicHeaders =
|
||||||
|
[ header "Content-Type" "application/json"
|
||||||
|
]
|
||||||
|
|
||||||
|
authenticatedHeaders : ApiToken -> List Header
|
||||||
|
authenticatedHeaders token =
|
||||||
|
[ header "Authorization" ("Bearer " ++ token)] ++ basicHeaders
|
37
src/Scylla/Http.elm
Normal file
37
src/Scylla/Http.elm
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
module Scylla.Http exposing (..)
|
||||||
|
import Scylla.Model exposing (..)
|
||||||
|
import Scylla.Api exposing (..)
|
||||||
|
import Scylla.Sync exposing (syncResponseDecoder)
|
||||||
|
import Scylla.Login exposing (loginResponseDecoder, Username, Password)
|
||||||
|
import Json.Encode exposing (object, string)
|
||||||
|
import Http exposing (request, jsonBody, expectJson)
|
||||||
|
|
||||||
|
-- Http Requests
|
||||||
|
firstSync : ApiUrl -> ApiToken -> Cmd Msg
|
||||||
|
firstSync apiUrl token = request
|
||||||
|
{ method = "GET"
|
||||||
|
, headers = authenticatedHeaders token
|
||||||
|
, url = apiUrl ++ "/sync"
|
||||||
|
, body = jsonBody <| object []
|
||||||
|
, expect = expectJson ReceiveSyncResponse syncResponseDecoder
|
||||||
|
, timeout = Nothing
|
||||||
|
, tracker = Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
login : ApiUrl -> Username -> Password -> Cmd Msg
|
||||||
|
login apiUrl username password = request
|
||||||
|
{ method = "POST"
|
||||||
|
, headers = basicHeaders
|
||||||
|
, url = apiUrl ++ "/login"
|
||||||
|
, body = jsonBody <| object
|
||||||
|
[ ("type", string "m.login.password")
|
||||||
|
, ("identifier", object
|
||||||
|
[ ("type", string "m.id.user")
|
||||||
|
, ("user", string username)
|
||||||
|
] )
|
||||||
|
, ("password", string password)
|
||||||
|
]
|
||||||
|
, expect = expectJson ReceiveLoginResponse loginResponseDecoder
|
||||||
|
, timeout = Nothing
|
||||||
|
, tracker = Nothing
|
||||||
|
}
|
20
src/Scylla/Login.elm
Normal file
20
src/Scylla/Login.elm
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
module Scylla.Login exposing (..)
|
||||||
|
import Scylla.Api exposing (ApiToken)
|
||||||
|
import Json.Decode as Decode exposing (Decoder, int, string, float, list, value, dict, bool)
|
||||||
|
import Json.Decode.Pipeline exposing (required, optional)
|
||||||
|
|
||||||
|
type alias Username = String
|
||||||
|
type alias Password = String
|
||||||
|
|
||||||
|
type alias LoginResponse =
|
||||||
|
{ userId : String
|
||||||
|
, accessToken : ApiToken
|
||||||
|
, deviceId : String
|
||||||
|
}
|
||||||
|
|
||||||
|
loginResponseDecoder : Decoder LoginResponse
|
||||||
|
loginResponseDecoder =
|
||||||
|
Decode.succeed LoginResponse
|
||||||
|
|> required "user_id" string
|
||||||
|
|> required "access_token" string
|
||||||
|
|> required "device_id" string
|
21
src/Scylla/Model.elm
Normal file
21
src/Scylla/Model.elm
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
module Scylla.Model exposing (..)
|
||||||
|
import Scylla.Api exposing (..)
|
||||||
|
import Scylla.Sync exposing (SyncResponse)
|
||||||
|
import Scylla.Login exposing (LoginResponse)
|
||||||
|
import Browser.Navigation as Nav
|
||||||
|
import Browser
|
||||||
|
import Http
|
||||||
|
import Url exposing (Url)
|
||||||
|
|
||||||
|
type alias Model =
|
||||||
|
{ key : Nav.Key
|
||||||
|
, token : Maybe ApiToken
|
||||||
|
, apiUrl : ApiUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
type Msg =
|
||||||
|
TryUrl Browser.UrlRequest
|
||||||
|
| ChangeUrl Url
|
||||||
|
| ReceiveSyncResponse (Result Http.Error SyncResponse)
|
||||||
|
| ReceiveLoginResponse (Result Http.Error LoginResponse)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
module Scylla.Sync exposing (..)
|
module Scylla.Sync exposing (..)
|
||||||
|
import Scylla.Api exposing (..)
|
||||||
import Dict exposing (Dict)
|
import Dict exposing (Dict)
|
||||||
import Json.Decode as Decode exposing (Decoder, int, string, float, list, value, dict, bool)
|
import Json.Decode as Decode exposing (Decoder, int, string, float, list, value, dict, bool)
|
||||||
import Json.Decode.Pipeline exposing (required, optional)
|
import Json.Decode.Pipeline exposing (required, optional)
|
||||||
|
|
||||||
|
-- Special Decoding
|
||||||
decodeJust : Decoder a -> Decoder (Maybe a)
|
decodeJust : Decoder a -> Decoder (Maybe a)
|
||||||
decodeJust = Decode.map Just
|
decodeJust = Decode.map Just
|
||||||
|
|
||||||
|
@ -227,3 +229,28 @@ leftRoomDecoder =
|
||||||
|> maybeDecode "state" stateDecoder
|
|> maybeDecode "state" stateDecoder
|
||||||
|> maybeDecode "timeline" timelineDecoder
|
|> maybeDecode "timeline" timelineDecoder
|
||||||
|> maybeDecode "account_data" accountDataDecoder
|
|> maybeDecode "account_data" accountDataDecoder
|
||||||
|
|
||||||
|
-- General Sync Response
|
||||||
|
type alias SyncResponse =
|
||||||
|
{ nextBatch : String
|
||||||
|
, rooms : Maybe Rooms
|
||||||
|
, presence : Maybe Presence
|
||||||
|
, accountData : Maybe AccountData
|
||||||
|
}
|
||||||
|
|
||||||
|
syncResponseDecoder : Decoder SyncResponse
|
||||||
|
syncResponseDecoder =
|
||||||
|
Decode.succeed SyncResponse
|
||||||
|
|> required "next_batch" string
|
||||||
|
|> maybeDecode "rooms" roomsDecoder
|
||||||
|
|> maybeDecode "presence" presenceDecoder
|
||||||
|
|> maybeDecode "account_data" accountDataDecoder
|
||||||
|
|
||||||
|
type alias Presence =
|
||||||
|
{ events : Maybe (List Event)
|
||||||
|
}
|
||||||
|
|
||||||
|
presenceDecoder : Decoder Presence
|
||||||
|
presenceDecoder =
|
||||||
|
Decode.succeed Presence
|
||||||
|
|> maybeDecode "events" (list eventDecoder)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user