1{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE RankNTypes #-}
5{-# LANGUAGE RecursiveDo #-}
6{-# LANGUAGE ScopedTypeVariables #-}
10------------------------------------------------------------------------------
13import Control.Monad.Fix (MonadFix)
14import Data.Monoid (First(..), (<>))
15import Data.Text (Text)
16import qualified Data.Text as T
21import Text.Read (readMaybe)
23------------------------------------------------------------------------------
25import Servant.Reflex.Multi
33 el "h1" $ text "Wowzers!"
34 divClass "example-base" run
35 divClass "example-multi" runMulti
38runMulti :: forall t m. (SupportsServantReflex t m,
40 DomBuilderSpace m ~ GhcjsDomSpace,
43 MonadHold t m) => m ()
47 let (_ :<|> _ :<|> sayHi :<|> dbl :<|> _ :<|> _ ) =
48 clientA api (Proxy :: Proxy m) (Proxy :: Proxy []) (Proxy :: Proxy Int) url
50 num :: Dynamic t (Either Text Double) <- fmap (note "No read" . readMaybe . T.unpack) . value <$> textInput def
51 num2 :: Dynamic t (Either Text Double) <- fmap (note "No read" . readMaybe . T.unpack) . value <$> textInput def
53 b <- button "Run dbl multi"
54 reqCount :: Dynamic t Int <- count b
55 r <- dbl ((\x y -> [x,y]) <$> num <*> num2) (tag (current reqCount) b)
56 dynText =<< holdDyn "Waiting" (T.pack . show . fmap reqSuccess <$> r)
58 lastInd <- holdDyn [] $ fmap reqTag <$> r
61 divClass "demo-group" $ do
62 nms <- fmap (fmap T.words . value) $ divClass "" $ do
65 grts <- fmap (fmap T.words . value) $ divClass "" $ do
68 gust <- fmap value $ divClass "gusto-input" $ checkbox False def
70 r' <- sayHi (fmap QParamSome <$> nms) (fmap (:[]) grts) (constDyn [True, False]) (1 <$ b)
72 dynText =<< holdDyn "Waiting" (T.pack . show . catMaybes . fmap reqSuccess <$> r')
76run :: forall t m. (SupportsServantReflex t m,
78 DomBuilderSpace m ~ GhcjsDomSpace,
81 MonadHold t m) => m ()
84 reqCount <- count $ leftmost
85 [() <$ unitBtn, () <$ intBtn, () <$ sayHiClicks, () <$ dblBtn, () <$ mpGo]
86 -- Allow user to choose the url target for the request
87 -- (alternatively we could just `let url = constDyn (BasePath "/")`)
90 dynText $ showBaseUrl <$> url
94 -- Name the computed API client functions
95 let (getUnit :<|> getInt :<|> sayhi :<|> dbl :<|> multi :<|> qna :<|> doRaw) =
96 client api (Proxy :: Proxy m) (Proxy :: Proxy Int) url
98 c2 = client (Proxy :: Proxy ComprehensiveAPI) (Proxy :: Proxy m) (Proxy :: Proxy ()) url -- Just make sure this compiles for now
100 (unitBtn, intBtn) <- elClass "div" "demo-group" $ do
101 unitBtn <- divClass "unit-button" $ button "Get unit"
102 intBtn <- divClass "int-button" $ button "Get int"
104 unitResponse <- getUnit $ tag (current reqCount) unitBtn
105 intResponse :: Event t (ReqResult Int Int) <- getInt $ tag (current reqCount) intBtn
107 score <- foldDyn (+) 0 (fmapMaybe reqSuccess intResponse)
109 r <- holdDyn "Waiting" $ showXhrResponse <$>
110 leftmost [fmapMaybe response unitResponse
111 ,fmapMaybe response intResponse
113 divClass "unit-int-response" $ el "p" $ dynText r >> el "br" (return ()) >> text "Total: " >> display score
114 return (unitBtn, intBtn)
116 sayHiClicks <- elClass "div" "demo-group" $ do
120 inp :: Dynamic t Text <- fmap value $ divClass "name-input" $ textInput def
121 let checkedName = fmap (\i -> bool (QParamSome i) (QParamInvalid "Need a name") (T.null i)) inp
124 text "Greetings (space-separated)"
126 greetings <- fmap (fmap T.words . value) $
127 divClass "greetings-input" $ textInput def
131 gusto <- fmap value $ divClass "gusto-input" $ checkbox False def
134 sayHiClicks :: Event t () <- divClass "hi-button" $ button "Say hi"
135 let triggers = leftmost [sayHiClicks, () <$ updated inp]
137 resp <- sayhi checkedName greetings gusto (tag (current reqCount) triggers)
138 divClass "greeting-response" $ dynText =<<
139 holdDyn "No hi yet" (leftmost [ fmapMaybe reqSuccess resp
140 , fmapMaybe reqFailure resp])
143 dblBtn <- elClass "div" "demo-group" $ do
144 text "A Double to double"
146 dblinp <- fmap value $ divClass "double-input" $ textInput def
147 dblBtn <- divClass "double-button" $ button "Double it"
148 dblResp <- dbl ((note "read failure" . readMaybe . T.unpack) <$>
149 dblinp) (tag (current reqCount) dblBtn)
150 divClass "double-errors" $ dynText =<<
151 holdDyn "(no errors)" (fmapMaybe reqFailure dblResp)
153 divClass "double-result" $ el "p" $ dynText =<<
154 holdDyn "No number yet" (tShow <$>
155 fmapMaybe reqSuccess dblResp)
158 mpGo <- elClass "div" "demo-group" $ do
159 text "Multi-part path"
160 b <- value <$> checkbox False def
161 mpGo <- button "Test"
162 multiResp <- multi b (tag (current reqCount) mpGo)
163 dynText =<< holdDyn "No res yet" (tShow <$>
172 elClass "div" "demo-group" $ do
173 text "JSON Unicode encoding test"
174 txt <- value <$> textInput def
175 ev <- (1 <$) <$> button "Question"
176 let dQ = Right . Question <$> traceDyn "will send: " txt
179 dynText =<< holdDyn "No Answer" (unAnswer <$> fmapMaybe reqSuccess rr)
181showXhrResponse :: XhrResponse -> Text
182showXhrResponse (XhrResponse stat stattxt rbmay rtmay respHeaders) =
183 T.unlines ["stat: " <> tShow stat
184 ,"stattxt: " <> tShow stattxt
185 ,"resp: " <> maybe "" showRB rbmay
186 ,"rtext: " <> tShow rtmay
187 ,"rHeaders: " <> tShow respHeaders]
189tShow :: Show a => a -> Text
192showRB :: XhrResponseBody -> Text
193showRB (XhrResponseBody_Default t) = tShow t
194showRB (XhrResponseBody_Text t) = tShow t
195showRB (XhrResponseBody_Blob t) = "<Blob>"
196showRB (XhrResponseBody_ArrayBuffer t) = tShow t
198note :: e -> Maybe a -> Either e a
199note e = maybe (Left e) Right
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list