Throttle search requests

Throttle search requests when typing. Also fix handling subscriptions
in main.
This commit is contained in:
Eike Kettner
2020-06-13 20:58:15 +02:00
parent 5468e24b55
commit 217fef7384
8 changed files with 160 additions and 132 deletions

View File

@ -16,6 +16,7 @@ import Data.Flags exposing (Flags)
import Data.Items
import Data.UiSettings exposing (UiSettings)
import Http
import Throttle exposing (Throttle)
type alias Model =
@ -27,6 +28,7 @@ type alias Model =
, searchOffset : Int
, moreAvailable : Bool
, moreInProgress : Bool
, throttle : Throttle Msg
}
@ -40,6 +42,7 @@ init _ =
, searchOffset = 0
, moreAvailable = True
, moreInProgress = False
, throttle = Throttle.create 1
}
@ -53,6 +56,7 @@ type Msg
| DoSearch
| ToggleSearchMenu
| LoadMore
| UpdateThrottle
type ViewMode

View File

@ -7,17 +7,15 @@ import Data.Flags exposing (Flags)
import Data.UiSettings exposing (UiSettings)
import Page exposing (Page(..))
import Page.Home.Data exposing (..)
import Util.Update
import Throttle
import Time
update : Nav.Key -> Flags -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg )
update : Nav.Key -> Flags -> UiSettings -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
update key flags settings msg model =
case msg of
Init ->
Util.Update.andThen1
[ update key flags settings (SearchMenuMsg Comp.SearchMenu.Init)
]
model
update key flags settings (SearchMenuMsg Comp.SearchMenu.Init) model
ResetSearch ->
let
@ -34,14 +32,20 @@ update key flags settings msg model =
newModel =
{ model | searchMenuModel = Tuple.first nextState.modelCmd }
( m2, c2 ) =
( m2, c2, s2 ) =
if nextState.stateChange && not model.searchInProgress then
doSearch flags settings newModel
else
( newModel, Cmd.none )
withSub ( newModel, Cmd.none )
in
( m2, Cmd.batch [ c2, Cmd.map SearchMenuMsg (Tuple.second nextState.modelCmd) ] )
( m2
, Cmd.batch
[ c2
, Cmd.map SearchMenuMsg (Tuple.second nextState.modelCmd)
]
, s2
)
ItemCardListMsg m ->
let
@ -56,9 +60,10 @@ update key flags settings msg model =
Nothing ->
Cmd.none
in
( { model | itemListModel = m2 }
, Cmd.batch [ Cmd.map ItemCardListMsg c2, cmd ]
)
withSub
( { model | itemListModel = m2 }
, Cmd.batch [ Cmd.map ItemCardListMsg c2, cmd ]
)
ItemSearchResp (Ok list) ->
let
@ -92,52 +97,71 @@ update key flags settings msg model =
update key flags settings (ItemCardListMsg (Comp.ItemCardList.AddResults list)) m
ItemSearchAddResp (Err _) ->
( { model
| moreInProgress = False
}
, Cmd.none
)
withSub
( { model
| moreInProgress = False
}
, Cmd.none
)
ItemSearchResp (Err _) ->
( { model
| searchInProgress = False
}
, Cmd.none
)
withSub
( { model
| searchInProgress = False
}
, Cmd.none
)
DoSearch ->
let
nm =
{ model | searchOffset = 0 }
in
doSearch flags settings nm
if model.searchInProgress then
withSub ( model, Cmd.none )
else
doSearch flags settings nm
ToggleSearchMenu ->
( { model | menuCollapsed = not model.menuCollapsed }
, Cmd.none
)
withSub
( { model | menuCollapsed = not model.menuCollapsed }
, Cmd.none
)
LoadMore ->
if model.moreAvailable then
doSearchMore flags settings model
doSearchMore flags settings model |> withSub
else
( model, Cmd.none )
withSub ( model, Cmd.none )
UpdateThrottle ->
let
( newThrottle, cmd ) =
Throttle.update model.throttle
in
withSub ( { model | throttle = newThrottle }, cmd )
doSearch : Flags -> UiSettings -> Model -> ( Model, Cmd Msg )
doSearch : Flags -> UiSettings -> Model -> ( Model, Cmd Msg, Sub Msg )
doSearch flags settings model =
let
cmd =
searchCmd =
doSearchCmd flags settings 0 model
( newThrottle, cmd ) =
Throttle.try searchCmd model.throttle
in
( { model
| searchInProgress = True
, viewMode = Listing
, searchOffset = 0
}
, cmd
)
withSub
( { model
| searchInProgress = cmd /= Cmd.none
, viewMode = Listing
, searchOffset = 0
, throttle = newThrottle
}
, cmd
)
doSearchMore : Flags -> UiSettings -> Model -> ( Model, Cmd Msg )
@ -149,3 +173,13 @@ doSearchMore flags settings model =
( { model | moreInProgress = True, viewMode = Listing }
, cmd
)
withSub : ( Model, Cmd Msg ) -> ( Model, Cmd Msg, Sub Msg )
withSub ( m, c ) =
( m
, c
, Throttle.ifNeeded
(Time.every 150 (\_ -> UpdateThrottle))
m.throttle
)

View File

@ -47,8 +47,15 @@ view settings model =
, onClick DoSearch
, title "Run search query"
, href ""
, disabled model.searchInProgress
]
[ i [ class "ui search icon" ] []
[ i
[ classList
[ ( "search icon", not model.searchInProgress )
, ( "loading spinner icon", model.searchInProgress )
]
]
[]
]
]
]
@ -82,12 +89,8 @@ view settings model =
]
, case model.viewMode of
Listing ->
if model.searchInProgress then
resultPlaceholder
else
Html.map ItemCardListMsg
(Comp.ItemCardList.view settings model.itemListModel)
Html.map ItemCardListMsg
(Comp.ItemCardList.view settings model.itemListModel)
Detail ->
div [] []
@ -123,34 +126,3 @@ view settings model =
]
]
]
resultPlaceholder : Html Msg
resultPlaceholder =
div [ class "ui basic segment" ]
[ div [ class "ui active inverted dimmer" ]
[ div [ class "ui medium text loader" ]
[ text "Searching "
]
]
, div [ class "ui middle aligned very relaxed divided basic list segment" ]
[ div [ class "item" ]
[ div [ class "ui fluid placeholder" ]
[ div [ class "full line" ] []
, div [ class "full line" ] []
]
]
, div [ class "item" ]
[ div [ class "ui fluid placeholder" ]
[ div [ class "full line" ] []
, div [ class "full line" ] []
]
]
, div [ class "item" ]
[ div [ class "ui fluid placeholder" ]
[ div [ class "full line" ] []
, div [ class "full line" ] []
]
]
]
]