adds type variable for Api.Response value field

This commit is contained in:
2019-11-15 16:05:17 +01:00
parent 1eb4fdc188
commit 516006f352
2 changed files with 90 additions and 65 deletions

View File

@@ -8,6 +8,7 @@ module Api exposing
, Msg(..) , Msg(..)
, Player , Player
, RequestData(..) , RequestData(..)
, ToChest(..)
, Update(..) , Update(..)
, Wealth , Wealth
, blankPlayer , blankPlayer
@@ -31,13 +32,8 @@ type alias HttpResult a =
-- Format of the server's response -- Format of the server's response
type Value type alias Response a =
= Text String { value : Maybe a
| Items Loot
type alias Response =
{ value : Maybe Value
, notification : Maybe String , notification : Maybe String
, updates : Maybe (List Update) , updates : Maybe (List Update)
, errors : Maybe String , errors : Maybe String
@@ -53,7 +49,7 @@ type Update
type Msg type Msg
= GotActionResult (HttpResult Response) = GotActionResult (HttpResult (Response ()))
@@ -186,25 +182,47 @@ lootDecoder =
D.list itemDecoder D.list itemDecoder
fetchLoot : String -> (Result Http.Error Loot -> msg) -> Cmd msg type ToChest
fetchLoot url toMsg = = OfPlayer Int
| OfGroup
| OfShop
fetchLoot : (ToChest -> Result Http.Error Loot -> msg) -> ToChest -> Cmd msg
fetchLoot toMsg dest =
let
url =
case dest of
OfPlayer id ->
"http://localhost:8088/api/players/" ++ String.fromInt id ++ "/loot"
OfShop ->
"http://localhost:8088/api/items"
OfGroup ->
"http://localhost:8088/api/players/0/loot"
in
Http.get Http.get
{ url = url { url = url
, expect = Http.expectJson toMsg (valueDecoder lootDecoder) , expect = Http.expectJson (toMsg dest) (valueDecoder lootDecoder)
} }
-- Retrieves items from a list of names
checkList : (Loot -> Maybe String -> msg) -> List String -> Cmd msg checkList : (Loot -> Maybe String -> msg) -> List String -> Cmd msg
checkList toMsg itemList = checkList toMsg itemList =
let let
parseResponse : Result Http.Error Response -> msg parseResponse : Result Http.Error (Response Loot) -> msg
parseResponse response = parseResponse response =
case response of case response of
Ok r -> Ok r ->
let let
items = items =
case r.value of case r.value of
Just (Items loot) -> Just loot ->
loot loot
_ -> _ ->
@@ -237,9 +255,13 @@ checkList toMsg itemList =
-- CLAIMS -- API RESPONSE
-- API Response
-- --
-- Loot-a-lot API use a flat response format with four fields :
-- * value
-- * notification
-- * updates
-- * errors
valueDecoder : Decoder a -> Decoder a valueDecoder : Decoder a -> Decoder a
@@ -266,10 +288,13 @@ updatesDecoder =
-- TODO: add a valueDecoder to get a proper value out of Json -- The 'value' field is actually a union-type
-- with heterogeneous data. We need to provide a
-- decoder to extract the value we expect, or ignore
-- it with ().
apiResponseDecoder : Decoder Value -> Decoder Response apiResponseDecoder : Decoder a -> Decoder (Response a)
apiResponseDecoder toValue = apiResponseDecoder toValue =
D.map4 Response D.map4 Response
(D.maybe (field "value" toValue)) (D.maybe (field "value" toValue))
@@ -278,18 +303,6 @@ apiResponseDecoder toValue =
(D.maybe (field "errors" string)) (D.maybe (field "errors" string))
undoLastAction id =
Http.request
{ url = "http://localhost:8088/api/players/" ++ String.fromInt id ++ "/events/last"
, method = "DELETE"
, headers = []
, body = Http.emptyBody
, expect = Http.expectJson GotActionResult (apiResponseDecoder string)
, timeout = Nothing
, tracker = Nothing
}
{- ACTIONS {- ACTIONS
@@ -370,12 +383,28 @@ confirmAction id data =
, headers = [] , headers = []
, url = endpoint , url = endpoint
, body = Http.jsonBody <| buildPayload data , body = Http.jsonBody <| buildPayload data
, expect = Http.expectJson GotActionResult (apiResponseDecoder string) , expect = Http.expectJson GotActionResult (apiResponseDecoder <| D.succeed ())
, timeout = Nothing , timeout = Nothing
, tracker = Nothing , tracker = Nothing
} }
undoLastAction id =
Http.request
{ url = "http://localhost:8088/api/players/" ++ String.fromInt id ++ "/events/last"
, method = "DELETE"
, headers = []
, body = Http.emptyBody
, expect = Http.expectJson GotActionResult (apiResponseDecoder <| D.succeed ())
, timeout = Nothing
, tracker = Nothing
}
-- UTILS
printError : Http.Error -> String printError : Http.Error -> String
printError error = printError error =
case error of case error of

View File

@@ -87,9 +87,9 @@ init (Player navKey playerId) =
, Cmd.batch , Cmd.batch
[ Api.fetchPlayer GotPlayer playerId [ Api.fetchPlayer GotPlayer playerId
, Api.fetchClaims GotClaims playerId , Api.fetchClaims GotClaims playerId
, fetchLoot (OfPlayer playerId) , Api.fetchLoot GotLoot (Api.OfPlayer playerId)
, fetchLoot OfGroup , Api.fetchLoot GotLoot Api.OfGroup
, fetchLoot OfShop , Api.fetchLoot GotLoot Api.OfShop
] ]
) )
@@ -173,13 +173,17 @@ viewHeaderBar title model =
[ renderIcon { icon = "fab fa-d-and-d", size = "medium", ratio = "2x" } [ renderIcon { icon = "fab fa-d-and-d", size = "medium", ratio = "2x" }
, span [ class "title is-4", style "padding-left" "0.4em" ] [ text title ] , span [ class "title is-4", style "padding-left" "0.4em" ] [ text title ]
] ]
, a [ class "navbar-burger is-active" ] , a
[ class "navbar-burger"
, classList [ ( "is-active", model.state.menuOpen ) ]
, onClick SwitchMenuOpen
]
[ span [ attribute "aria-hidden" "true" ] [] [ span [ attribute "aria-hidden" "true" ] []
, span [ attribute "aria-hidden" "true" ] [] , span [ attribute "aria-hidden" "true" ] []
, span [ attribute "aria-hidden" "true" ] [] , span [ attribute "aria-hidden" "true" ] []
] ]
] ]
, div [ class "navbar-menu is-active" ] , div [ class "navbar-menu", classList [ ( "is-active", model.state.menuOpen ) ] ]
[ div [ class "navbar-end" ] [ div [ class "navbar-end" ]
[ a [ class "navbar-item", href "/marchand" ] [ a [ class "navbar-item", href "/marchand" ]
[ renderIcon { icon = "fas fa-store-alt", ratio = "1x", size = "medium" } [ renderIcon { icon = "fas fa-store-alt", ratio = "1x", size = "medium" }
@@ -344,8 +348,6 @@ view model =
] ]
) )
] ]
, hr [] []
, section [ class "container" ] [ viewDebugSection model ]
] ]
@@ -733,10 +735,11 @@ viewControls mode content =
type Msg type Msg
= ApiMsg Api.Msg = ApiMsg Api.Msg
| ClearNotification | ClearNotification
| SwitchMenuOpen
| SetContent ChestContent | SetContent ChestContent
| SetSelection (Maybe Selection) | SetSelection (Maybe Selection)
| SwitchSelectionState Int | SwitchSelectionState Int
| GotLoot ToChest (HttpResult Loot) | GotLoot Api.ToChest (HttpResult Loot)
| GotClaims (HttpResult Claims) | GotClaims (HttpResult Claims)
| GotPlayer (HttpResult Api.Player) | GotPlayer (HttpResult Api.Player)
| SearchTextChanged String | SearchTextChanged String
@@ -763,6 +766,15 @@ insensitiveContains substring string =
update : Msg -> Model -> ( Model, Cmd Msg ) update : Msg -> Model -> ( Model, Cmd Msg )
update msg model = update msg model =
case msg of case msg of
SwitchMenuOpen ->
let
state =
model.state
in
( { model | state = { state | menuOpen = not model.state.menuOpen } }
, Cmd.none
)
NewItemsFromList newLoot maybeErrors -> NewItemsFromList newLoot maybeErrors ->
let let
state = state =
@@ -1031,13 +1043,13 @@ update msg model =
model.state model.state
in in
case dest of case dest of
OfPlayer _ -> Api.OfPlayer _ ->
{ model | state = { state | playerLoot = loot } } { model | state = { state | playerLoot = loot } }
OfGroup -> Api.OfGroup ->
{ model | state = { state | groupLoot = loot } } { model | state = { state | groupLoot = loot } }
OfShop -> Api.OfShop ->
{ model | state = { state | merchantLoot = loot } } { model | state = { state | merchantLoot = loot } }
, Cmd.none , Cmd.none
) )
@@ -1067,10 +1079,17 @@ setError error model =
let let
state = state =
model.state model.state
newError =
if error == "" then
Nothing
else
Just error
in in
{ model { model
| state = | state =
{ state | error = Just error } { state | error = newError }
} }
@@ -1124,29 +1143,6 @@ applyUpdate u model =
{ model | claims = List.filter (\c -> c.id /= claim.id) model.claims } { model | claims = List.filter (\c -> c.id /= claim.id) model.claims }
type ToChest
= OfPlayer Int
| OfGroup
| OfShop
fetchLoot : ToChest -> Cmd Msg
fetchLoot dest =
let
url =
case dest of
OfPlayer id ->
"http://localhost:8088/api/players/" ++ String.fromInt id ++ "/loot"
OfShop ->
"http://localhost:8088/api/items"
OfGroup ->
"http://localhost:8088/api/players/0/loot"
in
Api.fetchLoot url (GotLoot dest)
-- Selection -- Selection
-- Get list of selected items -- Get list of selected items