Loader2.purs 1.19 KB
Newer Older
Nicolas Pouillard's avatar
Nicolas Pouillard committed
1 2 3 4 5
module Gargantext.Components.Loader2 where

import Data.Maybe (Maybe(..), isNothing)
import Data.Tuple.Nested ((/\))
import Gargantext.Prelude
Nicolas Pouillard's avatar
Nicolas Pouillard committed
6 7 8
import Effect.Aff (Aff, launchAff, launchAff_, killFiber)
import Effect.Class (liftEffect)
import Effect.Exception (error)
Nicolas Pouillard's avatar
Nicolas Pouillard committed
9 10 11 12 13 14 15 16 17
import Reactix as R

type State path loaded = { currentPath :: path, loaded :: Maybe loaded }

useLoader
  :: forall path loaded
  .  Eq path
  => Show path
  => path
Nicolas Pouillard's avatar
Nicolas Pouillard committed
18 19 20
  -> (path -> Aff loaded)
  -> (path -> loaded -> R.Element)
  -> R.Hooks R.Element
Nicolas Pouillard's avatar
Nicolas Pouillard committed
21 22 23
useLoader newPath loader render = do
  {currentPath, loaded} /\ setState <- R.useState' { currentPath: newPath, loaded: Nothing }

24
  R.useEffect $
Nicolas Pouillard's avatar
Nicolas Pouillard committed
25
    if (isNothing loaded || newPath /= currentPath) then do
Nicolas Pouillard's avatar
Nicolas Pouillard committed
26
      logs $ "useLoader " <> show {newPath, currentPath, loadedIsNothing: isNothing loaded}
Nicolas Pouillard's avatar
Nicolas Pouillard committed
27 28 29

      fiber <- launchAff do
        freshlyLoaded <- loader newPath
30 31
        liftEffect $ setState $ const { currentPath: newPath, loaded: Just freshlyLoaded }
      pure $ launchAff_ $ killFiber (error "useLoader") fiber
Nicolas Pouillard's avatar
Nicolas Pouillard committed
32
    else do
33
      pure $ pure $ unit
Nicolas Pouillard's avatar
Nicolas Pouillard committed
34 35 36 37

  pure case loaded of
    Nothing ->
      -- TODO load spinner
Nicolas Pouillard's avatar
Nicolas Pouillard committed
38
      R.fragment []
Nicolas Pouillard's avatar
Nicolas Pouillard committed
39 40
    Just loadedData ->
      render currentPath loadedData