From 68c8761c3d42c01b2f53eb1c43d6e76054409989 Mon Sep 17 00:00:00 2001 From: Artus Date: Sat, 2 Nov 2019 16:09:00 +0100 Subject: [PATCH] works on items selection --- main.js | 356 +++++++++++++++++++++++++++++++++++++++++++-------- src/Main.elm | 112 +++++++++++++--- 2 files changed, 397 insertions(+), 71 deletions(-) diff --git a/main.js b/main.js index e6fd45b..9799e4f 100644 --- a/main.js +++ b/main.js @@ -5302,9 +5302,9 @@ var $author$project$Main$Model = F5( return {groupLoot: groupLoot, loot: loot, merchantItems: merchantItems, player: player, state: state}; }); var $author$project$Main$PlayerChest = {$: 'PlayerChest'}; -var $author$project$Main$State = F4( - function (navKey, route, error, menuOpen) { - return {error: error, menuOpen: menuOpen, navKey: navKey, route: route}; +var $author$project$Main$State = F5( + function (navKey, route, error, menuOpen, selectedItems) { + return {error: error, menuOpen: menuOpen, navKey: navKey, route: route, selectedItems: selectedItems}; }); var $author$project$Main$Player = F4( function (id, name, debt, wealth) { @@ -5321,9 +5321,11 @@ var $author$project$Main$blankPlayer = A4( 0, A4($author$project$Main$Wealth, 0, 0, 0, 0)); var $elm$core$Platform$Cmd$batch = _Platform_batch; -var $author$project$Main$GotLoot = function (a) { - return {$: 'GotLoot', a: a}; -}; +var $author$project$Main$GotLoot = F2( + function (a, b) { + return {$: 'GotLoot', a: a, b: b}; + }); +var $author$project$Main$OfGroup = {$: 'OfGroup'}; var $elm$json$Json$Decode$decodeString = _Json_runOnString; var $elm$http$Http$BadStatus_ = F2( function (a, b) { @@ -6130,12 +6132,30 @@ var $author$project$Main$lootDecoder = $elm$json$Json$Decode$list($author$projec var $author$project$Main$valueDecoder = function (thenDecoder) { return A2($elm$json$Json$Decode$field, 'value', thenDecoder); }; +var $author$project$Main$fetchGroupLoot = $elm$http$Http$get( + { + expect: A2( + $elm$http$Http$expectJson, + $author$project$Main$GotLoot($author$project$Main$OfGroup), + $author$project$Main$valueDecoder($author$project$Main$lootDecoder)), + url: 'http://localhost:8088/api/players/0/loot' + }); +var $author$project$Main$OfShop = {$: 'OfShop'}; +var $author$project$Main$fetchShopInventory = $elm$http$Http$get( + { + expect: A2( + $elm$http$Http$expectJson, + $author$project$Main$GotLoot($author$project$Main$OfShop), + $author$project$Main$valueDecoder($author$project$Main$lootDecoder)), + url: 'http://localhost:8088/api/items' + }); +var $author$project$Main$OfPlayer = {$: 'OfPlayer'}; var $author$project$Main$fetchLoot = function (id) { return $elm$http$Http$get( { expect: A2( $elm$http$Http$expectJson, - $author$project$Main$GotLoot, + $author$project$Main$GotLoot($author$project$Main$OfPlayer), $author$project$Main$valueDecoder($author$project$Main$lootDecoder)), url: 'http://localhost:8088/api/players/' + ($elm$core$String$fromInt(id) + '/loot') }); @@ -6176,6 +6196,15 @@ var $author$project$Main$initPlayer = function (id) { $author$project$Main$fetchLoot(id) ])); }; +var $author$project$Main$fetchInitialData = function (playerId) { + return $elm$core$Platform$Cmd$batch( + _List_fromArray( + [ + $author$project$Main$initPlayer(playerId), + $author$project$Main$fetchShopInventory, + $author$project$Main$fetchGroupLoot + ])); +}; var $elm$url$Url$Parser$State = F5( function (visited, unvisited, params, frag, value) { return {frag: frag, params: params, unvisited: unvisited, value: value, visited: visited}; @@ -6423,12 +6452,12 @@ var $author$project$Main$init = F3( return _Utils_Tuple2( A5( $author$project$Main$Model, - A4($author$project$Main$State, key, route, '', false), + A5($author$project$Main$State, key, route, '', false, _List_Nil), $author$project$Main$blankPlayer, $elm$core$Maybe$Nothing, $elm$core$Maybe$Nothing, $elm$core$Maybe$Nothing), - $author$project$Main$initPlayer(0)); + $author$project$Main$fetchInitialData(0)); }); var $elm$core$Platform$Sub$batch = _Platform_batch; var $elm$core$Platform$Sub$none = $elm$core$Platform$Sub$batch(_List_Nil); @@ -6455,6 +6484,30 @@ var $author$project$Main$setError = F2( {error: error}) }); }); +var $elm$core$Basics$not = _Basics_not; +var $author$project$Main$switchBooleanAt = function (idx) { + return F2( + function (i, value) { + return _Utils_eq(i, idx) ? (!value) : value; + }); +}; +var $author$project$Main$switchSelectionState = F2( + function (idx, model) { + var state = model.state; + var selection = model.state.selectedItems; + return _Utils_update( + model, + { + state: _Utils_update( + state, + { + selectedItems: A2( + $elm$core$List$indexedMap, + $author$project$Main$switchBooleanAt(idx), + selection) + }) + }); + }); var $elm$url$Url$addPort = F2( function (maybePort, starter) { if (maybePort.$ === 'Nothing') { @@ -6499,6 +6552,15 @@ var $elm$url$Url$toString = function (url) { _Utils_ap(http, url.host)), url.path))); }; +var $elm$core$Maybe$withDefault = F2( + function (_default, maybe) { + if (maybe.$ === 'Just') { + var value = maybe.a; + return value; + } else { + return _default; + } + }); var $author$project$Main$update = F2( function (msg, model) { switch (msg.$) { @@ -6531,7 +6593,36 @@ var $author$project$Main$update = F2( { state: _Utils_update( state, - {route: page}) + { + route: page, + selectedItems: function () { + switch (page.$) { + case 'GroupLoot': + return A2( + $elm$core$List$map, + function (v) { + return false; + }, + A2($elm$core$Maybe$withDefault, _List_Nil, model.groupLoot)); + case 'PlayerChest': + return A2( + $elm$core$List$map, + function (v) { + return false; + }, + A2($elm$core$Maybe$withDefault, _List_Nil, model.loot)); + case 'Merchant': + return A2( + $elm$core$List$map, + function (v) { + return false; + }, + A2($elm$core$Maybe$withDefault, _List_Nil, model.merchantItems)); + default: + return _List_Nil; + } + }() + }) }); }(), function () { @@ -6572,16 +6663,34 @@ var $author$project$Main$update = F2( model), $elm$core$Platform$Cmd$none); } - default: - var result = msg.a; + case 'GotLoot': + var dest = msg.a; + var result = msg.b; if (result.$ === 'Ok') { var loot = result.a; return _Utils_Tuple2( - _Utils_update( - model, - { - loot: $elm$core$Maybe$Just(loot) - }), + function () { + switch (dest.$) { + case 'OfPlayer': + return _Utils_update( + model, + { + loot: $elm$core$Maybe$Just(loot) + }); + case 'OfGroup': + return _Utils_update( + model, + { + groupLoot: $elm$core$Maybe$Just(loot) + }); + default: + return _Utils_update( + model, + { + merchantItems: $elm$core$Maybe$Just(loot) + }); + } + }(), $elm$core$Platform$Cmd$none); } else { var error = result.a; @@ -6592,6 +6701,11 @@ var $author$project$Main$update = F2( model), $elm$core$Platform$Cmd$none); } + default: + var idx = msg.a; + return _Utils_Tuple2( + A2($author$project$Main$switchSelectionState, idx, model), + $elm$core$Platform$Cmd$none); } }); var $elm$html$Html$article = _VirtualDom_node('article'); @@ -6714,6 +6828,17 @@ var $author$project$Main$viewDebugSection = function (model) { [ $elm$html$Html$text( 'Route : ' + $elm$core$Debug$toString(model.state.route)) + ])), + A2( + $elm$html$Html$p, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('panel-block') + ]), + _List_fromArray( + [ + $elm$html$Html$text( + 'Selection : ' + $elm$core$Debug$toString(model.state.selectedItems)) ])) ])); }; @@ -6738,7 +6863,7 @@ var $author$project$Main$viewHeaderBar = function (model) { $elm$html$Html$nav, _List_fromArray( [ - $elm$html$Html$Attributes$class('navbar'), + $elm$html$Html$Attributes$class('navbar container'), $elm$html$Html$Attributes$class('is-info') ]), _List_fromArray( @@ -6838,37 +6963,152 @@ var $author$project$Main$viewHeaderBar = function (model) { ])); }; var $elm$html$Html$table = _VirtualDom_node('table'); +var $elm$html$Html$th = _VirtualDom_node('th'); +var $elm$html$Html$thead = _VirtualDom_node('thead'); +var $author$project$Main$LootViewItemSwitched = function (a) { + return {$: 'LootViewItemSwitched', a: a}; +}; +var $elm$core$List$filter = F2( + function (isGood, list) { + return A3( + $elm$core$List$foldr, + F2( + function (x, xs) { + return isGood(x) ? A2($elm$core$List$cons, x, xs) : xs; + }), + _List_Nil, + list); + }); +var $elm$core$Tuple$second = function (_v0) { + var y = _v0.b; + return y; +}; +var $elm$html$Html$Attributes$classList = function (classes) { + return $elm$html$Html$Attributes$class( + A2( + $elm$core$String$join, + ' ', + A2( + $elm$core$List$map, + $elm$core$Tuple$first, + A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); +}; +var $elm$html$Html$input = _VirtualDom_node('input'); +var $elm$html$Html$label = _VirtualDom_node('label'); var $elm$html$Html$td = _VirtualDom_node('td'); var $elm$html$Html$tr = _VirtualDom_node('tr'); -var $author$project$Main$viewItemTableRow = function (item) { - return A2( - $elm$html$Html$tr, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('table') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$td, - _List_Nil, - _List_fromArray( - [ - A2( - $elm$html$Html$p, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text(item.name) - ])) - ])) - ])); -}; +var $elm$html$Html$Attributes$type_ = $elm$html$Html$Attributes$stringProperty('type'); +var $author$project$Main$viewItemTableRow = F3( + function (selected, idx, item) { + return A2( + $elm$html$Html$tr, + _List_fromArray( + [ + $elm$html$Html$Attributes$classList( + _List_fromArray( + [ + _Utils_Tuple2('is-selected', selected) + ])) + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$td, + _List_Nil, + _List_fromArray( + [ + A2( + $elm$html$Html$label, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level checkbox'), + $elm$html$Html$Events$onClick( + $author$project$Main$LootViewItemSwitched(idx)) + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level-left') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$p, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level-item') + ]), + _List_fromArray( + [ + $elm$html$Html$text(item.name) + ])) + ])), + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level-right') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$p, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level-item') + ]), + _List_fromArray( + [ + $elm$html$Html$text( + $elm$core$String$fromInt(item.base_price) + 'po') + ])), + A2( + $elm$html$Html$input, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('checkbox level-item'), + $elm$html$Html$Attributes$type_('checkbox') + ]), + _List_Nil) + ])) + ])) + ])) + ])); + }); var $author$project$Main$viewLoot = function (items) { return A2( $elm$html$Html$table, - _List_Nil, - A2($elm$core$List$map, $author$project$Main$viewItemTableRow, items)); + _List_fromArray( + [ + $elm$html$Html$Attributes$class('table is-fullwidth is-striped') + ]), + _Utils_ap( + _List_fromArray( + [ + A2( + $elm$html$Html$thead, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('table-header') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$th, + _List_Nil, + _List_fromArray( + [ + $elm$html$Html$text('Nom') + ])) + ])) + ]), + A2( + $elm$core$List$indexedMap, + $author$project$Main$viewItemTableRow(false), + items))); }; var $elm$html$Html$i = _VirtualDom_node('i'); var $author$project$Main$showWealthField = F2( @@ -6981,7 +7221,7 @@ var $author$project$Main$viewPlayerBar = F2( $elm$html$Html$section, _List_fromArray( [ - $elm$html$Html$Attributes$class('level is-mobile box') + $elm$html$Html$Attributes$class('level container is-mobile box') ]), _List_fromArray( [ @@ -7054,15 +7294,13 @@ var $author$project$Main$viewPlayerBar = F2( A2($author$project$Main$viewPlayerAction, player, route)) ])); }); -var $elm$core$Maybe$withDefault = F2( - function (_default, maybe) { - if (maybe.$ === 'Just') { - var value = maybe.a; - return value; - } else { - return _default; - } - }); +var $author$project$Main$viewSearchBar = A2( + $elm$html$Html$input, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('input') + ]), + _List_Nil); var $author$project$Main$view = function (model) { return { body: _List_fromArray( @@ -7083,11 +7321,15 @@ var $author$project$Main$view = function (model) { [ A2( $elm$html$Html$p, - _List_Nil, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('heading') + ]), _List_fromArray( [ $elm$html$Html$text('Mon Coffre') ])), + $author$project$Main$viewSearchBar, $author$project$Main$viewLoot( A2($elm$core$Maybe$withDefault, _List_Nil, model.loot)) ]); @@ -7113,7 +7355,9 @@ var $author$project$Main$view = function (model) { _List_fromArray( [ $elm$html$Html$text('Acheter des objets') - ])) + ])), + $author$project$Main$viewLoot( + A2($elm$core$Maybe$withDefault, _List_Nil, model.merchantItems)) ]); default: return _List_fromArray( diff --git a/src/Main.elm b/src/Main.elm index 67381ae..ad472b3 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -30,6 +30,7 @@ type alias State = , route : Route , error : String , menuOpen : Bool + , selectedItems : List Bool } type alias Model = @@ -47,9 +48,15 @@ init flags url key = Just r -> r Nothing -> PlayerChest in - ( Model (State key route "" False) blankPlayer Nothing Nothing Nothing, initPlayer 0) + ( Model (State key route "" False []) blankPlayer Nothing Nothing Nothing, fetchInitialData 0) +fetchInitialData : Int -> Cmd Msg +fetchInitialData playerId = + Cmd.batch [ initPlayer playerId + , fetchShopInventory + , fetchGroupLoot + ] -- PLAYER -- type alias Player = @@ -117,7 +124,22 @@ lootDecoder = fetchLoot id = Http.get { url = "http://localhost:8088/api/players/" ++ (String.fromInt id) ++ "/loot" - , expect = Http.expectJson GotLoot (valueDecoder lootDecoder)} + , expect = Http.expectJson (GotLoot OfPlayer) (valueDecoder lootDecoder)} + +fetchShopInventory = + Http.get + { url = "http://localhost:8088/api/items" + , expect = Http.expectJson (GotLoot OfShop) (valueDecoder lootDecoder)} + +fetchGroupLoot = + Http.get + { url = "http://localhost:8088/api/players/0/loot" + , expect = Http.expectJson (GotLoot OfGroup) (valueDecoder lootDecoder)} + +type ToChest + = OfPlayer + | OfGroup + | OfShop -- API Response -- valueDecoder : Decoder a -> Decoder a @@ -131,7 +153,8 @@ type Msg | UrlChanged Url.Url | PlayerChanged Int | GotPlayer (Result Http.Error Player) - | GotLoot (Result Http.Error Loot) + | GotLoot ToChest (Result Http.Error Loot) + | LootViewItemSwitched Int update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = @@ -153,7 +176,18 @@ update msg model = case route of Just page -> ( let state = model.state in - { model | state = { state | route = page }} + { model + | state = { state + | route = page + -- Reinitialize selectionList with url change + , selectedItems = + case page of + GroupLoot -> List.map (\v -> False) (Maybe.withDefault [] model.groupLoot) + PlayerChest -> List.map (\v -> False) (Maybe.withDefault [] model.loot) + Merchant -> List.map (\v -> False) (Maybe.withDefault [] model.merchantItems) + NewLoot -> [] + } + } , case page of GroupLoot -> Cmd.none a -> Cmd.none @@ -176,10 +210,13 @@ update msg model = , Cmd.none ) - GotLoot result -> + GotLoot dest result -> case result of Ok loot -> - ( { model | loot = Just loot} + ( case dest of + OfPlayer -> { model | loot = Just loot} + OfGroup -> { model | groupLoot = Just loot} + OfShop -> { model | merchantItems = Just loot} , Cmd.none ) Err error -> @@ -187,6 +224,9 @@ update msg model = , Cmd.none ) + LootViewItemSwitched idx -> + ( switchSelectionState idx model, Cmd.none ) + -- ERRORS setError : String -> Model -> Model @@ -204,6 +244,23 @@ printError error = Http.NetworkError -> "Le serveur ne répond pas" _ -> "Erreur inconnue" +-- STATE Utils + +switchBooleanAt idx = + (\i value -> + if i == idx then + not value + else + value + ) + +switchSelectionState idx model = + let + state = model.state + selection = model.state.selectedItems + in + { model | state = { state | selectedItems = List.indexedMap (switchBooleanAt idx) selection } } + -- SUBSCRIPTIONS -- subscriptions : Model -> Sub Msg @@ -224,7 +281,8 @@ view model = , article [class "section container"] (case model.state.route of PlayerChest -> - [ p [] [text "Mon Coffre"] + [ p [class "heading"] [text "Mon Coffre"] + , viewSearchBar , viewLoot (Maybe.withDefault [] model.loot) ] @@ -234,7 +292,9 @@ view model = ] Merchant -> - [ p [] [text "Acheter des objets"] ] + [ p [] [text "Acheter des objets"] + , viewLoot (Maybe.withDefault [] model.merchantItems) + ] NewLoot -> [ p [] [text "Nouveau trésor :) "] ] @@ -248,12 +308,27 @@ view model = viewLoot : Loot -> Html Msg viewLoot items = - table [] - (List.map viewItemTableRow items) + table [ class "table is-fullwidth is-striped"] + ([ thead [class "table-header"] + [ th [] [text "Nom"] ] + ] + ++ List.indexedMap (False |> viewItemTableRow) items + ) -viewItemTableRow item = - tr [class "table"] - [ td [] [p [] [text item.name]] + +viewItemTableRow selected idx item = + tr [ classList [ ("is-selected", selected) ] ] + [ td [] + [ label [ class "level checkbox", onClick (LootViewItemSwitched idx) ] + [ div [ class "level-left" ] + [ p [class "level-item"] [ text item.name ] + ] + , div [ class "level-right" ] + [ p [class "level-item"] [ text (String.fromInt item.base_price ++ "po") ] + , input [class "checkbox level-item", type_ "checkbox"] [] + ] + ] + ] ] -- DEBUG SECTION @@ -265,6 +340,7 @@ viewDebugSection model = , debugSwitchPlayers , p [class "panel-block has-text-danger"] [text model.state.error] , p [class "panel-block"] [text ("Route : " ++ Debug.toString model.state.route)] + , p [class "panel-block"] [text ("Selection : " ++ Debug.toString model.state.selectedItems)] ] debugSwitchPlayers : Html Msg @@ -279,7 +355,7 @@ debugSwitchPlayers = viewHeaderBar : Model -> Html Msg viewHeaderBar model = - nav [ class "navbar", class "is-info" ] + nav [ class "navbar container", class "is-info" ] [ div [ class "navbar-brand" ] [ a [ class "navbar-item", href "/"] [ text model.player.name ] @@ -310,7 +386,7 @@ viewHeaderBar model = viewPlayerBar : Player -> Route -> Html Msg viewPlayerBar player route = - section [ class "level is-mobile box" ] + section [ class "level container is-mobile box" ] [ div [class "level-left"] ([div [ class "level-item" ] [ span [ class "icon is-large" ] @@ -358,6 +434,12 @@ showWealthField name value = , p [class "heading"] [text name] ] +-- Search Bar + +viewSearchBar : Html Msg +viewSearchBar = + input [class "input"] [] + --- -- ROUTES ---