diff --git a/elm.json b/elm.json index 88d9b11..d743ede 100644 --- a/elm.json +++ b/elm.json @@ -11,6 +11,7 @@ "elm/html": "1.0.0", "elm/http": "2.0.0", "elm/json": "1.1.3", + "elm/svg": "1.0.1", "elm/url": "1.0.0" }, "indirect": { diff --git a/main.js b/main.js index 9574263..1280781 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 = F5( - function (navKey, route, error, menuOpen, selectedItems) { - return {error: error, menuOpen: menuOpen, navKey: navKey, route: route, selectedItems: selectedItems}; +var $author$project$Main$State = F6( + function (navKey, route, error, menuOpen, selection, activeMode) { + return {activeMode: activeMode, error: error, menuOpen: menuOpen, navKey: navKey, route: route, selection: selection}; }); var $author$project$Main$Player = F4( function (id, name, debt, wealth) { @@ -6452,7 +6452,7 @@ var $author$project$Main$init = F3( return _Utils_Tuple2( A5( $author$project$Main$Model, - A5($author$project$Main$State, key, route, '', false, $elm$core$Maybe$Nothing), + A6($author$project$Main$State, key, route, '', false, $elm$core$Maybe$Nothing, $elm$core$Maybe$Nothing), $author$project$Main$blankPlayer, $elm$core$Maybe$Nothing, $elm$core$Maybe$Nothing, @@ -6464,6 +6464,10 @@ var $elm$core$Platform$Sub$none = $elm$core$Platform$Sub$batch(_List_Nil); var $author$project$Main$subscriptions = function (_v0) { return $elm$core$Platform$Sub$none; }; +var $author$project$Main$Add = {$: 'Add'}; +var $author$project$Main$ModeSwitched = function (a) { + return {$: 'ModeSwitched', a: a}; +}; var $elm$core$Set$Set_elm_builtin = function (a) { return {$: 'Set_elm_builtin', a: a}; }; @@ -6597,31 +6601,28 @@ var $author$project$Main$update = F2( } case 'UrlChanged': var url = msg.a; + var state = model.state; var route = A2($elm$url$Url$Parser$parse, $author$project$Main$routeParser, url); if (route.$ === 'Just') { var page = route.a; - return _Utils_Tuple2( + return A2( + $author$project$Main$update, function () { - var state = model.state; - return _Utils_update( - model, - { - state: _Utils_update( - state, - { - route: page, - selectedItems: $elm$core$Maybe$Just($elm$core$Set$empty) - }) - }); - }(), - function () { - if (page.$ === 'GroupLoot') { - return $elm$core$Platform$Cmd$none; + if (page.$ === 'NewLoot') { + return $author$project$Main$ModeSwitched( + $elm$core$Maybe$Just($author$project$Main$Add)); } else { - var a = page; - return $elm$core$Platform$Cmd$none; + var other = page; + return $author$project$Main$ModeSwitched($elm$core$Maybe$Nothing); } - }()); + }(), + _Utils_update( + model, + { + state: _Utils_update( + state, + {route: page}) + })); } else { return _Utils_Tuple2( A2($author$project$Main$setError, 'Invalid route', model), @@ -6690,7 +6691,7 @@ var $author$project$Main$update = F2( model), $elm$core$Platform$Cmd$none); } - default: + case 'LootViewItemSwitched': var id = msg.a; var state = model.state; return _Utils_Tuple2( @@ -6700,16 +6701,57 @@ var $author$project$Main$update = F2( state: _Utils_update( state, { - selectedItems: A2( + selection: A2( $elm$core$Debug$log, 'new selection', - A2($author$project$Main$switchSelectionState, id, state.selectedItems)) + A2($author$project$Main$switchSelectionState, id, state.selection)) }) }), $elm$core$Platform$Cmd$none); + default: + var newMode = msg.a; + var state = model.state; + var _v7 = function () { + if (newMode.$ === 'Nothing') { + return _Utils_Tuple2($elm$core$Maybe$Nothing, $elm$core$Platform$Cmd$none); + } else { + var _new = newMode; + if ((_new.$ === 'Just') && (_new.a.$ === 'Confirm')) { + var _v10 = _new.a; + return _Utils_Tuple2($elm$core$Maybe$Nothing, $elm$core$Platform$Cmd$none); + } else { + var other = _new; + return _Utils_Tuple2(_new, $elm$core$Platform$Cmd$none); + } + } + }(); + var nextMode = _v7.a; + var cmd = _v7.b; + return _Utils_Tuple2( + _Utils_update( + model, + { + state: _Utils_update( + state, + { + activeMode: nextMode, + selection: function () { + if (nextMode.$ === 'Nothing') { + return $elm$core$Maybe$Nothing; + } else { + return $elm$core$Maybe$Just($elm$core$Set$empty); + } + }() + }) + }), + cmd); } }); -var $elm$html$Html$article = _VirtualDom_node('article'); +var $author$project$Main$Buy = {$: 'Buy'}; +var $author$project$Main$Confirm = {$: 'Confirm'}; +var $author$project$Main$Grab = {$: 'Grab'}; +var $author$project$Main$Sell = {$: 'Sell'}; +var $elm$html$Html$button = _VirtualDom_node('button'); var $elm$json$Json$Encode$string = _Json_wrap; var $elm$html$Html$Attributes$stringProperty = F2( function (key, string) { @@ -6719,16 +6761,8 @@ var $elm$html$Html$Attributes$stringProperty = F2( $elm$json$Json$Encode$string(string)); }); var $elm$html$Html$Attributes$class = $elm$html$Html$Attributes$stringProperty('className'); -var $elm$html$Html$hr = _VirtualDom_node('hr'); -var $elm$html$Html$p = _VirtualDom_node('p'); -var $elm$html$Html$section = _VirtualDom_node('section'); -var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text; -var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text; -var $author$project$Main$PlayerChanged = function (a) { - return {$: 'PlayerChanged', a: a}; -}; -var $elm$html$Html$a = _VirtualDom_node('a'); -var $elm$html$Html$div = _VirtualDom_node('div'); +var $elm$svg$Svg$Attributes$class = _VirtualDom_attribute('class'); +var $elm$html$Html$i = _VirtualDom_node('i'); var $elm$virtual_dom$VirtualDom$Normal = function (a) { return {$: 'Normal', a: a}; }; @@ -6746,6 +6780,98 @@ var $elm$html$Html$Events$onClick = function (msg) { 'click', $elm$json$Json$Decode$succeed(msg)); }; +var $elm$html$Html$span = _VirtualDom_node('span'); +var $author$project$Main$actionButton = F4( + function (mode, t, icon, color) { + return A2( + $elm$html$Html$button, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('button is-rounded is-' + color), + $elm$html$Html$Events$onClick( + $author$project$Main$ModeSwitched(mode)) + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$span, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('icon') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$i, + _List_fromArray( + [ + $elm$svg$Svg$Attributes$class('fas fa-' + icon) + ]), + _List_Nil) + ])) + ])); + }); +var $elm$html$Html$article = _VirtualDom_node('article'); +var $elm$html$Html$div = _VirtualDom_node('div'); +var $elm$html$Html$hr = _VirtualDom_node('hr'); +var $elm$html$Html$p = _VirtualDom_node('p'); +var $elm$html$Html$section = _VirtualDom_node('section'); +var $elm$virtual_dom$VirtualDom$text = _VirtualDom_text; +var $elm$html$Html$text = $elm$virtual_dom$VirtualDom$text; +var $author$project$Main$stackedIcon = function (name) { + return A2( + $elm$html$Html$span, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('icon is-large has-text-dark') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$span, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('fa-stack') + ]), + _List_fromArray( + [ + A2( + $elm$html$Html$i, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('fas fa-circle fa-stack-2x') + ]), + _List_Nil), + A2( + $elm$html$Html$i, + _List_fromArray( + [ + $elm$html$Html$Attributes$class(name + ' fa-inverse fa-stack-1x') + ]), + _List_Nil), + $elm$html$Html$text(name) + ])) + ])); +}; +var $author$project$Main$debugSandbox = _List_fromArray( + [ + $author$project$Main$stackedIcon('fas fa-coins'), + $author$project$Main$stackedIcon('fab fa-d-and-d'), + $author$project$Main$stackedIcon('fas fa-praying-hands'), + $author$project$Main$stackedIcon('fas fa-gem'), + $author$project$Main$stackedIcon('fas fa-pen'), + $author$project$Main$stackedIcon('fas fa-percentage'), + $author$project$Main$stackedIcon('fas fa-store-alt'), + $author$project$Main$stackedIcon('fas fa-cart-plus'), + $author$project$Main$stackedIcon('fas fa-angry'), + $author$project$Main$stackedIcon('fas fa-plus'), + $author$project$Main$stackedIcon('fas fa-tools'), + $author$project$Main$stackedIcon('fas fa-search') + ]); +var $author$project$Main$PlayerChanged = function (a) { + return {$: 'PlayerChanged', a: a}; +}; +var $elm$html$Html$a = _VirtualDom_node('a'); var $author$project$Main$debugSwitchPlayers = A2( $elm$html$Html$div, _List_fromArray( @@ -6839,8 +6965,20 @@ var $author$project$Main$viewDebugSection = function (model) { _List_fromArray( [ $elm$html$Html$text( - 'Selection : ' + $elm$core$Debug$toString(model.state.selectedItems)) - ])) + 'Active Mode : ' + $elm$core$Debug$toString(model.state.activeMode)) + ])), + 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.selection)) + ])), + A2($elm$html$Html$p, _List_Nil, $author$project$Main$debugSandbox) ])); }; var $elm$virtual_dom$VirtualDom$attribute = F2( @@ -6858,7 +6996,6 @@ var $elm$html$Html$Attributes$href = function (url) { _VirtualDom_noJavaScriptUri(url)); }; var $elm$html$Html$nav = _VirtualDom_node('nav'); -var $elm$html$Html$span = _VirtualDom_node('span'); var $author$project$Main$viewHeaderBar = function (model) { return A2( $elm$html$Html$nav, @@ -6994,13 +7131,66 @@ var $elm$html$Html$Attributes$classList = function (classes) { $elm$core$Tuple$first, A2($elm$core$List$filter, $elm$core$Tuple$second, classes)))); }; +var $elm$core$String$fromFloat = _String_fromNumber; +var $author$project$Main$controlsRenderer = F2( + function (mode, item) { + switch (mode.$) { + case 'Buy': + return 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') + ])); + case 'Sell': + return A2( + $elm$html$Html$p, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level-item') + ]), + _List_fromArray( + [ + $elm$html$Html$text( + $elm$core$String$fromFloat(item.base_price / 2) + 'po') + ])); + case 'Grab': + return A2( + $elm$html$Html$p, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level-item') + ]), + _List_fromArray( + [ + $elm$html$Html$text('Grab') + ])); + case 'Add': + return A2( + $elm$html$Html$p, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level-item') + ]), + _List_fromArray( + [ + $elm$html$Html$text('New !') + ])); + default: + return $elm$html$Html$text(''); + } + }); var $elm$html$Html$input = _VirtualDom_node('input'); var $author$project$Main$isSelected = F2( function (id, selection) { return A2($elm$core$Set$member, id, selection); }); var $elm$html$Html$label = _VirtualDom_node('label'); -var $elm$core$Basics$not = _Basics_not; var $elm$json$Json$Decode$at = F2( function (fields, decoder) { return A3($elm$core$List$foldr, $elm$json$Json$Decode$field, decoder, fields); @@ -7017,23 +7207,53 @@ var $elm$html$Html$Events$onCheck = function (tagger) { 'change', A2($elm$json$Json$Decode$map, tagger, $elm$html$Html$Events$targetChecked)); }; +var $elm$core$List$singleton = function (value) { + return _List_fromArray( + [value]); +}; var $elm$html$Html$td = _VirtualDom_node('td'); var $elm$html$Html$tr = _VirtualDom_node('tr'); var $elm$html$Html$Attributes$type_ = $elm$html$Html$Attributes$stringProperty('type'); -var $author$project$Main$viewItemTableRow = F2( - function (selection, item) { - var _v0 = function () { +var $author$project$Main$viewItemTableRow = F3( + function (selection, activeMode, item) { + var selected = function () { if (selection.$ === 'Just') { var s = selection.a; - return _Utils_Tuple2( - true, - A2($author$project$Main$isSelected, item.id, s)); + return A2($author$project$Main$isSelected, item.id, s); } else { - return _Utils_Tuple2(false, false); + return false; + } + }(); + var levelRight = function () { + if (activeMode.$ === 'Nothing') { + return _List_Nil; + } else { + var mode = activeMode.a; + return $elm$core$List$singleton( + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level-right') + ]), + _List_fromArray( + [ + A2($author$project$Main$controlsRenderer, mode, item), + A2( + $elm$html$Html$input, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('checkbox level-item'), + $elm$html$Html$Attributes$type_('checkbox'), + $elm$html$Html$Events$onCheck( + function (v) { + return $author$project$Main$LootViewItemSwitched(item.id); + }) + ]), + _List_Nil) + ]))); } }(); - var canSelect = _v0.a; - var selected = _v0.b; return A2( $elm$html$Html$tr, _List_fromArray( @@ -7057,75 +7277,43 @@ var $author$project$Main$viewItemTableRow = F2( [ $elm$html$Html$Attributes$class('level checkbox') ]), - _List_fromArray( - [ - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('level-left') - ]), - _List_fromArray( + $elm$core$List$concat( + _List_fromArray( + [ + _List_fromArray( [ A2( - $elm$html$Html$p, + $elm$html$Html$div, _List_fromArray( [ - $elm$html$Html$Attributes$class('level-item') + $elm$html$Html$Attributes$class('level-left') ]), _List_fromArray( [ - $elm$html$Html$text(item.name) - ])) - ])), - A2( - $elm$html$Html$div, - _List_fromArray( - [ - $elm$html$Html$Attributes$classList( - _List_fromArray( - [ - _Utils_Tuple2('level-right', true), - _Utils_Tuple2('is-hidden', !canSelect) + A2( + $elm$html$Html$p, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('level-item') + ]), + _List_fromArray( + [ + $elm$html$Html$text(item.name) + ])) ])) ]), - _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 is-hidden'), - $elm$html$Html$Attributes$type_('checkbox'), - $elm$html$Html$Events$onCheck( - function (v) { - return $author$project$Main$LootViewItemSwitched(item.id); - }) - ]), - _List_Nil) - ])) - ])) + levelRight + ]))) ])) ])); }); -var $author$project$Main$viewLoot = F2( - function (items, selection) { +var $author$project$Main$viewLoot = F3( + function (items, selection, activeMode) { return A2( $elm$html$Html$table, _List_fromArray( [ - $elm$html$Html$Attributes$class('table is-fullwidth is-striped') + $elm$html$Html$Attributes$class('table is-fullwidth is-striped is-light') ]), _Utils_ap( _List_fromArray( @@ -7149,10 +7337,9 @@ var $author$project$Main$viewLoot = F2( ]), A2( $elm$core$List$map, - $author$project$Main$viewItemTableRow(selection), + A2($author$project$Main$viewItemTableRow, selection, activeMode), items))); }); -var $elm$html$Html$i = _VirtualDom_node('i'); var $author$project$Main$showWealthField = F2( function (name, value) { return A2( @@ -7195,70 +7382,8 @@ var $author$project$Main$showWealth = function (wealth) { A2($author$project$Main$showWealthField, 'cp', wealth.cp) ]); }; -var $elm$html$Html$button = _VirtualDom_node('button'); -var $author$project$Main$actionButton = F3( - function (t, n, c) { - return A2( - $elm$html$Html$button, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('button is-rounded is-' + c) - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$span, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('icon') - ]), - _List_fromArray( - [ - A2( - $elm$html$Html$i, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('fas fa-' + n) - ]), - _List_Nil) - ])), - A2( - $elm$html$Html$span, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text(t) - ])) - ])); - }); -var $author$project$Main$viewPlayerAction = F2( - function (player, route) { - switch (route.$) { - case 'PlayerChest': - return _List_fromArray( - [ - A3($author$project$Main$actionButton, 'Vendre', 'coins', 'danger') - ]); - case 'GroupLoot': - return _List_fromArray( - [ - A3($author$project$Main$actionButton, 'Demander', 'coins', 'primary') - ]); - case 'Merchant': - return _List_fromArray( - [ - A3($author$project$Main$actionButton, 'Acheter', 'coins', 'success') - ]); - default: - return _List_fromArray( - [ - A3($author$project$Main$actionButton, 'Valider', 'coins', 'primary'), - A3($author$project$Main$actionButton, 'Annuler', 'coins', 'danger') - ]); - } - }); var $author$project$Main$viewPlayerBar = F2( - function (player, route) { + function (player, actionControls) { return A2( $elm$html$Html$section, _List_fromArray( @@ -7333,7 +7458,7 @@ var $author$project$Main$viewPlayerBar = F2( [ $elm$html$Html$Attributes$class('level-right') ]), - A2($author$project$Main$viewPlayerAction, player, route)) + actionControls) ])); }); var $author$project$Main$viewSearchBar = A2( @@ -7353,82 +7478,114 @@ var $elm$core$Maybe$withDefault = F2( } }); var $author$project$Main$view = function (model) { + var actionControls = function () { + var _v2 = model.state.activeMode; + if (_v2.$ === 'Just') { + var mode = _v2.a; + return _List_fromArray( + [ + A2( + $elm$html$Html$div, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('buttons') + ]), + _List_fromArray( + [ + A4( + $author$project$Main$actionButton, + $elm$core$Maybe$Just($author$project$Main$Confirm), + 'Valider', + 'plus', + 'primary'), + A4($author$project$Main$actionButton, $elm$core$Maybe$Nothing, 'Annuler', 'coins', 'danger') + ])) + ]); + } else { + var _v3 = model.state.route; + switch (_v3.$) { + case 'PlayerChest': + return _List_fromArray( + [ + A4( + $author$project$Main$actionButton, + $elm$core$Maybe$Just($author$project$Main$Sell), + '', + 'coins', + 'danger') + ]); + case 'GroupLoot': + return _List_fromArray( + [ + A4( + $author$project$Main$actionButton, + $elm$core$Maybe$Just($author$project$Main$Grab), + 'Demander', + 'coins', + 'primary') + ]); + case 'Merchant': + return _List_fromArray( + [ + A4( + $author$project$Main$actionButton, + $elm$core$Maybe$Just($author$project$Main$Buy), + '', + 'coins', + 'success') + ]); + default: + return _List_Nil; + } + } + }(); + var _v0 = function () { + var _v1 = model.state.route; + switch (_v1.$) { + case 'PlayerChest': + return _Utils_Tuple2( + 'Mon coffre', + A2($elm$core$Maybe$withDefault, _List_Nil, model.loot)); + case 'GroupLoot': + return _Utils_Tuple2( + 'Coffre de groupe', + A2($elm$core$Maybe$withDefault, _List_Nil, model.groupLoot)); + case 'Merchant': + return _Utils_Tuple2( + 'Marchand', + A2($elm$core$Maybe$withDefault, _List_Nil, model.merchantItems)); + default: + return _Utils_Tuple2('Nouveau trésor :)', _List_Nil); + } + }(); + var header = _v0.a; + var shownLoot = _v0.b; return { body: _List_fromArray( [ $author$project$Main$viewHeaderBar(model), - A2($author$project$Main$viewPlayerBar, model.player, model.state.route), + A2($author$project$Main$viewPlayerBar, model.player, actionControls), A2( $elm$html$Html$article, _List_fromArray( [ $elm$html$Html$Attributes$class('section container') ]), - function () { - var _v0 = model.state.route; - switch (_v0.$) { - case 'PlayerChest': - return _List_fromArray( - [ - A2( - $elm$html$Html$p, - _List_fromArray( - [ - $elm$html$Html$Attributes$class('heading') - ]), - _List_fromArray( - [ - $elm$html$Html$text('Mon Coffre') - ])), - $author$project$Main$viewSearchBar, - A2( - $author$project$Main$viewLoot, - A2($elm$core$Maybe$withDefault, _List_Nil, model.loot), - model.state.selectedItems) - ]); - case 'GroupLoot': - return _List_fromArray( - [ - A2( - $elm$html$Html$p, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text('Coffre de groupe') - ])), - A2( - $author$project$Main$viewLoot, - A2($elm$core$Maybe$withDefault, _List_Nil, model.groupLoot), - model.state.selectedItems) - ]); - case 'Merchant': - return _List_fromArray( - [ - A2( - $elm$html$Html$p, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text('Acheter des objets') - ])), - A2( - $author$project$Main$viewLoot, - A2($elm$core$Maybe$withDefault, _List_Nil, model.merchantItems), - model.state.selectedItems) - ]); - default: - return _List_fromArray( - [ - A2( - $elm$html$Html$p, - _List_Nil, - _List_fromArray( - [ - $elm$html$Html$text('Nouveau trésor :) ') - ])) - ]); - } - }()), + _List_fromArray( + [ + A2( + $elm$html$Html$p, + _List_fromArray( + [ + $elm$html$Html$Attributes$class('heading') + ]), + _List_fromArray( + [ + $elm$html$Html$text(header) + ])), + $author$project$Main$viewSearchBar, + A3($author$project$Main$viewLoot, shownLoot, model.state.selection, model.state.activeMode) + ])), A2($elm$html$Html$hr, _List_Nil, _List_Nil), A2( $elm$html$Html$section, diff --git a/src/Main.elm b/src/Main.elm index 871c584..7127ec6 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -7,6 +7,7 @@ import Url import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..) +import Svg.Attributes import Http import Json.Decode exposing (Decoder, field, list, string, int) import Url.Parser as P exposing (Parser, (), oneOf, s) @@ -35,7 +36,8 @@ type alias State = , route : Route , error : String , menuOpen : Bool - , selectedItems : Maybe Selection + , selection : Maybe Selection + , activeMode : Maybe ViewMode } type alias Model = @@ -53,7 +55,7 @@ init flags url key = Just r -> r Nothing -> PlayerChest in - ( Model (State key route "" False Nothing) blankPlayer Nothing Nothing Nothing, fetchInitialData 0) + ( Model (State key route "" False Nothing Nothing) blankPlayer Nothing Nothing Nothing, fetchInitialData 0) fetchInitialData : Int -> Cmd Msg @@ -160,6 +162,7 @@ type Msg | GotPlayer (Result Http.Error Player) | GotLoot ToChest (Result Http.Error Loot) | LootViewItemSwitched Int + | ModeSwitched (Maybe ViewMode) update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = @@ -177,19 +180,16 @@ update msg model = UrlChanged url -> let route = P.parse routeParser url + state = model.state in case route of Just page -> - ( let - state = model.state - in - { model | state = - { state | route = page , selectedItems = Just Set.empty} - } - , case page of - GroupLoot -> Cmd.none - a -> Cmd.none - ) + { model | state = { state | route = page }} + |> update (case page of + -- Directly enter add mode on NewLoot view + NewLoot -> ModeSwitched (Just Add) + other -> ModeSwitched Nothing + ) Nothing -> ( setError "Invalid route" model, Cmd.none ) @@ -227,9 +227,35 @@ update msg model = state = model.state in ( { model | state = - { state | selectedItems = Debug.log "new selection" (switchSelectionState id state.selectedItems) }} + { state | selection = Debug.log "new selection" (switchSelectionState id state.selection) }} , Cmd.none ) + ModeSwitched newMode -> + let + state = model.state + + (nextMode, cmd) = + case newMode of + Nothing -> -- Cancel action + (Nothing, Cmd.none) + new -> + case new of + Just Confirm -> + -- Confirm action and exit + (Nothing, Cmd.none) + other -> + -- Enter mode + (new, Cmd.none) + + in + ( { model | state = + { state | activeMode = nextMode + , selection = case nextMode of + Nothing -> Nothing + Just _ -> Just Set.empty + }} + , cmd) + -- ERRORS setError : String -> Model -> Model @@ -269,33 +295,56 @@ subscriptions _ = -- VIEWS --- +type ViewMode + = Sell + | Buy + | Grab + | Add + | Confirm -- Confirm action and exit mode + +actionButton mode t icon color = + button [ class <| "button is-rounded is-" ++ color + , onClick (ModeSwitched mode) ] + [ span [ class "icon" ] [ i [ Svg.Attributes.class <| "fas fa-" ++ icon ] [] ] + ] + view : Model -> Browser.Document Msg view model = + let + (header, shownLoot) = + case model.state.route of + PlayerChest -> + ("Mon coffre", Maybe.withDefault [] model.loot) + GroupLoot -> + ("Coffre de groupe", Maybe.withDefault [] model.groupLoot) + Merchant -> + ("Marchand", Maybe.withDefault [] model.merchantItems) + NewLoot -> + ("Nouveau trésor :)", [] ) + actionControls = + case model.state.activeMode of + Just mode -> -- When a mode is active + [ div [class "buttons"] + [actionButton (Just Confirm) "Valider" "plus" "primary" + , actionButton Nothing "Annuler" "coins" "danger"] + ] + Nothing -> -- Buttons to enter mode + case model.state.route of + PlayerChest -> [actionButton (Just Sell) "" "coins" "danger"] + GroupLoot -> [actionButton (Just Grab) "Demander" "coins" "primary"] + Merchant -> [actionButton (Just Buy) "" "coins" "success"] + NewLoot -> [] + + in { title = "Loot-a-lot in ELM" , body = [ viewHeaderBar model - , viewPlayerBar model.player model.state.route + , viewPlayerBar model.player actionControls , article [class "section container"] - (case model.state.route of - PlayerChest -> - [ p [class "heading"] [text "Mon Coffre"] - , viewSearchBar - , viewLoot (Maybe.withDefault [] model.loot) model.state.selectedItems - ] - - GroupLoot -> - [ p [] [text "Coffre de groupe"] - , viewLoot (Maybe.withDefault [] model.groupLoot) model.state.selectedItems - ] - - Merchant -> - [ p [] [text "Acheter des objets"] - , viewLoot (Maybe.withDefault [] model.merchantItems) model.state.selectedItems - ] - - NewLoot -> - [ p [] [text "Nouveau trésor :) "] ] - ) + [ p [class "heading"] [text header] + , viewSearchBar + , viewLoot shownLoot model.state.selection model.state.activeMode + ] , hr [] [] , section [class "container"] [viewDebugSection model] ] @@ -306,36 +355,55 @@ view model = isSelected id selection = Set.member id selection -viewLoot : Loot -> Maybe Selection -> Html Msg -viewLoot items selection = - table [ class "table is-fullwidth is-striped"] +viewLoot : Loot -> Maybe Selection -> Maybe ViewMode -> Html Msg +viewLoot items selection activeMode = + table [ class "table is-fullwidth is-striped is-light"] ([ thead [class "table-header"] [ th [] [text "Nom"] ] ] - ++ List.map (viewItemTableRow selection) items + ++ List.map (viewItemTableRow selection activeMode) items ) +controlsRenderer : ViewMode -> Item -> Html Msg +controlsRenderer mode item = + case mode of + Buy -> p [class "level-item"] [ text (String.fromInt item.base_price ++ "po")] + Sell -> p [class "level-item"] [ text (String.fromFloat (toFloat item.base_price / 2) ++ "po")] + Grab -> p [class "level-item"] [ text "Grab" ] + Add -> p [class "level-item"] [ text "New !" ] + Confirm -> text "" -viewItemTableRow selection item = +viewItemTableRow : Maybe Selection -> Maybe ViewMode -> Item -> Html Msg +viewItemTableRow selection activeMode item = let - (canSelect, selected) = + selected = case selection of Just s -> - (True, isSelected item.id s) + isSelected item.id s Nothing -> - (False, False) + False + + levelRight = + case activeMode of + Nothing -> [] + Just mode -> List.singleton ( + div [ class "level-right" ] + [ controlsRenderer mode item + , input [ class "checkbox level-item" + , type_ "checkbox" + , onCheck (\v -> LootViewItemSwitched item.id) + ] [] + ]) in tr [ classList [ ("is-selected", selected) ] ] [ td [] [ label [ class "level checkbox" ] - [ div [ class "level-left" ] - [ p [class "level-item"] [ text item.name ] - ] - , div [ classList [("level-right", True), ("is-hidden", not canSelect)]] - [ p [class "level-item"] [ text (String.fromInt item.base_price ++ "po") ] - , input [class "checkbox level-item", type_ "checkbox", onCheck (\v -> LootViewItemSwitched item.id)] [] - ] - ] + (List.concat [[ + div [ class "level-left" ] + [ p [class "level-item"] [ text item.name ]] + ] + , levelRight + ]) ] ] @@ -348,9 +416,34 @@ 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)] + , p [class "panel-block"] [text ("Active Mode : " ++ Debug.toString model.state.activeMode)] + , p [class "panel-block"] [text ("Selection : " ++ Debug.toString model.state.selection)] + , p [] debugSandbox ] +stackedIcon name = + span [class "icon is-large has-text-dark"] + [ span [ class "fa-stack" ] + [ i [ class "fas fa-circle fa-stack-2x" ] [] + , i [ class (name ++ " fa-inverse fa-stack-1x") ] [] + , text name ] + ] + +debugSandbox = + [ stackedIcon "fas fa-coins" + , stackedIcon "fab fa-d-and-d" + , stackedIcon "fas fa-praying-hands" + , stackedIcon "fas fa-gem" + , stackedIcon "fas fa-pen" + , stackedIcon "fas fa-percentage" + , stackedIcon "fas fa-store-alt" + , stackedIcon "fas fa-cart-plus" + , stackedIcon "fas fa-angry" + , stackedIcon "fas fa-plus" + , stackedIcon "fas fa-tools" + , stackedIcon "fas fa-search" + ] + debugSwitchPlayers : Html Msg debugSwitchPlayers = div [ class "panel-tabs" ] @@ -392,8 +485,8 @@ viewHeaderBar model = -- PLAYER BAR -viewPlayerBar : Player -> Route -> Html Msg -viewPlayerBar player route = +viewPlayerBar : Player -> List (Html Msg)-> Html Msg +viewPlayerBar player actionControls = section [ class "level container is-mobile box" ] [ div [class "level-left"] ([div [ class "level-item" ] @@ -410,22 +503,9 @@ viewPlayerBar player route = [] ) ) - , div [class "level-right"] (viewPlayerAction player route) + , div [class "level-right"] actionControls ] -actionButton t n c = button [ class ("button is-rounded is-" ++ c) ] - [ span [ class "icon" ] [ i [ class ("fas fa-" ++ n) ] [] ] - , span [] [ text t ] - ] - -viewPlayerAction : Player -> Route -> List (Html Msg) -viewPlayerAction player route = - case route of - PlayerChest -> [actionButton "Vendre" "coins" "danger"] - GroupLoot -> [actionButton "Demander" "coins" "primary"] - Merchant -> [actionButton "Acheter" "coins" "success"] - NewLoot -> [actionButton "Valider" "coins" "primary", actionButton "Annuler" "coins" "danger"] - showWealth : Wealth -> List (Html Msg) showWealth wealth =