impls search
This commit is contained in:
@@ -1,17 +1,24 @@
|
|||||||
module Page.Chest exposing (..)
|
module Page.Chest exposing (..)
|
||||||
|
|
||||||
|
import Api
|
||||||
|
exposing
|
||||||
|
( ActionMode(..)
|
||||||
|
, Claims
|
||||||
|
, HttpResult
|
||||||
|
, Item
|
||||||
|
, Loot
|
||||||
|
, Wealth
|
||||||
|
, confirmAction
|
||||||
|
)
|
||||||
import Browser.Navigation as Nav
|
import Browser.Navigation as Nav
|
||||||
|
|
||||||
import Api exposing (ActionMode(..), confirmAction, HttpResult
|
|
||||||
, Wealth, Claims
|
|
||||||
, Item, Loot)
|
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onCheck, onClick)
|
import Html.Events exposing (onCheck, onClick, onInput)
|
||||||
import Route exposing (ChestContent(..))
|
import Route exposing (ChestContent(..))
|
||||||
|
import Session exposing (Session(..))
|
||||||
import Set exposing (Set)
|
import Set exposing (Set)
|
||||||
import Utils exposing (..)
|
import Utils exposing (..)
|
||||||
import Session exposing (Session(..))
|
|
||||||
|
|
||||||
|
|
||||||
-- MODEL
|
-- MODEL
|
||||||
@@ -22,6 +29,7 @@ type alias State =
|
|||||||
, mode : ActionMode
|
, mode : ActionMode
|
||||||
, error : Maybe String
|
, error : Maybe String
|
||||||
, notification : Maybe String
|
, notification : Maybe String
|
||||||
|
|
||||||
-- Fetched on init
|
-- Fetched on init
|
||||||
, player : Api.Player
|
, player : Api.Player
|
||||||
, playerLoot : Loot
|
, playerLoot : Loot
|
||||||
@@ -40,22 +48,25 @@ type alias Model =
|
|||||||
, state : State
|
, state : State
|
||||||
, shown : Route.ChestContent
|
, shown : Route.ChestContent
|
||||||
, selection : Maybe Selection
|
, selection : Maybe Selection
|
||||||
|
, searchText : String
|
||||||
, claims : Claims
|
, claims : Claims
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
init (Player navKey playerId) =
|
init (Player navKey playerId) =
|
||||||
( Model
|
( Model
|
||||||
navKey
|
navKey
|
||||||
(State False NoMode Nothing Nothing Api.blankPlayer [] [] [] [])
|
(State False NoMode Nothing Nothing Api.blankPlayer [] [] [] [])
|
||||||
Route.PlayerLoot
|
Route.PlayerLoot
|
||||||
Nothing
|
Nothing
|
||||||
|
""
|
||||||
[]
|
[]
|
||||||
, Cmd.batch
|
, Cmd.batch
|
||||||
[ Api.fetchPlayer GotPlayer playerId
|
[ Api.fetchPlayer GotPlayer playerId
|
||||||
, Api.fetchClaims GotClaims playerId
|
, Api.fetchClaims GotClaims playerId
|
||||||
, fetchLoot (OfPlayer playerId)
|
, fetchLoot (OfPlayer playerId)
|
||||||
, fetchLoot (OfGroup)
|
, fetchLoot OfGroup
|
||||||
, fetchLoot (OfShop)
|
, fetchLoot OfShop
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -100,7 +111,6 @@ stackedIcon name =
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
debugSandbox =
|
debugSandbox =
|
||||||
[ stackedIcon "fas fa-coins"
|
[ stackedIcon "fas fa-coins"
|
||||||
, stackedIcon "fab fa-d-and-d"
|
, stackedIcon "fab fa-d-and-d"
|
||||||
@@ -127,7 +137,7 @@ viewHeaderBar title model =
|
|||||||
[ div [ class "navbar-brand" ]
|
[ div [ class "navbar-brand" ]
|
||||||
[ a [ class "navbar-item", href "/" ]
|
[ a [ class "navbar-item", href "/" ]
|
||||||
[ renderIcon { icon = "fab fa-d-and-d", size = "medium", ratio = "2x" }
|
[ 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" ]
|
, a [ class "navbar-burger is-active" ]
|
||||||
[ span [ attribute "aria-hidden" "true" ] []
|
[ span [ attribute "aria-hidden" "true" ] []
|
||||||
@@ -216,7 +226,6 @@ showWealthField name value =
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- VIEW
|
-- VIEW
|
||||||
|
|
||||||
|
|
||||||
@@ -246,6 +255,9 @@ view model =
|
|||||||
isSelected =
|
isSelected =
|
||||||
itemInSelection model.selection
|
itemInSelection model.selection
|
||||||
|
|
||||||
|
canSelect =
|
||||||
|
canSelectIn model.state.mode
|
||||||
|
|
||||||
rowRenderer =
|
rowRenderer =
|
||||||
case model.state.mode of
|
case model.state.mode of
|
||||||
NoMode ->
|
NoMode ->
|
||||||
@@ -262,25 +274,16 @@ view model =
|
|||||||
Nothing
|
Nothing
|
||||||
|
|
||||||
activeMode ->
|
activeMode ->
|
||||||
Just (rowRendererForMode isSelected activeMode)
|
Just (rowRendererForMode activeMode)
|
||||||
in
|
in
|
||||||
[ viewHeaderBar model.state.player.name model
|
[ viewHeaderBar model.state.player.name model
|
||||||
, viewPlayerBar model.state.player renderControls
|
, viewPlayerBar model.state.player renderControls
|
||||||
, main_
|
, main_
|
||||||
[ class "container" ]
|
[ class "container" ]
|
||||||
[ viewNotification model.state.notification
|
[ viewNotification model.state.notification
|
||||||
, article
|
|
||||||
[ class "section" ]
|
-- TODO: viewAddLoot when in Add mode
|
||||||
[ div [ class "columns" ]
|
, viewLoot header model.searchText rowRenderer canSelect isSelected <| shownItems model
|
||||||
[ 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
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
, hr [] []
|
, hr [] []
|
||||||
, section [ class "container" ] [ viewDebugSection model ]
|
, section [ class "container" ] [ viewDebugSection model ]
|
||||||
@@ -288,9 +291,49 @@ view model =
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Renderers
|
-- VIEW LOOT
|
||||||
--
|
|
||||||
-- Item -> Html Msg
|
|
||||||
|
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
|
claimedItemRenderer : (Item -> Bool) -> Item -> Html Msg
|
||||||
@@ -307,13 +350,8 @@ claimedItemRenderer isClaimed item =
|
|||||||
text ""
|
text ""
|
||||||
|
|
||||||
|
|
||||||
rowRendererForMode : (Item -> Bool) -> ActionMode -> Item -> Html Msg
|
rowRendererForMode : ActionMode -> Item -> Html Msg
|
||||||
rowRendererForMode isSelected mode item =
|
rowRendererForMode mode item =
|
||||||
let
|
|
||||||
canSelect =
|
|
||||||
canSelectIn mode
|
|
||||||
|
|
||||||
renderInfo =
|
|
||||||
case mode of
|
case mode of
|
||||||
Buy ->
|
Buy ->
|
||||||
p [ class "level-item" ] [ text (String.fromInt item.base_price ++ "po") ]
|
p [ class "level-item" ] [ text (String.fromInt item.base_price ++ "po") ]
|
||||||
@@ -329,53 +367,40 @@ rowRendererForMode isSelected mode item =
|
|||||||
|
|
||||||
NoMode ->
|
NoMode ->
|
||||||
text ""
|
text ""
|
||||||
in
|
|
||||||
div [ class "level-right" ] <|
|
|
||||||
renderInfo
|
viewItemTableRow : (Item -> Bool) -> Bool -> Maybe (Item -> Html Msg) -> Item -> Html Msg
|
||||||
:: (if canSelect then
|
viewItemTableRow isSelected canSelect rowRenderer item =
|
||||||
[ input
|
let
|
||||||
|
rightLevel =
|
||||||
|
div [ class "level-right" ]
|
||||||
|
[ case rowRenderer of
|
||||||
|
Just render ->
|
||||||
|
render item
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
text ""
|
||||||
|
, if canSelect then
|
||||||
|
input
|
||||||
[ class "checkbox level-item"
|
[ class "checkbox level-item"
|
||||||
, type_ "checkbox"
|
, type_ "checkbox"
|
||||||
, checked <| isSelected item
|
, checked <| isSelected item
|
||||||
, onCheck (\v -> SwitchSelectionState item.id)
|
, onCheck (\v -> SwitchSelectionState item.id)
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
]
|
|
||||||
|
|
||||||
else
|
else
|
||||||
[]
|
text ""
|
||||||
)
|
]
|
||||||
|
in
|
||||||
|
|
||||||
viewItemTableRow : (Item -> Bool) -> Maybe (Item -> Html Msg) -> Item -> Html Msg
|
|
||||||
viewItemTableRow isSelected rowRenderer item =
|
|
||||||
tr [ classList [ ( "is-selected", isSelected item ) ] ]
|
tr [ classList [ ( "is-selected", isSelected item ) ] ]
|
||||||
[ td []
|
[ td []
|
||||||
[ label [ class "level checkbox" ] <|
|
[ label [ class "level checkbox" ]
|
||||||
div [ class "level-left" ]
|
[ div [ class "level-left" ]
|
||||||
[ p [ class "level-item" ] [ text item.name ] ]
|
[ p [ class "level-item" ] [ text item.name ] ]
|
||||||
:: (case rowRenderer of
|
, rightLevel
|
||||||
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" ] [] ]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -433,8 +458,9 @@ viewControls mode content =
|
|||||||
type Msg
|
type Msg
|
||||||
= ApiMsg Api.Msg
|
= ApiMsg Api.Msg
|
||||||
| ClearNotification
|
| ClearNotification
|
||||||
| SetContent (ChestContent)
|
| SetContent ChestContent
|
||||||
| SetSelection (Maybe Selection)
|
| SetSelection (Maybe Selection)
|
||||||
|
| SearchTextChanged String
|
||||||
| GotLoot ToChest (HttpResult Loot)
|
| GotLoot ToChest (HttpResult Loot)
|
||||||
| GotClaims (HttpResult Claims)
|
| GotClaims (HttpResult Claims)
|
||||||
| GotPlayer (HttpResult Api.Player)
|
| GotPlayer (HttpResult Api.Player)
|
||||||
@@ -443,9 +469,6 @@ type Msg
|
|||||||
| ConfirmAction
|
| ConfirmAction
|
||||||
|
|
||||||
|
|
||||||
-- UPDATE
|
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||||
update msg model =
|
update msg model =
|
||||||
case msg of
|
case msg of
|
||||||
@@ -479,9 +502,10 @@ update msg model =
|
|||||||
case result of
|
case result of
|
||||||
Ok player ->
|
Ok player ->
|
||||||
let
|
let
|
||||||
state = model.state
|
state =
|
||||||
|
model.state
|
||||||
in
|
in
|
||||||
( { model | state = { state | player = player }} , Cmd.none)
|
( { model | state = { state | player = player } }, Cmd.none )
|
||||||
|
|
||||||
Err error ->
|
Err error ->
|
||||||
( setError ("Fetching player... " ++ Debug.toString error) model
|
( setError ("Fetching player... " ++ Debug.toString error) model
|
||||||
@@ -489,8 +513,11 @@ update msg model =
|
|||||||
)
|
)
|
||||||
|
|
||||||
ModeSwitched newMode ->
|
ModeSwitched newMode ->
|
||||||
let state = model.state in
|
let
|
||||||
{ model | state = { state | mode = newMode }}
|
state =
|
||||||
|
model.state
|
||||||
|
in
|
||||||
|
{ model | state = { state | mode = newMode } }
|
||||||
|> update
|
|> update
|
||||||
(SetSelection
|
(SetSelection
|
||||||
(case newMode of
|
(case newMode of
|
||||||
@@ -506,7 +533,6 @@ update msg model =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
ConfirmAction ->
|
ConfirmAction ->
|
||||||
case model.state.mode of
|
case model.state.mode of
|
||||||
-- This should not happen, so we ignore it
|
-- This should not happen, so we ignore it
|
||||||
@@ -535,26 +561,29 @@ update msg model =
|
|||||||
SetSelection new ->
|
SetSelection new ->
|
||||||
( { model | selection = new }, Cmd.none )
|
( { model | selection = new }, Cmd.none )
|
||||||
|
|
||||||
GotClaims (Ok claims )->
|
SearchTextChanged search ->
|
||||||
( { model | claims = claims } , Cmd.none )
|
( { model | searchText = search }, Cmd.none )
|
||||||
|
|
||||||
|
GotClaims (Ok claims) ->
|
||||||
|
( { model | claims = claims }, Cmd.none )
|
||||||
|
|
||||||
GotClaims (Err error) ->
|
GotClaims (Err error) ->
|
||||||
( setError (Debug.toString error) model, Cmd.none )
|
( setError (Debug.toString error) model, Cmd.none )
|
||||||
|
|
||||||
GotLoot dest (Ok loot) ->
|
GotLoot dest (Ok loot) ->
|
||||||
(
|
( let
|
||||||
let
|
state =
|
||||||
state = model.state
|
model.state
|
||||||
in
|
in
|
||||||
case dest of
|
case dest of
|
||||||
OfPlayer _ ->
|
OfPlayer _ ->
|
||||||
{ model | state = { state | playerLoot = loot }}
|
{ model | state = { state | playerLoot = loot } }
|
||||||
|
|
||||||
OfGroup ->
|
OfGroup ->
|
||||||
{ model | state = { state | groupLoot = loot }}
|
{ model | state = { state | groupLoot = loot } }
|
||||||
|
|
||||||
OfShop ->
|
OfShop ->
|
||||||
{ model | state = { state | merchantLoot = loot }}
|
{ model | state = { state | merchantLoot = loot } }
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -573,6 +602,8 @@ setNotification notification model =
|
|||||||
{ state | notification = notification }
|
{ state | notification = notification }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- ERRORS
|
-- ERRORS
|
||||||
|
|
||||||
|
|
||||||
@@ -595,15 +626,21 @@ setError error model =
|
|||||||
applyUpdate : Api.Update -> Model -> Model
|
applyUpdate : Api.Update -> Model -> Model
|
||||||
applyUpdate u model =
|
applyUpdate u model =
|
||||||
let
|
let
|
||||||
state = model.state
|
state =
|
||||||
|
model.state
|
||||||
in
|
in
|
||||||
case u of
|
case u of
|
||||||
Api.ItemRemoved item ->
|
Api.ItemRemoved item ->
|
||||||
{ model | state = { state | playerLoot =
|
{ model
|
||||||
List.filter (\i -> i.id /= item.id) model.state.playerLoot }}
|
| state =
|
||||||
|
{ state
|
||||||
|
| playerLoot =
|
||||||
|
List.filter (\i -> i.id /= item.id) model.state.playerLoot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Api.ItemAdded item ->
|
Api.ItemAdded item ->
|
||||||
{ model | state = { state | playerLoot = (item :: model.state.playerLoot) }}
|
{ model | state = { state | playerLoot = item :: model.state.playerLoot } }
|
||||||
|
|
||||||
Api.WealthUpdated diff ->
|
Api.WealthUpdated diff ->
|
||||||
let
|
let
|
||||||
@@ -613,7 +650,9 @@ applyUpdate u model =
|
|||||||
wealth =
|
wealth =
|
||||||
player.wealth
|
player.wealth
|
||||||
in
|
in
|
||||||
{ model | state = { state
|
{ model
|
||||||
|
| state =
|
||||||
|
{ state
|
||||||
| player =
|
| player =
|
||||||
{ player
|
{ player
|
||||||
| wealth =
|
| wealth =
|
||||||
@@ -623,16 +662,16 @@ applyUpdate u model =
|
|||||||
(wealth.gp + diff.gp)
|
(wealth.gp + diff.gp)
|
||||||
(wealth.pp + diff.pp)
|
(wealth.pp + diff.pp)
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Api.ClaimAdded claim ->
|
Api.ClaimAdded claim ->
|
||||||
{ model | claims = (claim :: model.claims) }
|
{ model | claims = claim :: model.claims }
|
||||||
|
|
||||||
Api.ClaimRemoved claim ->
|
Api.ClaimRemoved claim ->
|
||||||
{ model | claims = List.filter (\c -> c.id /= claim.id) model.claims }
|
{ model | claims = List.filter (\c -> c.id /= claim.id) model.claims }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type ToChest
|
type ToChest
|
||||||
= OfPlayer Int
|
= OfPlayer Int
|
||||||
| OfGroup
|
| OfGroup
|
||||||
|
|||||||
Reference in New Issue
Block a user