1- module Search exposing (Model , Msg , Post , init , update , view )
1+ module Search exposing (Model , Msg , Post , init , subscriptions , update , view )
22
33import Browser.Dom as Dom
4+ import Browser.Events
45import Html exposing (Html )
56import Html.Attributes as Attributes
67import Html.Events as Events
78import Html.Lazy as Lazy
89import HtmlHelpers exposing (nothing )
910import Http
11+ import Json.Decode as Json
1012import Maybe exposing (Maybe )
1113import Task
1214
@@ -46,24 +48,8 @@ init () =
4648update : Msg -> Model -> ( Model , Cmd Msg )
4749update msg model =
4850 case msg of
49- ToggleSearch ->
50- let
51- open : Bool
52- open =
53- not model. open
54-
55- cmd : Cmd Msg
56- cmd =
57- if open then
58- Dom . focus inputId |> Task . attempt ( \ _ -> Noop )
59-
60- else
61- Cmd . none
62- in
63- ( { model | open = open }, cmd )
64-
6551 ChangeTerm term ->
66- ( { model | searchTerm = term }, Cmd . none )
52+ ( { model | searchTerm = term |> String . replace " / " " " }, Cmd . none )
6753
6854 GotXmlFeed ( Ok feed) ->
6955 ( { model | content = feed |> transformFeed |> Just }, Cmd . none )
@@ -74,11 +60,18 @@ update msg model =
7460 Noop ->
7561 ( model, Cmd . none )
7662
63+ OpenSearch ->
64+ ( { model | open = True }, Dom . focus inputId |> Task . attempt ( \ _ -> Noop ) )
65+
66+ CloseSearch ->
67+ ( { model | open = False }, Cmd . none )
68+
7769
7870type Msg
7971 = ChangeTerm String
8072 | GotXmlFeed ( Result Http . Error String )
81- | ToggleSearch
73+ | OpenSearch
74+ | CloseSearch
8275 | Noop
8376
8477
@@ -157,7 +150,7 @@ view model =
157150 , Attributes . style " border-radius" " 0 2rem 2rem 0"
158151 , Attributes . style " backdrop-filter" " blur(5rem)"
159152 , Attributes . style " transition" " 0.4s ease opacity"
160- , Events . onClick ToggleSearch
153+ , Events . onClick OpenSearch
161154 ]
162155 [ Html . text " Search?" ]
163156
@@ -169,7 +162,7 @@ view model =
169162 , Attributes . style " left" " 0"
170163 , Attributes . style " right" " 0"
171164 , Attributes . style " z-index" " -1"
172- , Events . onClick ToggleSearch
165+ , Events . onClick CloseSearch
173166 ]
174167 []
175168 , searchResults model
@@ -233,6 +226,7 @@ resultEntry post =
233226 entryStyle
234227 [ Html . a
235228 [ Attributes . href post. link
229+ , Attributes . tabindex 0
236230 ]
237231 [ Html . text post. title ]
238232 ]
@@ -305,3 +299,39 @@ getXmlFeed =
305299 { url = " /index.xml"
306300 , expect = Http . expectString GotXmlFeed
307301 }
302+
303+
304+
305+ -- SUBSCRIPTIONS
306+
307+
308+ subscriptions : Model -> Sub Msg
309+ subscriptions _ =
310+ Browser . Events . onKeyPress keyboardEventDecoder
311+
312+
313+ keyPressHandler : RawKeyboardEvent -> Msg
314+ keyPressHandler { ctrlKey, code } =
315+ case ( ctrlKey, code ) of
316+ ( False , " Slash" ) ->
317+ OpenSearch
318+
319+ ( False , " Escape" ) ->
320+ CloseSearch
321+
322+ _ ->
323+ Noop
324+
325+
326+ keyboardEventDecoder : Json .Decoder Msg
327+ keyboardEventDecoder =
328+ Json . map2 RawKeyboardEvent
329+ ( Json . field " code" Json . string)
330+ ( Json . field " ctrlKey" Json . bool)
331+ |> Json . map keyPressHandler
332+
333+
334+ type alias RawKeyboardEvent =
335+ { code : String
336+ , ctrlKey : Bool
337+ }
0 commit comments