adds type variable for Api.Response value field
This commit is contained in:
89
src/Api.elm
89
src/Api.elm
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user