Add a load-more button to item list

This commit is contained in:
Eike Kettner
2020-06-06 02:08:20 +02:00
parent e5b90eff34
commit b150269528
9 changed files with 251 additions and 16 deletions

View File

@ -2,13 +2,19 @@ module Page.Home.Data exposing
( Model
, Msg(..)
, ViewMode(..)
, emptyModel
, doSearchCmd
, init
, itemNav
, resultsBelowLimit
, searchLimit
)
import Api
import Api.Model.ItemLightList exposing (ItemLightList)
import Comp.ItemCardList
import Comp.SearchMenu
import Data.Flags exposing (Flags)
import Data.Items
import Http
@ -18,16 +24,22 @@ type alias Model =
, searchInProgress : Bool
, viewMode : ViewMode
, menuCollapsed : Bool
, searchOffset : Int
, moreAvailable : Bool
, moreInProgress : Bool
}
emptyModel : Model
emptyModel =
init : Flags -> Model
init _ =
{ searchMenuModel = Comp.SearchMenu.emptyModel
, itemListModel = Comp.ItemCardList.init
, searchInProgress = False
, viewMode = Listing
, menuCollapsed = False
, searchOffset = 0
, moreAvailable = True
, moreInProgress = False
}
@ -39,6 +51,7 @@ type Msg
| ItemSearchResp (Result Http.Error ItemLightList)
| DoSearch
| ToggleSearchMenu
| LoadMore
type ViewMode
@ -58,3 +71,32 @@ itemNav id model =
{ prev = Maybe.map .id prev
, next = Maybe.map .id next
}
searchLimit : Int
searchLimit =
90
doSearchCmd : Flags -> Int -> Comp.SearchMenu.Model -> Cmd Msg
doSearchCmd flags offset model =
let
smask =
Comp.SearchMenu.getItemSearch model
mask =
{ smask
| limit = searchLimit
, offset = offset
}
in
Api.itemSearch flags mask ItemSearchResp
resultsBelowLimit : Model -> Bool
resultsBelowLimit model =
let
len =
Data.Items.length model.itemListModel.results
in
len < searchLimit

View File

@ -1,6 +1,5 @@
module Page.Home.Update exposing (update)
import Api
import Browser.Navigation as Nav
import Comp.ItemCardList
import Comp.SearchMenu
@ -21,7 +20,11 @@ update key flags msg model =
model
ResetSearch ->
update key flags (SearchMenuMsg Comp.SearchMenu.ResetForm) model
let
nm =
{ model | searchOffset = 0 }
in
update key flags (SearchMenuMsg Comp.SearchMenu.ResetForm) nm
SearchMenuMsg m ->
let
@ -57,32 +60,71 @@ update key flags msg model =
ItemSearchResp (Ok list) ->
let
noff =
model.searchOffset + searchLimit
m =
{ model | searchInProgress = False, viewMode = Listing }
{ model
| searchInProgress = False
, moreInProgress = False
, searchOffset = noff
, viewMode = Listing
, moreAvailable = list.groups /= []
}
in
update key flags (ItemCardListMsg (Comp.ItemCardList.SetResults list)) m
if list.groups == [] then
( m, Cmd.none )
else if model.searchOffset == 0 then
update key flags (ItemCardListMsg (Comp.ItemCardList.SetResults list)) m
else
update key flags (ItemCardListMsg (Comp.ItemCardList.AddResults list)) m
ItemSearchResp (Err _) ->
( { model | searchInProgress = False }, Cmd.none )
( { model
| searchInProgress = False
}
, Cmd.none
)
DoSearch ->
doSearch flags model
let
nm =
{ model | searchOffset = 0 }
in
doSearch flags nm
ToggleSearchMenu ->
( { model | menuCollapsed = not model.menuCollapsed }
, Cmd.none
)
LoadMore ->
if model.moreAvailable then
doSearchMore flags model
else
( model, Cmd.none )
doSearch : Flags -> Model -> ( Model, Cmd Msg )
doSearch flags model =
let
smask =
Comp.SearchMenu.getItemSearch model.searchMenuModel
mask =
{ smask | limit = 100 }
cmd =
doSearchCmd flags model.searchOffset model.searchMenuModel
in
( { model | searchInProgress = True, viewMode = Listing }
, Api.itemSearch flags mask ItemSearchResp
, cmd
)
doSearchMore : Flags -> Model -> ( Model, Cmd Msg )
doSearchMore flags model =
let
cmd =
doSearchCmd flags model.searchOffset model.searchMenuModel
in
( { model | moreInProgress = True, viewMode = Listing }
, cmd
)

View File

@ -61,6 +61,7 @@ view model =
, not model.menuCollapsed
)
, ( "sixteen wide column", model.menuCollapsed )
, ( "item-card-list", True )
]
]
[ div
@ -90,6 +91,36 @@ view model =
Detail ->
div [] []
]
, div
[ classList
[ ( "sixteen wide column", True )
]
]
[ div [ class "ui basic center aligned segment" ]
[ button
[ classList
[ ( "ui basic tiny button", True )
, ( "disabled", not model.moreAvailable )
, ( "hidden invisible", resultsBelowLimit model )
]
, disabled (not model.moreAvailable || model.moreInProgress || model.searchInProgress)
, title "Load more items"
, href "#"
, onClick LoadMore
]
[ if model.moreInProgress then
i [ class "loading spinner icon" ] []
else
i [ class "angle double down icon" ] []
, if model.moreAvailable then
text "Load more"
else
text "That's all"
]
]
]
]