Skip to content

Commit f04ed69

Browse files
committed
debounce is configurable for every action, showing app version in ui
1 parent 65d0f07 commit f04ed69

File tree

3 files changed

+71
-40
lines changed

3 files changed

+71
-40
lines changed

ghcjs/currency-converter/Main.hs

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import qualified Data.ByteString.Lazy as BL
1212
#endif
1313
import qualified Data.List.NonEmpty as NonEmpty
1414
import qualified Data.Map as Map
15+
import qualified Data.Text as T
16+
import qualified Data.Version as Version
1517
import Functora.Money
1618
import Functora.Prelude as Prelude
1719
import Functora.Rates
@@ -27,7 +29,8 @@ import qualified Material.Theme as Theme
2729
import qualified Material.Typography as Typography
2830
import Miso hiding (view)
2931
import qualified Miso
30-
import Miso.String hiding (cons, foldl, null, reverse)
32+
import Miso.String hiding (cons, foldl, intercalate, null, reverse)
33+
import qualified Paths_app as Paths
3134
import qualified Text.Fuzzy as Fuzzy
3235

3336
#ifndef __GHCJS__
@@ -61,12 +64,18 @@ data Model = Model
6164
modelMarket :: MVar Market,
6265
modelCurrencies :: NonEmpty CurrencyInfo,
6366
modelSnackbarQueue :: Snackbar.Queue Action,
64-
modelProducerQueue :: TChan (Model -> Model),
65-
modelConsumerQueue :: TChan (Model -> Model),
67+
modelProducerQueue :: TChan (ChanItem (Model -> Model)),
68+
modelConsumerQueue :: TChan (ChanItem (Model -> Model)),
6669
modelUpdatedAt :: UTCTime
6770
}
6871
deriving stock (Eq, Generic)
6972

73+
data ChanItem a = ChanItem
74+
{ chanItemDelay :: Natural,
75+
chanItemValue :: a
76+
}
77+
deriving stock (Eq, Ord, Show, Read, Data, Generic)
78+
7079
data TopOrBottom
7180
= Top
7281
| Bottom
@@ -191,15 +200,17 @@ data Action
191200
| InitUpdate
192201
| TimeUpdate
193202
| ChanUpdate Model
194-
| PushUpdate (JSM ()) (Model -> Model)
203+
| PushUpdate (JSM ()) (ChanItem (Model -> Model))
195204

196205
--
197206
-- NOTE : In most cases we don't need JSM.
198207
--
199-
pureUpdate :: (Model -> Model) -> Action
200-
pureUpdate = PushUpdate $ pure ()
208+
pureUpdate :: Natural -> (Model -> Model) -> Action
209+
pureUpdate delay =
210+
PushUpdate (pure ())
211+
. ChanItem delay
201212

202-
pushActionQueue :: (MonadIO m) => Model -> (Model -> Model) -> m ()
213+
pushActionQueue :: (MonadIO m) => Model -> ChanItem (Model -> Model) -> m ()
203214
pushActionQueue st =
204215
liftIO
205216
. atomically
@@ -255,7 +266,7 @@ updateModel InitUpdate prevSt = do
255266
{ modelProducerQueue = prod,
256267
modelConsumerQueue = cons
257268
}
258-
pushActionQueue nextSt (& #modelHide .~ False)
269+
pushActionQueue nextSt $ ChanItem 0 (& #modelHide .~ False)
259270
pure $ ChanUpdate nextSt
260271
]
261272
updateModel TimeUpdate st = do
@@ -266,7 +277,9 @@ updateModel TimeUpdate st = do
266277
pure TimeUpdate,
267278
do
268279
ct <- getCurrentTime
269-
unless (upToDate ct $ st ^. #modelUpdatedAt) $ pushActionQueue st id
280+
unless (upToDate ct $ st ^. #modelUpdatedAt)
281+
. pushActionQueue st
282+
$ ChanItem 0 id
270283
pure Noop
271284
]
272285
updateModel (ChanUpdate prevSt) _ = do
@@ -291,19 +304,25 @@ updateModel (PushUpdate runJSM updater) st = do
291304
pure Noop
292305
]
293306

294-
drainTChan :: (MonadIO m) => TChan a -> m [a]
307+
drainTChan :: (MonadIO m) => TChan (ChanItem a) -> m [a]
295308
drainTChan chan = do
296309
item <- liftIO . atomically $ readTChan chan
297310
liftIO
298-
. fmap ((item :) . reverse)
299-
$ drainInto [] False
311+
. fmap ((chanItemValue item :) . reverse)
312+
. drainInto []
313+
$ chanItemDelay item
300314
where
301-
drainInto acc debounced = do
315+
drainInto acc delay = do
302316
item <- atomically $ tryReadTChan chan
303317
case item of
304-
Nothing | debounced -> pure acc
305-
Nothing -> sleepMilliSeconds 300 >> drainInto acc True
306-
Just next -> drainInto (next : acc) False
318+
Nothing | delay == 0 -> pure acc
319+
Nothing -> do
320+
sleepMilliSeconds $ from @Natural @Integer delay
321+
drainInto acc 0
322+
Just next ->
323+
drainInto (chanItemValue next : acc)
324+
. max delay
325+
$ chanItemDelay next
307326

308327
syncInputs :: Model -> JSM ()
309328
syncInputs st =
@@ -342,10 +361,9 @@ updateSnackbar ::
342361
) =>
343362
(Snackbar.Queue Action -> Snackbar.Queue Action) ->
344363
a ->
345-
Model ->
346-
Model
364+
ChanItem (Model -> Model)
347365
updateSnackbar before x =
348-
(& #modelSnackbarQueue %~ (Snackbar.addMessage msg . before))
366+
ChanItem 0 (& #modelSnackbarQueue %~ (Snackbar.addMessage msg . before))
349367
where
350368
msg =
351369
inspect x
@@ -527,7 +545,7 @@ amountWidget st loc =
527545
(parseMoney input == Just output)
528546
|| (input == inspectMoneyAmount output)
529547
onBlurAction =
530-
pureUpdate $ \st' ->
548+
pureUpdate 0 $ \st' ->
531549
if valid
532550
then st'
533551
else
@@ -546,9 +564,10 @@ amountWidget st loc =
546564
<> inspect loc
547565
<> "').getElementsByTagName('input')[0].blur();"
548566
)
549-
id
567+
( ChanItem 300 id
568+
)
550569
onInputAction txt =
551-
pureUpdate $ \st' ->
570+
pureUpdate 300 $ \st' ->
552571
st'
553572
& #modelData
554573
. getMoneyOptic loc
@@ -565,7 +584,8 @@ amountWidget st loc =
565584
. getMoneyOptic loc
566585
. #modelMoneyAmountInput
567586
)
568-
id
587+
( ChanItem 0 id
588+
)
569589
onClearAction =
570590
PushUpdate
571591
( do
@@ -576,7 +596,7 @@ amountWidget st loc =
576596
<> inspect loc
577597
<> "'); if (el) el.value = '';"
578598
)
579-
( \st' ->
599+
( ChanItem 300 $ \st' ->
580600
st'
581601
& #modelData
582602
. getMoneyOptic loc
@@ -668,14 +688,14 @@ currencyWidget st loc =
668688
]
669689
where
670690
search input =
671-
pureUpdate $ \st' ->
691+
pureUpdate 0 $ \st' ->
672692
st'
673693
& #modelData
674694
. getMoneyOptic loc
675695
. #modelMoneyCurrencySearch
676696
.~ from @String @Text input
677697
opened =
678-
pureUpdate $ \st' ->
698+
pureUpdate 0 $ \st' ->
679699
st'
680700
& #modelData
681701
. getMoneyOptic loc
@@ -686,7 +706,7 @@ currencyWidget st loc =
686706
. #modelMoneyCurrencySearch
687707
.~ mempty
688708
closed =
689-
pureUpdate $ \st' ->
709+
pureUpdate 0 $ \st' ->
690710
st'
691711
& #modelData
692712
. getMoneyOptic loc
@@ -735,7 +755,7 @@ currencyListItemWidget loc current item =
735755
else Nothing
736756
)
737757
& ListItem.setOnClick
738-
( pureUpdate $ \st ->
758+
( pureUpdate 0 $ \st ->
739759
st
740760
& #modelData
741761
. getMoneyOptic loc
@@ -773,7 +793,7 @@ swapAmountsWidget =
773793
"Swap amounts"
774794
where
775795
onClickAction =
776-
pureUpdate $ \st ->
796+
pureUpdate 0 $ \st ->
777797
let baseInput =
778798
st ^. #modelData . #modelDataTopMoney . #modelMoneyAmountInput
779799
baseOutput =
@@ -819,7 +839,7 @@ swapCurrenciesWidget =
819839
"Swap currencies"
820840
where
821841
onClickAction =
822-
pureUpdate $ \st ->
842+
pureUpdate 0 $ \st ->
823843
let baseCurrency =
824844
st ^. #modelData . #modelDataTopMoney . #modelMoneyCurrencyInfo
825845
quoteCurrency =
@@ -851,12 +871,13 @@ copyright =
851871
a_ [href_ "license.html"] [Miso.text "Terms and Conditions"],
852872
Miso.text " and ",
853873
a_ [href_ "privacy.html"] [Miso.text "Privacy Policy"],
854-
Miso.text "."
874+
Miso.text ". ",
875+
Miso.text . ms $ "Version " <> vsn <> "."
855876
]
856877

857878
snackbarClosed :: Snackbar.MessageId -> Action
858879
snackbarClosed msg =
859-
pureUpdate (& #modelSnackbarQueue %~ Snackbar.close msg)
880+
pureUpdate 0 (& #modelSnackbarQueue %~ Snackbar.close msg)
860881

861882
inspectMoneyAmount :: (MoneyTags tags, From String a) => Money tags -> a
862883
inspectMoneyAmount =
@@ -867,3 +888,9 @@ upToDate lhs rhs =
867888
diff < 3600
868889
where
869890
diff = abs . toRational $ diffUTCTime lhs rhs
891+
892+
vsn :: Text
893+
vsn =
894+
T.intercalate "."
895+
. fmap inspect
896+
$ Version.versionBranch Paths.version

ghcjs/currency-converter/app.cabal

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 2.2
22
name: app
3-
version: 0.1.0.2
3+
version: 0.1.0.3
44
synopsis: First miso app
55
category: Web
66
build-type: Simple
@@ -10,6 +10,8 @@ flag ghcid
1010
default: False
1111

1212
common pkg
13+
other-modules: Paths_app
14+
autogen-modules: Paths_app
1315
default-language: Haskell2010
1416
js-sources:
1517
static/app.js
@@ -70,9 +72,9 @@ common pkg
7072
TypeOperators
7173

7274
executable app
73-
import: pkg
74-
main-is: Main.hs
75-
ghcjs-options: -dedupe
75+
import: pkg
76+
main-is: Main.hs
77+
ghcjs-options: -dedupe
7678
build-depends:
7779
, base
7880
, containers
@@ -81,6 +83,7 @@ executable app
8183
, jsaddle
8284
, miso
8385
, miso-components
86+
, text
8487

8588
if !impl(ghcjs)
8689
build-depends:
@@ -91,7 +94,8 @@ executable app
9194
, warp
9295
, websockets
9396

97+
if impl(ghcjs)
98+
ghc-options: -Wno-missing-home-modules
99+
94100
if (flag(ghcid) && impl(ghc >=8.10.7))
95101
ghc-options: -Wno-unused-packages
96-
97-
default-language: Haskell2010

ghcjs/currency-converter/trapeze.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
platforms:
22
android:
33
appName: Currency Converter
4-
versionCode: 3
5-
versionName: 0.1.0.2
4+
versionCode: 4
5+
versionName: 0.1.0.3
66
packageName: com.functora.currency_converter
77
manifest:
88
- file: AndroidManifest.xml

0 commit comments

Comments
 (0)