From 13d9378c358f898c9d9d962c67b51725bd2d29c6 Mon Sep 17 00:00:00 2001 From: Artus Date: Tue, 12 Nov 2019 15:58:07 +0100 Subject: [PATCH] adds AutoCompletion and Modal --- src/Page/Chest.elm | 172 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 155 insertions(+), 17 deletions(-) diff --git a/src/Page/Chest.elm b/src/Page/Chest.elm index f2dda91..aec9b75 100644 --- a/src/Page/Chest.elm +++ b/src/Page/Chest.elm @@ -29,6 +29,8 @@ type alias State = , mode : ActionMode , error : Maybe String , notification : Maybe String + , autoComplete : Loot + , newItem : Maybe Item -- Fetched on init , player : Api.Player @@ -56,7 +58,7 @@ type alias Model = init (Player navKey playerId) = ( Model navKey - (State False NoMode Nothing Nothing Api.blankPlayer [] [] [] []) + (State False NoMode Nothing Nothing [] Nothing Api.blankPlayer [] [] [] []) Route.PlayerLoot Nothing "" @@ -137,7 +139,7 @@ viewHeaderBar title model = [ div [ class "navbar-brand" ] [ a [ class "navbar-item", href "/" ] [ renderIcon { icon = "fab fa-d-and-d", size = "medium", ratio = "2x" } - , span [ class "title is-4" ] [ text title ] + , span [ class "title is-4", style "padding-left" "0.4em" ] [ text title ] ] , a [ class "navbar-burger is-active" ] [ span [ attribute "aria-hidden" "true" ] [] @@ -283,7 +285,7 @@ view model = activeMode -> Just (rowRendererForMode activeMode) in - [ viewHeaderBar model.state.player.name model + [ viewHeaderBar "Mon coffre" model , viewPlayerBar model.state.player renderControls , main_ [ class "container" ] @@ -450,20 +452,87 @@ viewItemTableRow isSelected canSelect rowRenderer item = -- +fromListModal isActive = + div [ class "modal", classList [ ( "is-active", isActive ) ] ] + [ div [ class "modal-background" ] [] + , div [ class "modal-card" ] + [ header [ class "modal-card-head" ] [ p [ class "modal-card-title" ] [ text "Liste d'objets" ] ] + , div [ class "modal-card-body" ] + [ textarea [ class "textarea" ] [] + ] + , div [ class "modal-card-foot" ] + [ button [ class "button" ] [ text "Ok" ] + , button [ class "button" ] [ text "Annuler" ] + ] + ] + ] + + +viewCompletionDropdown : Bool -> Loot -> Html Msg +viewCompletionDropdown shown results = + div + [ class "dropdown" + , classList [ ( "is-active", shown ) ] + ] + [ div [ class "dropdown-menu" ] + [ div [ class "dropdown-content" ] + (List.map + (\item -> + a + [ class "dropdown-item" + , onClick (SetNewItem item) + ] + [ text item.name ] + ) + results + ) + ] + ] + + viewAddLoot : Model -> Html Msg viewAddLoot model = let + autoResults = + model.state.autoComplete + showCompletionTips = + if List.length autoResults > 0 && newItem.base_price == 0 then + True + + else + False + + showModal = False newItem = - Item 0 "New one #1" 2000 + case model.state.newItem of + Just item -> + item + + Nothing -> + Item 0 "" 0 itemIsValid = - False + if nameValid && priceValid then + True + + else + False + + nameValid = + newItem.name /= "" + + priceValid = + newItem.base_price > 0 + + doesNotYetExists = + newItem.id == 0 in div [ class "box is-primary" ] - [ div [ class "field is-horizontal" ] + [ fromListModal showModal + , div [ class "field is-horizontal" ] [ div [ class "field-label is-medium" ] [ label [ class "label" ] [ text "Source du loot" ] ] , div [ class "field-body" ] [ div [ class "field" ] @@ -486,19 +555,26 @@ viewAddLoot model = [ div [ class "control" ] [ input [ class "input" + , classList [ ( "is-success", nameValid ), ( "is-danger", not nameValid ) ] , type_ "text" , value newItem.name + , onInput NewItemNameChanged ] [] ] - , div - [ class "dropdown" - , classList [ ( "is-active", showCompletionTips ) ] - ] - [ div [ class "dropdown-menu" ] - [ div [ class "dropdown-content" ] - [ a [ class "dropdown-item" ] [ text "item" ] ] - ] + , if showCompletionTips then + viewCompletionDropdown showCompletionTips autoResults + + else + text "" + , p [ class "help has-text-warning" ] + [ text + (if nameValid && doesNotYetExists then + "Cet objet n'existe pas dans l'inventaire. Il y sera ajouté si vous validez." + + else + "" + ) ] ] , div [ class "field is-narrow" ] @@ -509,17 +585,27 @@ viewAddLoot model = [ type_ "number" , class "input" , value <| String.fromInt newItem.base_price - , classList [ ( "is-danger", True ) ] + , onInput NewItemPriceChanged + , classList [ ( "is-danger", not priceValid ), ( "is-success", priceValid ) ] ] [] ] ] - , p [ class "help has-text-danger" ] [ text "Vous devez renseigner le prix !" ] + , p [ class "help has-text-danger" ] + [ text + (if priceValid then + "" + + else + "Vous devez renseigner le prix !" + ) + ] ] , div [ class "field is-narrow" ] [ div [ class "control" ] [ button - [ class "button is-primary" + [ class "button" + , classList [ ( "is-primary", not doesNotYetExists ), ( "is-warning", doesNotYetExists ) ] , disabled <| not itemIsValid , onClick <| NewItemAdded newItem ] @@ -602,6 +688,14 @@ type Msg | ModeSwitched ActionMode | ConfirmAction | NewItemAdded Item + | NewItemNameChanged String + | NewItemPriceChanged String + | SetNewItem Item + + +insensitiveContains : String -> String -> Bool +insensitiveContains substring string = + String.contains (String.toLower substring) (String.toLower string) update : Msg -> Model -> ( Model, Cmd Msg ) @@ -614,6 +708,50 @@ update msg model = in ( { model | state = { state | newLoot = item :: state.newLoot } }, Cmd.none ) + SetNewItem item -> + let + state = + model.state + in + ( { model | state = { state | newItem = Just item } }, Cmd.none ) + + NewItemPriceChanged price -> + case String.toInt price of + Just newPrice -> + let + newItem = + case model.state.newItem of + Just item -> + { item | base_price = newPrice } + + Nothing -> + Item 0 "" newPrice + in + update (SetNewItem newItem) model + + Nothing -> + ( model, Cmd.none ) + + NewItemNameChanged itemName -> + let + state = + model.state + + autoState = + model.state.autoComplete + + -- For now, merchantLoot *IS* the inventory + results = + model.state.merchantLoot + |> List.filter (\i -> insensitiveContains itemName i.name) + in + { model + | state = + { state | autoComplete = results } + } + -- Update newItem field and erase other (outdated) values + |> update (SetNewItem <| Item 0 itemName 0) + ApiMsg apiMsg -> case apiMsg of Api.GotActionResult response ->