From 2a4b56fc704d784c52184e3744b44f17bd6a5729 Mon Sep 17 00:00:00 2001
From: James Laver <james.laver@gmail.com>
Date: Fri, 20 Sep 2019 15:55:22 +0200
Subject: [PATCH] Replace G.C.Loader2 with G.Hooks.Loader

---
 src/Gargantext/Components/DocsTable.purs      |  4 +-
 src/Gargantext/Components/Loader2.purs        | 42 -----------------
 src/Gargantext/Components/Tree.purs           |  2 +-
 src/Gargantext/Hooks/Loader.purs              | 45 +++++++++++++++++++
 src/Gargantext/Pages/Corpus/Chart/Histo.purs  |  4 +-
 .../Pages/Corpus/Chart/Metrics.purs           |  3 +-
 src/Gargantext/Pages/Corpus/Chart/Pie.purs    |  5 ++-
 src/Gargantext/Pages/Corpus/Chart/Tree.purs   |  4 +-
 src/Gargantext/Pages/Corpus/Document.purs     |  2 +-
 src/Gargantext/Pages/Lists.purs               |  2 +-
 src/Gargantext/Pages/Texts.purs               |  2 +-
 11 files changed, 63 insertions(+), 52 deletions(-)
 delete mode 100644 src/Gargantext/Components/Loader2.purs
 create mode 100644 src/Gargantext/Hooks/Loader.purs

diff --git a/src/Gargantext/Components/DocsTable.purs b/src/Gargantext/Components/DocsTable.purs
index bb9db699..62cb35b7 100644
--- a/src/Gargantext/Components/DocsTable.purs
+++ b/src/Gargantext/Components/DocsTable.purs
@@ -25,9 +25,11 @@ import Reactix.DOM.HTML as H
 import Gargantext.Prelude
 import Gargantext.Config (End(..), NodeType(..), OrderBy(..), Path(..), TabType, TabPostQuery(..), toUrl, endConfigStateful, toLink)
 import Gargantext.Config.REST (get, put, post, deleteWithBody, delete)
-import Gargantext.Components.Loader2 (useLoader)
+import Gargantext.Components.Node (NodePoly(..))
 import Gargantext.Components.Search.Types (Category(..), CategoryQuery(..), favCategory, trashCategory, decodeCategory, putCategories)
 import Gargantext.Components.Table as T
+import Gargantext.Hooks.Loader (useLoader)
+import Gargantext.Utils.DecodeMaybe ((.|))
 import Gargantext.Utils.Reactix as R2
 import Gargantext.Router as Router
 ------------------------------------------------------------------------
diff --git a/src/Gargantext/Components/Loader2.purs b/src/Gargantext/Components/Loader2.purs
deleted file mode 100644
index a426bcf7..00000000
--- a/src/Gargantext/Components/Loader2.purs
+++ /dev/null
@@ -1,42 +0,0 @@
-module Gargantext.Components.Loader2 where
-
-import Data.Maybe (Maybe(..), isNothing)
-import Data.Tuple.Nested ((/\))
-import Gargantext.Prelude
-import Effect.Aff (Aff, launchAff, launchAff_, killFiber)
-import Effect.Class (liftEffect)
-import Effect.Exception (error)
-import Reactix as R
-
-type Props path loaded = { path :: path, loaded :: loaded }
-
-type State path loaded = { currentPath :: path, loaded :: Maybe loaded }
-
-useLoader
-  :: forall path loaded
-  .  Eq path
-  => Show path
-  => path
-  -> (path -> Aff loaded)
-  -> (Props path loaded -> R.Element)
-  -> R.Hooks R.Element
-useLoader newPath loader render = do
-  {currentPath, loaded} /\ setState <- R.useState' { currentPath: newPath, loaded: Nothing }
-
-  R.useEffect $
-    if (isNothing loaded || newPath /= currentPath) then do
-      logs $ "useLoader " <> show {newPath, currentPath, loadedIsNothing: isNothing loaded}
-
-      fiber <- launchAff do
-        freshlyLoaded <- loader newPath
-        liftEffect $ setState $ const { currentPath: newPath, loaded: Just freshlyLoaded }
-      pure $ launchAff_ $ killFiber (error "useLoader") fiber
-    else do
-      pure $ pure $ unit
-
-  pure case loaded of
-    Nothing ->
-      -- TODO load spinner
-      R.fragment []
-    Just loadedData ->
-      render {path: currentPath, loaded: loadedData}
diff --git a/src/Gargantext/Components/Tree.purs b/src/Gargantext/Components/Tree.purs
index b1b29b99..ab7d9a63 100644
--- a/src/Gargantext/Components/Tree.purs
+++ b/src/Gargantext/Components/Tree.purs
@@ -28,10 +28,10 @@ import Web.File.File (toBlob)
 import Web.File.FileList (FileList, item)
 import Web.File.FileReader.Aff (readAsText)
 
-import Gargantext.Components.Loader2 (useLoader)
 import Gargantext.Config (toUrl, EndConfig, endConfig, End(..), NodeType(..), readNodeType)
 import Gargantext.Config as C
 import Gargantext.Config.REST (get, put, post, postWwwUrlencoded, delete)
+import Gargantext.Hooks.Loader (useLoader)
 import Gargantext.Router as Router
 import Gargantext.Types (class ToQuery, toQuery)
 import Gargantext.Utils (id)
diff --git a/src/Gargantext/Hooks/Loader.purs b/src/Gargantext/Hooks/Loader.purs
new file mode 100644
index 00000000..486cb266
--- /dev/null
+++ b/src/Gargantext/Hooks/Loader.purs
@@ -0,0 +1,45 @@
+module Gargantext.Hooks.Loader where
+
+import Data.Maybe (Maybe(..), isNothing, maybe)
+import Data.Tuple (fst)
+import Data.Tuple.Nested ((/\))
+import Gargantext.Prelude
+import Effect.Aff (Aff)
+import Effect.Class (liftEffect)
+import Reactix as R
+import Gargantext.Utils.Reactix as R2
+import Gargantext.Components.LoadingSpinner (loadingSpinner)
+
+useLoader :: forall path state. path -> (path -> Aff state) -> (state -> R.Element) -> R.Hooks R.Element
+useLoader path loader render = do
+  state <- R.useState' Nothing
+  loader' <- R.useMemo2 path loader (\_ -> loader path)
+  useLoaderEffect state loader'
+  pure $ maybe (loadingSpinner {}) render (fst state)
+
+useLoader2 :: forall path state. R.State path -> (path -> Aff state) -> (state -> R.Element) -> R.Hooks R.Element
+useLoader2 path loader render = do
+  state <- R.useState' Nothing
+  useLoaderEffect2 path state loader
+  pure $ maybe (loadingSpinner {}) render (fst state)
+  
+useLoaderEffect :: forall state. R.State (Maybe state) -> Aff state -> R.Hooks Unit
+useLoaderEffect (state /\ setState) loader = do
+  R.useEffect2 state loader $ do
+    if isNothing state then
+      R2.affEffect "useLoader" $ loader >>= (liftEffect <<< setState <<< const <<< Just)
+    else pure R.nothing
+
+useLoaderEffect' :: forall state. Aff state -> R.Hooks (R.State (Maybe state))
+useLoaderEffect' aff = do
+  state <- R.useState' Nothing
+  useLoaderEffect state aff
+  pure state
+
+useLoaderEffect2 :: forall st path. R.State path -> R.State (Maybe st) -> (path -> Aff st) -> R.Hooks Unit
+useLoaderEffect2 path state loader = useRepointer path loader >>= useLoaderEffect state
+
+useRepointer :: forall path st. R.State path -> (path -> Aff st) -> R.Hooks (Aff st)
+useRepointer path@(path' /\ _) loader = R.useMemo1 path' (\_ -> loader path')
+
+
diff --git a/src/Gargantext/Pages/Corpus/Chart/Histo.purs b/src/Gargantext/Pages/Corpus/Chart/Histo.purs
index d6d4be76..0ad884db 100644
--- a/src/Gargantext/Pages/Corpus/Chart/Histo.purs
+++ b/src/Gargantext/Pages/Corpus/Chart/Histo.purs
@@ -9,12 +9,14 @@ import Reactix as R
 import Thermite (Spec)
 
 import Gargantext.Prelude
-import Gargantext.Components.Loader2 (useLoader)
+import Gargantext.Types (TermList(..))
+import Gargantext.Components.Loader as Loader
 import Gargantext.Components.Charts.Options.ECharts
 import Gargantext.Components.Charts.Options.Series
 import Gargantext.Components.Charts.Options.Color
 import Gargantext.Components.Charts.Options.Font
 import Gargantext.Components.Charts.Options.Data
+import Gargantext.Hooks.Loader (useLoader)
 import Gargantext.Utils.Reactix as R2
 import Gargantext.Pages.Corpus.Chart.Utils as U
 
diff --git a/src/Gargantext/Pages/Corpus/Chart/Metrics.purs b/src/Gargantext/Pages/Corpus/Chart/Metrics.purs
index 978d2427..6a6d6847 100644
--- a/src/Gargantext/Pages/Corpus/Chart/Metrics.purs
+++ b/src/Gargantext/Pages/Corpus/Chart/Metrics.purs
@@ -12,13 +12,14 @@ import Reactix as R
 
 import Gargantext.Prelude
 import Gargantext.Types (TermList(..))
-import Gargantext.Components.Loader2 (useLoader)
+import Gargantext.Components.Loader as Loader
 import Gargantext.Components.Charts.Options.ECharts
 import Gargantext.Components.Charts.Options.Type
 import Gargantext.Components.Charts.Options.Series
 import Gargantext.Components.Charts.Options.Color
 import Gargantext.Components.Charts.Options.Font
 import Gargantext.Components.Charts.Options.Data
+import Gargantext.Hooks.Loader (useLoader)
 import Gargantext.Utils.Reactix as R2
 import Gargantext.Pages.Corpus.Chart.Utils as U
 
diff --git a/src/Gargantext/Pages/Corpus/Chart/Pie.purs b/src/Gargantext/Pages/Corpus/Chart/Pie.purs
index 182b3021..a18c68a1 100644
--- a/src/Gargantext/Pages/Corpus/Chart/Pie.purs
+++ b/src/Gargantext/Pages/Corpus/Chart/Pie.purs
@@ -13,12 +13,13 @@ import Reactix as R
 import Thermite (Spec)
 
 import Gargantext.Prelude
-import Gargantext.Components.Loader2 (useLoader)
+import Gargantext.Types (TermList(..))
 import Gargantext.Components.Charts.Options.ECharts
 import Gargantext.Components.Charts.Options.Series (seriesBarD1, seriesPieD1)
 import Gargantext.Components.Charts.Options.Color (blue)
 import Gargantext.Components.Charts.Options.Font
-import Gargantext.Components.Charts.Options.Data (dataSerie)
+import Gargantext.Components.Charts.Options.Data
+import Gargantext.Hooks.Loader (useLoader)
 import Gargantext.Utils.Reactix as R2
 import Gargantext.Pages.Corpus.Chart.Utils as U
 
diff --git a/src/Gargantext/Pages/Corpus/Chart/Tree.purs b/src/Gargantext/Pages/Corpus/Chart/Tree.purs
index 5140bce7..730d79f8 100644
--- a/src/Gargantext/Pages/Corpus/Chart/Tree.purs
+++ b/src/Gargantext/Pages/Corpus/Chart/Tree.purs
@@ -10,10 +10,12 @@ import Reactix.DOM.HTML as H
 import Thermite (Spec)
 
 import Gargantext.Prelude
-import Gargantext.Components.Loader2 (useLoader)
+import Gargantext.Types (TermList(..))
 import Gargantext.Components.Charts.Options.ECharts
 import Gargantext.Components.Charts.Options.Series
 import Gargantext.Components.Charts.Options.Font
+import Gargantext.Components.Charts.Options.Data
+import Gargantext.Hooks.Loader (useLoader)
 import Gargantext.Utils.Reactix as R2
 import Gargantext.Pages.Corpus.Chart.Utils as U
 
diff --git a/src/Gargantext/Pages/Corpus/Document.purs b/src/Gargantext/Pages/Corpus/Document.purs
index 83cb177e..82046953 100644
--- a/src/Gargantext/Pages/Corpus/Document.purs
+++ b/src/Gargantext/Pages/Corpus/Document.purs
@@ -15,10 +15,10 @@ import Gargantext.Prelude
 import Gargantext.Config          (toUrl, endConfigStateful, NodeType(..), End(..), TabSubType(..), TabType(..), CTabNgramType(..), CTabNgramType(..))
 import Gargantext.Config.REST     (get)
 import Gargantext.Components.AutoUpdate (autoUpdateElt)
-import Gargantext.Components.Loader2 (useLoader)
 import Gargantext.Components.Node (NodePoly(..))
 import Gargantext.Components.NgramsTable.Core
 import Gargantext.Components.Annotation.AnnotatedField as AnnotatedField
+import Gargantext.Hooks.Loader (useLoader)
 import Gargantext.Types (TermList)
 import Gargantext.Utils.Reactix as R2
 
diff --git a/src/Gargantext/Pages/Lists.purs b/src/Gargantext/Pages/Lists.purs
index 9e56df93..edd72349 100644
--- a/src/Gargantext/Pages/Lists.purs
+++ b/src/Gargantext/Pages/Lists.purs
@@ -9,12 +9,12 @@ import Thermite (Spec)
 --------------------------------------------------------
 import Gargantext.Prelude
 import Gargantext.Components.Node (NodePoly(..), HyperdataList)
-import Gargantext.Components.Loader2 (useLoader)
 import Gargantext.Components.Table as Table
 import Gargantext.Config      (toUrl, endConfigStateful, Path(..), NodeType(..), End(..))
 import Gargantext.Config.REST (get)
 import Gargantext.Pages.Lists.Tabs.Types (CorpusData, CorpusInfo(..))
 import Gargantext.Pages.Lists.Tabs.Specs (elt) as Tabs
+import Gargantext.Hooks.Loader (useLoader)
 import Gargantext.Utils.Reactix as R2
 
 ------------------------------------------------------------------------
diff --git a/src/Gargantext/Pages/Texts.purs b/src/Gargantext/Pages/Texts.purs
index 64a737c8..3c9f6232 100644
--- a/src/Gargantext/Pages/Texts.purs
+++ b/src/Gargantext/Pages/Texts.purs
@@ -9,12 +9,12 @@ import Thermite (Spec)
 --------------------------------------------------------
 import Gargantext.Prelude
 import Gargantext.Components.Node (NodePoly(..), HyperdataList)
-import Gargantext.Components.Loader2 (useLoader)
 import Gargantext.Components.Table as Table
 import Gargantext.Config      (toUrl, endConfigStateful, Path(..), NodeType(..), End(..))
 import Gargantext.Config.REST (get)
 import Gargantext.Pages.Texts.Tabs.Types (CorpusData, CorpusInfo(..))
 import Gargantext.Pages.Texts.Tabs.Specs (elt) as Tabs
+import Gargantext.Hooks.Loader (useLoader)
 import Gargantext.Utils.Reactix as R2
 
 ------------------------------------------------------------------------
-- 
2.21.0