@@ -1,11 +1,13 @@
11{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE FlexibleContexts #-}
32{-# LANGUAGE DataKinds #-}
3+{-# LANGUAGE FlexibleContexts #-}
44{-# LANGUAGE LambdaCase #-}
55{-# LANGUAGE OverloadedStrings #-}
6+{-# LANGUAGE RecursiveDo #-}
67{-# LANGUAGE TypeApplications #-}
78module Frontend where
89
10+import qualified Data.Map as M
911import Data.Text (Text)
1012import Obelisk.Frontend
1113import Obelisk.Route
@@ -35,20 +37,28 @@ type FrontendWidget js t m =
3537 )
3638
3739data State = NotStarted | Loading | Loaded (Maybe Text)
40+ deriving (Eq)
41+
42+submitAttrs :: State -> M.Map Text Text
43+submitAttrs = \case
44+ Loading -> ("disabled" =: "true")
45+ _ -> mempty
3846
3947urlInput :: AppWidget js t m => m (Dynamic t State)
4048urlInput = do
41− inputEl <- el "label" $ do
42− text "url: "
43− inputElement def
44− click <- button "shorten"
45− let url = tagPromptlyDyn (_inputElement_value inputEl) click
46− request <- prerender
47− (pure never)
48− ((decodeXhrResponse <$>) <$> performRequestAsync (shortenRequest <$> url))
49− let requestEv = switchDyn request
50− holdDyn NotStarted $
51− leftmost [Loading <$ click, Loaded <$> requestEv]
49+ rec
50+ inputEl <- inputElement $ def
51+ (submitBtn,_) <- elAttr "span" ("id" =: "submit") $
52+ elDynAttr' "button" (submitAttrs <$> state) $ text "shorten"
53+ let click = domEvent Click submitBtn
54+ let url = tagPromptlyDyn (_inputElement_value inputEl) click
55+ request <- prerender
56+ (pure never)
57+ ((decodeXhrResponse <$>) <$> performRequestAsync (shortenRequest <$> url))
58+ state <- holdDyn NotStarted $
59+ leftmost [Loading <$ click, Loaded <$> switchDyn request]
60+ _ <- pure state
61+ pure state
5262
5363createShortLinkRoute :: Text
5464createShortLinkRoute = renderBackendRoute checkedFullRouteEncoder $ BackendRoute_Shorten :/ ()
@@ -59,14 +69,14 @@ shortenRequest s = postJson createShortLinkRoute (ShortenRequest s)
5969createdLink :: AppWidget js t m => State -> m ()
6070createdLink = \case
6171 NotStarted -> blank
62− Loading -> text "loading"
72+ Loading -> text "shortening..."
6373 Loaded a -> case a of
6474 Nothing -> text "Error"
6575 Just url -> elAttr "a" ("href" =: url) $ text url
6676
6777app :: AppWidget js t m => m ()
6878app = do
69− state <- urlInput
79+ state <- el "div" $ urlInput
7080 _ <- dyn $ createdLink <$> state
7181 blank
7282
@@ -75,5 +85,6 @@ frontend = Frontend
7585 { _frontend_head = do
7686 el "title" $ text "Url Shortener"
7787 elAttr "link" ("rel" =: "stylesheet" <> "href" =: static @"style.css") blank
88+ elAttr "link" ("rel" =: "stylesheet" <> "href" =: "https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.css") blank
7889 , _frontend_body = app
7990 }