impls search
This commit is contained in:
@@ -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,13 +350,8 @@ claimedItemRenderer isClaimed item =
|
||||
text ""
|
||||
|
||||
|
||||
rowRendererForMode : (Item -> Bool) -> ActionMode -> Item -> Html Msg
|
||||
rowRendererForMode isSelected mode item =
|
||||
let
|
||||
canSelect =
|
||||
canSelectIn mode
|
||||
|
||||
renderInfo =
|
||||
rowRendererForMode : ActionMode -> Item -> Html Msg
|
||||
rowRendererForMode mode item =
|
||||
case mode of
|
||||
Buy ->
|
||||
p [ class "level-item" ] [ text (String.fromInt item.base_price ++ "po") ]
|
||||
@@ -329,53 +367,40 @@ rowRendererForMode isSelected mode item =
|
||||
|
||||
NoMode ->
|
||||
text ""
|
||||
in
|
||||
div [ class "level-right" ] <|
|
||||
renderInfo
|
||||
:: (if canSelect then
|
||||
[ input
|
||||
|
||||
|
||||
viewItemTableRow : (Item -> Bool) -> Bool -> Maybe (Item -> Html Msg) -> Item -> Html Msg
|
||||
viewItemTableRow isSelected canSelect rowRenderer item =
|
||||
let
|
||||
rightLevel =
|
||||
div [ class "level-right" ]
|
||||
[ case rowRenderer of
|
||||
Just render ->
|
||||
render item
|
||||
|
||||
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 =
|
||||
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 ->
|
||||
[]
|
||||
)
|
||||
, rightLevel
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
|
||||
-- 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" ] [] ]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -479,9 +502,10 @@ update msg model =
|
||||
case result of
|
||||
Ok player ->
|
||||
let
|
||||
state = model.state
|
||||
state =
|
||||
model.state
|
||||
in
|
||||
( { model | state = { state | player = player }} , Cmd.none)
|
||||
( { model | state = { state | player = player } }, Cmd.none )
|
||||
|
||||
Err error ->
|
||||
( setError ("Fetching player... " ++ Debug.toString error) model
|
||||
@@ -489,8 +513,11 @@ update msg model =
|
||||
)
|
||||
|
||||
ModeSwitched newMode ->
|
||||
let state = model.state in
|
||||
{ model | state = { state | mode = newMode }}
|
||||
let
|
||||
state =
|
||||
model.state
|
||||
in
|
||||
{ model | state = { state | mode = newMode } }
|
||||
|> update
|
||||
(SetSelection
|
||||
(case newMode of
|
||||
@@ -506,7 +533,6 @@ update msg model =
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
ConfirmAction ->
|
||||
case model.state.mode of
|
||||
-- This should not happen, so we ignore it
|
||||
@@ -535,26 +561,29 @@ 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
|
||||
( let
|
||||
state =
|
||||
model.state
|
||||
in
|
||||
case dest of
|
||||
OfPlayer _ ->
|
||||
{ model | state = { state | playerLoot = loot }}
|
||||
{ model | state = { state | playerLoot = loot } }
|
||||
|
||||
OfGroup ->
|
||||
{ model | state = { state | groupLoot = loot }}
|
||||
{ model | state = { state | groupLoot = loot } }
|
||||
|
||||
OfShop ->
|
||||
{ model | state = { state | merchantLoot = loot }}
|
||||
{ model | state = { state | merchantLoot = loot } }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
@@ -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,7 +650,9 @@ applyUpdate u model =
|
||||
wealth =
|
||||
player.wealth
|
||||
in
|
||||
{ model | state = { state
|
||||
{ model
|
||||
| state =
|
||||
{ state
|
||||
| player =
|
||||
{ player
|
||||
| wealth =
|
||||
@@ -623,16 +662,16 @@ applyUpdate u model =
|
||||
(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
|
||||
|
||||
Reference in New Issue
Block a user