@@ -2,66 +2,71 @@ module Spago.Search.App.SearchResults where
22
33import Prelude
44
5−import Spago.Search.App.SearchField (Message(..))
6−import Spago.Search.Declarations
7−import Spago.Search.Index
8−import Spago.Search.Extra
5+import Spago.Search.Declarations (loadDeclarations)
6+import Spago.Search.Extra (whenJust)
7+import Spago.Search.Index (SearchIndex, SearchResult, mkSearchIndex)
98
10−import CSS hiding (render,map)
119import Data.Array as Array
10+import Data.Either (Either(..))
1211import Data.List as List
13−import Data.Maybe
14−import Data.Newtype
12+import Data.Maybe (Maybe(..), isNothing)
13+import Data.Newtype (unwrap, wrap)
1514import Data.Search.Trie as Trie
16−import Data.String (null) as String
15+import Data.String (length) as String
1716import Data.String.CodeUnits (toCharArray) as String
1817import Data.String.Common (toLower) as String
19−import Effect.Aff
20−import Effect.Console
18+import Effect.Aff (Aff)
19+import Effect.Console (error)
2120import Halogen as H
2221import Halogen.HTML as HH
23−import Halogen.HTML.CSS as HS
24−import Halogen.HTML.Events as HE
2522import Halogen.HTML.Properties as HP
23+import Spago.Search.App.SearchField (Message(..))
24+import Web.DOM.Element (Element)
25+import Web.DOM.Element as Element
2626
27−type State = { shown :: Boolean
28− , mbIndex :: Maybe SearchIndex
27+type State = { mbIndex :: Maybe SearchIndex
2928 , results :: Array SearchResult
3029 , input :: String
30+ , contents :: Element
3131 }
3232
3333data Query a
3434 = SearchFieldMessage Message a
3535
36−component :: forall i o. H.Component HH.HTML Query i o Aff
37−component =
36+mkComponent :: forall i o. Element -> H.Component HH.HTML Query i o Aff
37+mkComponent contents =
3838 H.mkComponent
3939 { initialState:
40− const { mbIndex: Nothing, results: [], shown: false, input: "" }
40+ const { mbIndex: Nothing, results: [], input: "", contents }
4141 , render
4242 , eval: H.mkEval $ H.defaultEval { handleQuery = handleQuery }
4343 }
4444
4545handleQuery :: forall o a. Query a -> H.HalogenM State Unit () o Aff (Maybe a)
4646handleQuery (SearchFieldMessage Focused next) = do
47− H.modify_ (_ { shown = true })
4847 state <- H.get
4948 when (isNothing state.mbIndex) do
50− declarations <- H.liftAff $ loadDeclarations "../spago-search-index.js"
51− H.modify_ (_ { mbIndex = Just $ mkSearchIndex declarations })
49+ eiDeclarations <- H.liftAff $ loadDeclarations "../spago-search-index.js"
50+ case eiDeclarations of
51+ Left err -> do
52+ H.liftEffect do
53+ error $ "spago-search: couldn't load search index: " <> err
54+ Right declarations -> do
55+ H.modify_ (_ { mbIndex = Just $ mkSearchIndex declarations })
5256 pure Nothing
5357handleQuery (SearchFieldMessage LostFocus next) = do
5458 state <- H.get
5559 when (Array.null state.results) do
56− H.modify_ (_ { shown = false })
60+ showPageContents
5761 pure Nothing
5862handleQuery (SearchFieldMessage (InputUpdated input) next) = do
5963 H.modify_ (_ { input = input })
60−
61− if String.null input
64+ if String.length input < 2
6265 then do
66+ showPageContents
6367 H.modify_ (_ { results = [] })
6468 else do
69+ hidePageContents
6570 state <- H.get
6671 whenJust (unwrap <$> state.mbIndex) \index -> do
6772 let path = List.fromFoldable $
@@ -76,33 +81,91 @@ handleQuery (SearchFieldMessage (InputUpdated input) next) = do
7681
7782 pure Nothing
7883
84+showPageContents :: forall o. H.HalogenM State Unit () o Aff Unit
85+showPageContents = do
86+ state <- H.get
87+ H.liftEffect do
88+ Element.removeAttribute "style" state.contents
89+
90+hidePageContents :: forall o. H.HalogenM State Unit () o Aff Unit
91+hidePageContents = do
92+ state <- H.get
93+ H.liftEffect do
94+ Element.setAttribute "style" "display: none" state.contents
95+
7996render :: forall m. State -> H.ComponentHTML Unit () m
80−render { mbIndex: Nothing, shown: true } =
81− renderSummary "Loading index..."
82−render { mbIndex: Nothing, shown: false } =
97+render { mbIndex: Nothing } =
98+ HH.div_ []
99+render { input: "" } =
83100 HH.div_ []
84−render state
85− | not state.shown || String.null state.input = HH.div_ []
86− | otherwise =
87− HH.div
88− [ HS.style do
89− float floatLeft
101+render state =
102+ HH.div [ HP.classes [ wrap "container"
103+ , wrap "clearfix"
104+ ]
105+ ]
106+ if Array.null state.results
107+ then
108+ [ renderSummary "No search results" ]
109+ else
110+ [ renderSummary $
111+ "Found " <>
112+ show (Array.length state.results) <>
113+ " definitions" ] <>
114+
115+ [ HH.div [ HP.id_ "spage-search-results-container" ] $
116+ Array.concat $
117+ state.results <#> renderResult
90118 ]
91− if Array.null state.results
92− then
93− [ renderSummary "No search results" ]
94− else
95− [ renderSummary $
96− "Found " <>
97− show (Array.length state.results) <>
98− " definitions" ] <>
99−
100− [ HH.div_ $ state.results <#> \result ->
101− HH.div_ [ HH.text (unwrap result).name ]
102− ]
103119
104120renderSummary :: forall a b. String -> HH.HTML b a
105121renderSummary text =
106122 HH.div [ HP.id_ "spago-search-summary" ]
107123 [ HH.text text
108124 ]
125+
126+renderResult :: forall a b. SearchResult -> Array (HH.HTML a b)
127+renderResult = unwrap >>> \result ->
128+ [ HH.div [ HP.class_ (wrap "result") ]
129+ [ HH.h3 [ HP.class_ (wrap "result__title") ]
130+ [ HH.a [ HP.class_ (wrap "result__link") ]
131+ [ HH.text result.name ]
132+ ]
133+ ]
134+
135+ , HH.div [ HP.class_ (wrap "result__body") ] $
136+ [ HH.pre [ HP.class_ (wrap "result__signature") ]
137+ [ HH.code_ []
138+ ]
139+ ] <>
140+
141+ case result.comments of
142+ Just comments -> [ HH.pre_
143+ [ HH.text comments
144+ ]
145+ ]
146+ Nothing -> [ ]
147+
148+ , HH.div [ HP.class_ (wrap "result__actions") ]
149+ [ HH.span [ HP.class_ (wrap "result__actions__item") ]
150+ [ HH.span [ HP.classes [ wrap "badge"
151+ , wrap "badge--package"
152+ ]
153+ , HP.title "Package"
154+ ]
155+ [ HH.text "P"
156+ ]
157+ , HH.text result.packageName
158+ ]
159+
160+ , HH.span [ HP.class_ (wrap "result__actions__item") ]
161+ [ HH.span [ HP.classes [ wrap "badge"
162+ , wrap "badge--module"
163+ ]
164+ , HP.title "Module"
165+ ]
166+ [ HH.text "M"
167+ ]
168+ , HH.text result.moduleName
169+ ]
170+ ]
171+ ]