add backdrop for suggestions and show suggestions loading spinner the moment a user starts typing (#129)

fixes #118
fixes #122
This commit is contained in:
Rok Garbas 2020-07-09 19:00:28 +02:00 committed by GitHub
parent a3ed2036cb
commit 71eba22a0e
Failed to generate hash of commit
2 changed files with 125 additions and 122 deletions

View file

@ -149,7 +149,7 @@ init channel query show from size model =
( { channel = Maybe.withDefault defaultChannel channel ( { channel = Maybe.withDefault defaultChannel channel
, queryDebounce = , queryDebounce =
Debouncer.Messages.manual Debouncer.Messages.manual
|> Debouncer.Messages.settleWhenQuietFor (Just <| Debouncer.Messages.fromSeconds 0.6) |> Debouncer.Messages.settleWhenQuietFor (Just <| Debouncer.Messages.fromSeconds 0.4)
|> Debouncer.Messages.toDebouncer |> Debouncer.Messages.toDebouncer
, query = query , query = query
, querySuggest = , querySuggest =
@ -264,22 +264,7 @@ update path navKey result_type options decodeResultItemSource msg model =
(QueryInputDebounce (Debouncer.Messages.provideInput QueryInputSuggestionsSubmit)) (QueryInputDebounce (Debouncer.Messages.provideInput QueryInputSuggestionsSubmit))
{ model { model
| query = Just query | query = Just query
, querySuggest = , querySuggest = RemoteData.Loading
case model.querySuggest of
RemoteData.Success result ->
let
suggestions =
getSuggestions (Just "XXXX") model.querySuggest
|> List.map .text
in
if List.member (Just query) suggestions then
RemoteData.NotAsked
else
model.querySuggest
_ ->
RemoteData.NotAsked
, querySelectedSuggestion = Nothing , querySelectedSuggestion = Nothing
} }
|> Tuple.mapSecond |> Tuple.mapSecond
@ -708,14 +693,25 @@ view path title model viewSuccess outMsg =
[ text <| Maybe.withDefault "" x.text ] [ text <| Maybe.withDefault "" x.text ]
] ]
in in
div [ class "search-page" ] div
[ classList
[ ( "search-page", True )
, ( "with-suggestions", RemoteData.isSuccess model.querySuggest && List.length suggestions > 0 )
, ( "with-suggestions-loading"
, (model.query /= Nothing)
&& (model.query /= Just "")
&& not (RemoteData.isSuccess model.querySuggest || RemoteData.isNotAsked model.querySuggest)
)
]
]
[ h1 [ class "page-header" ] [ text title ] [ h1 [ class "page-header" ] [ text title ]
, div , div
[ classList [ class "search-backdrop"
[ ( "search-input", True ) , onClick <| outMsg SuggestionsClose
, ( "with-suggestions", RemoteData.isSuccess model.querySuggest && List.length suggestions > 0 )
, ( "with-suggestions-loading", RemoteData.isLoading model.querySuggest )
] ]
[]
, div
[ class "search-input"
] ]
[ form [ onSubmit (outMsg QueryInputSubmit) ] [ form [ onSubmit (outMsg QueryInputSubmit) ]
[ p [ p

View file

@ -29,21 +29,28 @@ header .navbar.navbar-static-top {
} }
} }
.search-page { .search-page.with-suggestions-loading {
.search-input.with-suggestions-loading {
.input-append div.loader { .input-append div.loader {
display: block; display: block;
} }
} }
.search-input.with-suggestions { .search-page.with-suggestions {
ul.dropdown-menu { ul.dropdown-menu {
display: block; display: block;
} }
.input-append input { .input-append input {
border-radius: 4px 0 0 0; border-radius: 4px 0 0 0;
} }
.search-backdrop {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 999;
} }
.search-input { }
.search-input {
position: relative; position: relative;
ul.dropdown-menu { ul.dropdown-menu {
font-size: 18px; font-size: 18px;
@ -98,8 +105,8 @@ header .navbar.navbar-static-top {
font-size: 1.2em; font-size: 1.2em;
margin-left: 0.2em; margin-left: 0.2em;
} }
} }
.search-result { .search-result {
tbody > tr { tbody > tr {
cursor: pointer; cursor: pointer;
} }
@ -128,9 +135,9 @@ header .navbar.navbar-static-top {
tbody > td > dl > dd { tbody > td > dl > dd {
margin-bottom: 1em; margin-bottom: 1em;
} }
}
} }
.loader, .loader,
.loader:before, .loader:before,
.loader:after { .loader:after {