Loader2.purs 1.27 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
import Reactix as R

11 12
type Props path loaded = { path :: path, loaded :: loaded }

Nicolas Pouillard's avatar
Nicolas Pouillard committed
13 14 15 16 17 18 19
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
20
  -> (path -> Aff loaded)
21
  -> (Props path loaded -> R.Element)
Nicolas Pouillard's avatar
Nicolas Pouillard committed
22
  -> R.Hooks R.Element
Nicolas Pouillard's avatar
Nicolas Pouillard committed
23 24 25
useLoader newPath loader render = do
  {currentPath, loaded} /\ setState <- R.useState' { currentPath: newPath, loaded: Nothing }

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

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

  pure case loaded of
    Nothing ->
      -- TODO load spinner
Nicolas Pouillard's avatar
Nicolas Pouillard committed
40
      R.fragment []
Nicolas Pouillard's avatar
Nicolas Pouillard committed
41
    Just loadedData ->
42
      render {path: currentPath, loaded: loadedData}