adds routing and some models

This commit is contained in:
2019-11-01 15:53:21 +01:00
parent 1fc3aa340d
commit 4ea22c2d49
3 changed files with 983 additions and 441 deletions

9
build.sh Executable file
View File

@@ -0,0 +1,9 @@
if [[ $1 == "--debug" ]]
then
optimize=""
else
optimize="--optimize"
fi
elm make src/Main.elm $optimize --output=main.js

1212
main.js

File diff suppressed because it is too large Load Diff

View File

@@ -2,12 +2,14 @@ module Main exposing (..)
import Browser import Browser
import Browser.Navigation as Nav import Browser.Navigation as Nav
import Platform.Cmd exposing (Cmd)
import Url import Url
import Html exposing (..) import Html exposing (..)
import Html.Attributes exposing (..) import Html.Attributes exposing (..)
import Html.Events exposing (..) import Html.Events exposing (..)
import Http import Http
import Json.Decode exposing (Decoder, field, string, int) import Json.Decode exposing (Decoder, field, list, string, int)
import Url.Parser as P exposing (Parser, (</>), oneOf, s)
-- Main -- Main
main : Program () Model Msg main : Program () Model Msg
@@ -25,26 +27,52 @@ main =
type alias Model = type alias Model =
{ key : Nav.Key { key : Nav.Key
, url : Url.Url , route : Route
, player: Player , player: Player
, loot: Maybe Loot
, groupLoot : Maybe Loot
, error: String , error: String
} }
init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg ) init : () -> Url.Url -> Nav.Key -> ( Model, Cmd Msg )
init flags url key = init flags url key =
( Model key url blankPlayer "", (fetchPlayer 0)) let
route = case P.parse routeParser url of
Just r -> r
Nothing -> GroupLoot
in
( Model key route blankPlayer Nothing Nothing "", initPlayer 0)
-- PLAYER -- PLAYER
-- --
type alias Player = type alias Player =
{ name: String { id: Int
, name: String
, debt: Int , debt: Int
, wealth: Wealth , wealth: Wealth
} }
blankPlayer = blankPlayer =
Player "Loading" 100 (Wealth 0 0 0 0) Player 0 "Loading" 100 (Wealth 0 0 0 0)
initPlayer id =
Cmd.batch [fetchPlayer id, fetchLoot id]
fetchPlayer : Int -> Cmd Msg
fetchPlayer id =
Http.get
{ url = "http://localhost:8088/api/players/" ++ (String.fromInt id) ++ "/"
, expect = Http.expectJson GotPlayer (valueDecoder playerDecoder )
}
playerDecoder : Decoder Player
playerDecoder =
Json.Decode.map4 Player
(field "id" int)
(field "name" string)
(field "debt" int)
wealthDecoder
type alias Wealth = type alias Wealth =
{ cp: Int { cp: Int
@@ -53,31 +81,51 @@ type alias Wealth =
, pp: Int , pp: Int
} }
fetchPlayer : Int -> Cmd Msg wealthDecoder : Decoder Wealth
fetchPlayer id = wealthDecoder =
Http.get Json.Decode.map4 Wealth
{ url = "http://localhost:8088/api/players/" ++ (String.fromInt id) ++ "/" (field "cp" int)
, expect = Http.expectJson GotPlayer playerDecoder (field "sp" int)
(field "gp" int)
(field "pp" int)
type alias Item =
{ id: Int
, name: String
, base_price: Int
} }
playerDecoder : Decoder Player itemDecoder =
playerDecoder = Json.Decode.map3 Item
Json.Decode.map3 Player (field "id" int)
(field "value" (field "name" string)) (field "name" string)
(field "value" (field "debt" int)) (field "base_price" int)
(Json.Decode.map4 Wealth
(field "value" (field "cp" int)) type alias Loot =
(field "value" (field "sp" int)) List Item
(field "value" (field "gp" int))
(field "value" (field "pp" int))) lootDecoder : Decoder Loot
lootDecoder =
Json.Decode.list itemDecoder
fetchLoot id =
Http.get
{ url = "http://localhost:8088/api/players/" ++ (String.fromInt id) ++ "/loot"
, expect = Http.expectJson GotLoot (valueDecoder lootDecoder)}
-- API Response
--
valueDecoder : Decoder a -> Decoder a
valueDecoder thenDecoder =
field "value" thenDecoder
-- UPDATE -- UPDATE
type Msg type Msg
= LinkClicked Browser.UrlRequest = LinkClicked Browser.UrlRequest
| UrlChanged Url.Url | UrlChanged Url.Url
| DebugSwitchPlayer Int | PlayerChanged Int
| GotPlayer (Result Http.Error Player) | GotPlayer (Result Http.Error Player)
| GotLoot (Result Http.Error Loot)
update : Msg -> Model -> ( Model, Cmd Msg ) update : Msg -> Model -> ( Model, Cmd Msg )
update msg model = update msg model =
@@ -92,12 +140,22 @@ update msg model =
( { model | error = "Invalid request '" ++ href ++ "'" }, Cmd.none ) ( { model | error = "Invalid request '" ++ href ++ "'" }, Cmd.none )
UrlChanged url -> UrlChanged url ->
( { model | url = url } let
, Cmd.none route = P.parse routeParser url
in
case route of
Just page ->
( { model | route = page }
, case page of
GroupLoot -> Cmd.none
a -> Cmd.none
) )
DebugSwitchPlayer id -> Nothing ->
( model, fetchPlayer id) ( { model | error = "Invalid route" }, Cmd.none )
PlayerChanged newId ->
( { model | player = blankPlayer }, initPlayer newId )
GotPlayer result -> GotPlayer result ->
case result of case result of
@@ -105,7 +163,15 @@ update msg model =
( { model | player = player } ( { model | player = player }
, Cmd.none , Cmd.none
) )
Err error -> ( { model | error = (printError error) }, Cmd.none ) Err error -> ( { model | error = "Fetching player... " ++ (printError error) }, Cmd.none )
GotLoot result ->
case result of
Ok loot ->
( { model | loot = Just loot}
, Cmd.none
)
Err error -> ( { model | error = "Fetching loot... " ++ (printError error) }, Cmd.none )
-- ERRORS -- ERRORS
@@ -131,29 +197,53 @@ view model =
, body = , body =
[ viewHeaderBar model [ viewHeaderBar model
, viewPlayerWealth model.player , viewPlayerWealth model.player
, section [] , section [class "container"]
[ text "Loot-a-lot" ] (case model.route of
, p [] [ text "Start using it !" ] PlayerChest ->
, viewDebugSection model [ p [] [text "Mon Coffre"]
, viewLoot (case model.loot of
Just i -> i
Nothing -> [])
]
GroupLoot ->
[ p [] [text "Coffre de groupe"] ]
Merchant ->
[ p [] [text "Acheter des objets"] ]
NewLoot ->
[ p [] [text "Nouveau trésor :) "] ]
)
, section [class "container"] [viewDebugSection model]
] ]
} }
viewItemTableRow item =
tr [class "table"]
[ td [] [p [] [text item.name]]
]
viewLoot : Loot -> Html Msg
viewLoot items =
table []
(List.map viewItemTableRow items)
-- DEBUG SECTION -- DEBUG SECTION
viewDebugSection model = viewDebugSection model =
div [class "panel is-danger"] div [class "panel is-danger"]
[ p [class "panel-heading"] [text "Debug"] [ p [class "panel-heading"] [text "Debug"]
, debugSwitchPlayers , debugSwitchPlayers
, p [class "panel-block"] [text ("URL :" ++ Url.toString model.url)]
, p [class "panel-block has-text-danger"] [text model.error] , p [class "panel-block has-text-danger"] [text model.error]
, p [class "panel-block"] [text ("Route : " ++ Debug.toString model.route)]
] ]
debugSwitchPlayers : Html Msg debugSwitchPlayers : Html Msg
debugSwitchPlayers = debugSwitchPlayers =
div [ class "panel-tabs" ] div [ class "panel-tabs" ]
[ a [ onClick (DebugSwitchPlayer 0) ] [text "Groupe"] [ a [ onClick (PlayerChanged 0) ] [text "Groupe"]
, a [ onClick (DebugSwitchPlayer 1) ] [text "Lomion"] , a [ onClick (PlayerChanged 1) ] [text "Lomion"]
, a [ onClick (DebugSwitchPlayer 2) ] [text "Fefi"] , a [ onClick (PlayerChanged 2) ] [text "Fefi"]
] ]
-- HEADER SECTION -- HEADER SECTION
@@ -172,8 +262,8 @@ viewHeaderBar model =
] ]
, div [ class "navbar-menu is-active" ] , div [ class "navbar-menu is-active" ]
[ div [class "navbar-end"] [ div [class "navbar-end"]
[ a [class "navbar-item", href "#marchand"] [text "Marchand"] [ a [class "navbar-item", href "/marchand"] [text "Marchand"]
, a [class "navbar-item", href "#coffre"] [text "Mon coffre"] , a [class "navbar-item", href "/coffre"] [text "Mon coffre"]
] ]
] ]
@@ -187,9 +277,8 @@ viewPlayerWealth player =
section [ class "level" ] section [ class "level" ]
([div [class "level-left box"] ([div [class "level-left box"]
([div [ class "level-item" ] ([div [ class "level-item" ]
[ p [class "is-size-3"] [text "Argent"] [ span [ class "icon is-large" ]
, span [ class "icon is-large" ] [ i [ class "fas fa-2x fa-piggy-bank" ] [] ] [ i [ class "fas fa-2x fa-piggy-bank" ] [] ]]
]
] ++ (showWealth player.wealth)) ] ++ (showWealth player.wealth))
] ++ (if player.debt > 0 then ] ++ (if player.debt > 0 then
[ div [class "level-right"] [ div [class "level-right"]
@@ -217,3 +306,23 @@ showWealthField name value =
[ p [ class "is-size-4"] [text (String.fromInt value)] [ p [ class "is-size-4"] [text (String.fromInt value)]
, p [class "heading"] [text name] , p [class "heading"] [text name]
] ]
-- ROUTES
--
type Route
= PlayerChest
| Merchant
| GroupLoot
| NewLoot
routeParser : Parser (Route -> a) a
routeParser =
oneOf
[ P.map GroupLoot P.top
, P.map PlayerChest (P.s "coffre")
, P.map Merchant (P.s "marchand")
, P.map NewLoot (P.s "nouveau-tresor")
]