impls search

This commit is contained in:
2019-11-11 21:15:44 +01:00
parent 3aee238cd9
commit c368715c8d

View File

@@ -1,17 +1,24 @@
module Page.Chest exposing (..)
import Api
exposing
( ActionMode(..)
, Claims
, HttpResult
, Item
, Loot
, Wealth
, confirmAction
)
import Browser.Navigation as Nav
import Api exposing (ActionMode(..), confirmAction, HttpResult
, Wealth, Claims
, Item, Loot)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onCheck, onClick)
import Html.Events exposing (onCheck, onClick, onInput)
import Route exposing (ChestContent(..))
import Session exposing (Session(..))
import Set exposing (Set)
import Utils exposing (..)
import Session exposing (Session(..))
-- MODEL
@@ -22,6 +29,7 @@ type alias State =
, mode : ActionMode
, error : Maybe String
, notification : Maybe String
-- Fetched on init
, player : Api.Player
, playerLoot : Loot
@@ -40,22 +48,25 @@ type alias Model =
, state : State
, shown : Route.ChestContent
, selection : Maybe Selection
, searchText : String
, claims : Claims
}
init (Player navKey playerId) =
( Model
navKey
(State False NoMode Nothing Nothing Api.blankPlayer [] [] [] [])
Route.PlayerLoot
Nothing
""
[]
, Cmd.batch
[ Api.fetchPlayer GotPlayer playerId
, Api.fetchClaims GotClaims playerId
, fetchLoot (OfPlayer playerId)
, fetchLoot (OfGroup)
, fetchLoot (OfShop)
, fetchLoot OfGroup
, fetchLoot OfShop
]
)
@@ -100,7 +111,6 @@ stackedIcon name =
]
debugSandbox =
[ stackedIcon "fas fa-coins"
, stackedIcon "fab fa-d-and-d"
@@ -127,7 +137,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 [] [ text model.state.player.name ]
, span [] [ text title ]
]
, a [ class "navbar-burger is-active" ]
[ span [ attribute "aria-hidden" "true" ] []
@@ -216,7 +226,6 @@ showWealthField name value =
-- VIEW
@@ -246,6 +255,9 @@ view model =
isSelected =
itemInSelection model.selection
canSelect =
canSelectIn model.state.mode
rowRenderer =
case model.state.mode of
NoMode ->
@@ -262,25 +274,16 @@ view model =
Nothing
activeMode ->
Just (rowRendererForMode isSelected activeMode)
Just (rowRendererForMode activeMode)
in
[ viewHeaderBar model.state.player.name model
, viewPlayerBar model.state.player renderControls
, main_
[ class "container" ]
[ viewNotification model.state.notification
, article
[ class "section" ]
[ div [ class "columns" ]
[ div [ class "column is-one-third" ] [ p [ class "title" ] [ text header ] ]
, div [ class "column" ] [ viewSearchBar ]
]
, table [ class "table is-fullwidth is-striped is-hoverable" ]
[ thead [ class "table-header" ]
[ th [] [ text "Nom" ] ]
, tbody [] <| List.map (viewItemTableRow isSelected rowRenderer) <| shownItems model
]
]
-- TODO: viewAddLoot when in Add mode
, viewLoot header model.searchText rowRenderer canSelect isSelected <| shownItems model
]
, hr [] []
, section [ class "container" ] [ viewDebugSection model ]
@@ -288,9 +291,49 @@ view model =
-- Renderers
--
-- Item -> Html Msg
-- VIEW LOOT
viewLoot : String -> String -> Maybe (Item -> Html Msg) -> Bool -> (Item -> Bool) -> Loot -> Html Msg
viewLoot header searchText rowRenderer canSelect isSelected items =
let
filteredItems =
List.filter
(\i -> String.toLower i.name |> String.contains (String.toLower searchText) )
items
in
article
[ class "section" ]
[ div [ class "columns" ]
[ div [ class "column is-one-third" ] [ p [ class "title" ] [ text header ] ]
, div [ class "column" ] [ viewSearchBar searchText ]
]
, table [ class "table is-fullwidth is-striped is-hoverable" ]
[ thead [ class "table-header" ]
[ th [] [ text "Nom" ] ]
, tbody [] <| List.map (viewItemTableRow isSelected canSelect rowRenderer) filteredItems
]
]
-- Search Bar
viewSearchBar : String -> Html Msg
viewSearchBar textValue =
div [ class "field" ]
[ p [ class "control has-icons-left" ]
[ input [ class "input"
, onInput SearchTextChanged
, value textValue ] []
, span [ class "icon is-left" ] [ i [ class "fas fa-search" ] [] ]
]
]
-- Renderers : Item -> Html Msg
claimedItemRenderer : (Item -> Bool) -> Item -> Html Msg
@@ -307,74 +350,56 @@ claimedItemRenderer isClaimed item =
text ""
rowRendererForMode : (Item -> Bool) -> ActionMode -> Item -> Html Msg
rowRendererForMode isSelected mode item =
rowRendererForMode : ActionMode -> Item -> Html Msg
rowRendererForMode 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 !" ]
NoMode ->
text ""
viewItemTableRow : (Item -> Bool) -> Bool -> Maybe (Item -> Html Msg) -> Item -> Html Msg
viewItemTableRow isSelected canSelect rowRenderer item =
let
canSelect =
canSelectIn mode
rightLevel =
div [ class "level-right" ]
[ case rowRenderer of
Just render ->
render item
renderInfo =
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 !" ]
NoMode ->
text ""
in
div [ class "level-right" ] <|
renderInfo
:: (if canSelect then
[ input
Nothing ->
text ""
, if canSelect then
input
[ class "checkbox level-item"
, type_ "checkbox"
, checked <| isSelected item
, onCheck (\v -> SwitchSelectionState item.id)
]
[]
]
else
[]
)
viewItemTableRow : (Item -> Bool) -> Maybe (Item -> Html Msg) -> Item -> Html Msg
viewItemTableRow isSelected rowRenderer item =
else
text ""
]
in
tr [ classList [ ( "is-selected", isSelected item ) ] ]
[ td []
[ label [ class "level checkbox" ] <|
div [ class "level-left" ]
[ label [ class "level checkbox" ]
[ div [ class "level-left" ]
[ p [ class "level-item" ] [ text item.name ] ]
:: (case rowRenderer of
Just render ->
List.singleton (render item)
Nothing ->
[]
)
]
]
-- Search Bar
viewSearchBar : Html Msg
viewSearchBar =
div [ class "field" ]
[ p [ class "control has-icons-left" ]
[ input [ class "input" ] []
, span [ class "icon is-left" ] [ i [ class "fas fa-search" ] [] ]
, rightLevel
]
]
]
@@ -406,7 +431,7 @@ canSelectIn mode =
viewControls : ActionMode -> ChestContent -> List (Html Msg)
viewControls mode content =
case mode of
NoMode ->
NoMode ->
case content of
PlayerLoot ->
[ actionButton (ModeSwitched Sell) "Vendre" "coins" "danger" ]
@@ -433,8 +458,9 @@ viewControls mode content =
type Msg
= ApiMsg Api.Msg
| ClearNotification
| SetContent (ChestContent)
| SetContent ChestContent
| SetSelection (Maybe Selection)
| SearchTextChanged String
| GotLoot ToChest (HttpResult Loot)
| GotClaims (HttpResult Claims)
| GotPlayer (HttpResult Api.Player)
@@ -443,9 +469,6 @@ type Msg
| ConfirmAction
-- UPDATE
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
@@ -476,36 +499,39 @@ update msg model =
( { model | shown = content }, Cmd.none )
GotPlayer result ->
case result of
Ok player ->
let
state = model.state
in
( { model | state = { state | player = player }} , Cmd.none)
case result of
Ok player ->
let
state =
model.state
in
( { model | state = { state | player = player } }, Cmd.none )
Err error ->
( setError ("Fetching player... " ++ Debug.toString error) model
, Cmd.none
)
Err error ->
( setError ("Fetching player... " ++ Debug.toString error) model
, Cmd.none
)
ModeSwitched newMode ->
let state = model.state in
{ model | state = { state | mode = newMode }}
|> update
(SetSelection
(case newMode of
NoMode ->
Nothing
let
state =
model.state
in
{ model | state = { state | mode = newMode } }
|> update
(SetSelection
(case newMode of
NoMode ->
Nothing
Grab ->
-- Currently claimed object are initially selected
Just (Set.fromList <| List.map (\c -> c.loot_id) model.claims)
others ->
Just Set.empty
)
)
Grab ->
-- Currently claimed object are initially selected
Just (Set.fromList <| List.map (\c -> c.loot_id) model.claims)
others ->
Just Set.empty
)
)
ConfirmAction ->
case model.state.mode of
@@ -535,31 +561,34 @@ update msg model =
SetSelection new ->
( { model | selection = new }, Cmd.none )
GotClaims (Ok claims )->
( { model | claims = claims } , Cmd.none )
SearchTextChanged search ->
( { model | searchText = search }, Cmd.none )
GotClaims (Ok claims) ->
( { model | claims = claims }, Cmd.none )
GotClaims (Err error) ->
( setError (Debug.toString error) model, Cmd.none )
GotLoot dest (Ok loot) ->
(
let
state = model.state
in
case dest of
OfPlayer _ ->
{ model | state = { state | playerLoot = loot }}
( let
state =
model.state
in
case dest of
OfPlayer _ ->
{ model | state = { state | playerLoot = loot } }
OfGroup ->
{ model | state = { state | groupLoot = loot }}
OfGroup ->
{ model | state = { state | groupLoot = loot } }
OfShop ->
{ model | state = { state | merchantLoot = loot }}
, Cmd.none
)
OfShop ->
{ model | state = { state | merchantLoot = loot } }
, Cmd.none
)
GotLoot _ (Err error) ->
( setError (Debug.toString error) model, Cmd.none )
( setError (Debug.toString error) model, Cmd.none )
setNotification : Maybe String -> Model -> Model
@@ -573,6 +602,8 @@ setNotification notification model =
{ state | notification = notification }
}
-- ERRORS
@@ -595,15 +626,21 @@ setError error model =
applyUpdate : Api.Update -> Model -> Model
applyUpdate u model =
let
state = model.state
state =
model.state
in
case u of
Api.ItemRemoved item ->
{ model | state = { state | playerLoot =
List.filter (\i -> i.id /= item.id) model.state.playerLoot }}
{ model
| state =
{ state
| playerLoot =
List.filter (\i -> i.id /= item.id) model.state.playerLoot
}
}
Api.ItemAdded item ->
{ model | state = { state | playerLoot = (item :: model.state.playerLoot) }}
{ model | state = { state | playerLoot = item :: model.state.playerLoot } }
Api.WealthUpdated diff ->
let
@@ -613,26 +650,28 @@ applyUpdate u model =
wealth =
player.wealth
in
{ model | state = { state
| player =
{ player
| wealth =
Wealth
(wealth.cp + diff.cp)
(wealth.sp + diff.sp)
(wealth.gp + diff.gp)
(wealth.pp + diff.pp)
{ model
| state =
{ state
| player =
{ player
| wealth =
Wealth
(wealth.cp + diff.cp)
(wealth.sp + diff.sp)
(wealth.gp + diff.gp)
(wealth.pp + diff.pp)
}
}
}}
}
Api.ClaimAdded claim ->
{ model | claims = (claim :: model.claims) }
{ model | claims = claim :: model.claims }
Api.ClaimRemoved claim ->
{ model | claims = List.filter (\c -> c.id /= claim.id) model.claims }
type ToChest
= OfPlayer Int
| OfGroup