Commit cb6b7381 authored by Justin Woo's avatar Justin Woo

fix localstorage hook not being able to synchronously get state

parent 06a87aa3
module Gargantext.Components.Forest where module Gargantext.Components.Forest where
import Gargantext.Prelude
import Data.Array as A import Data.Array as A
import Data.Maybe (Maybe(..)) import Data.Maybe (Maybe(..))
import Data.Set (Set)
import Data.Set as Set
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
import Gargantext.Components.Forest.Tree (treeView) import Gargantext.Components.Forest.Tree (treeView)
import Gargantext.Components.Login.Types (TreeId)
import Gargantext.Ends (Frontends) import Gargantext.Ends (Frontends)
import Gargantext.Routes (AppRoute) import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (Session(..), Sessions, unSessions) import Gargantext.Sessions (Session(..), Sessions, unSessions)
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
import Prelude (const, pure, ($), (<$>))
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
...@@ -24,13 +29,15 @@ forest props = R.createElement forestCpt props [] ...@@ -24,13 +29,15 @@ forest props = R.createElement forestCpt props []
forestCpt :: R.Component Props forestCpt :: R.Component Props
forestCpt = R.hooksComponent "G.C.Forest.forest" cpt where forestCpt = R.hooksComponent "G.C.Forest.forest" cpt where
cpt {frontends, route, sessions, showLogin } _ = R2.useCache (frontends /\ route /\ sessions) (cpt' showLogin) cpt {frontends, route, sessions, showLogin } _ = do
cpt' showLogin (frontends /\ route /\ sessions) = openNodes <- R2.useLocalStorageState R2.openNodesKey (Set.empty :: Set TreeId)
R2.useCache (frontends /\ route /\ sessions /\ fst openNodes) (cpt' openNodes showLogin)
cpt' openNodes showLogin (frontends /\ route /\ sessions /\ openNodesState) = do
pure $ R.fragment $ A.cons (plus showLogin) trees pure $ R.fragment $ A.cons (plus showLogin) trees
where where
trees = tree <$> unSessions sessions trees = tree <$> unSessions sessions
tree s@(Session {treeId}) = tree s@(Session {treeId}) =
treeView { root: treeId, frontends, mCurrentRoute: Just route, session: s } treeView { root: treeId, frontends, mCurrentRoute: Just route, session: s, openNodes }
plus :: R2.Setter Boolean -> R.Element plus :: R2.Setter Boolean -> R.Element
plus showLogin = plus showLogin =
......
...@@ -20,7 +20,6 @@ import Gargantext.Ends (Frontends) ...@@ -20,7 +20,6 @@ import Gargantext.Ends (Frontends)
import Gargantext.Routes (AppRoute) import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (Session) import Gargantext.Sessions (Session)
import Gargantext.Types (AsyncTask(..)) import Gargantext.Types (AsyncTask(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
...@@ -29,6 +28,7 @@ type Props = ( root :: ID ...@@ -29,6 +28,7 @@ type Props = ( root :: ID
, mCurrentRoute :: Maybe AppRoute , mCurrentRoute :: Maybe AppRoute
, session :: Session , session :: Session
, frontends :: Frontends , frontends :: Frontends
, openNodes :: R.State (Set TreeId)
) )
treeView :: Record Props -> R.Element treeView :: Record Props -> R.Element
...@@ -37,10 +37,9 @@ treeView props = R.createElement treeViewCpt props [] ...@@ -37,10 +37,9 @@ treeView props = R.createElement treeViewCpt props []
treeViewCpt :: R.Component Props treeViewCpt :: R.Component Props
treeViewCpt = R.hooksComponent "G.C.Tree.treeView" cpt treeViewCpt = R.hooksComponent "G.C.Tree.treeView" cpt
where where
cpt { root, mCurrentRoute, session, frontends } _children = do cpt { root, mCurrentRoute, session, frontends, openNodes } _children = do
-- NOTE: this is a hack to reload the tree view on demand -- NOTE: this is a hack to reload the tree view on demand
reload <- R.useState' (0 :: Reload) reload <- R.useState' (0 :: Reload)
openNodes <- R2.useLocalStorageState R2.openNodesKey (Set.empty :: Set TreeId)
pure $ treeLoadView pure $ treeLoadView
{ root, mCurrentRoute, session, frontends, openNodes, reload } { root, mCurrentRoute, session, frontends, openNodes, reload }
......
...@@ -12,9 +12,8 @@ import Data.Argonaut as Argonaut ...@@ -12,9 +12,8 @@ import Data.Argonaut as Argonaut
import Data.Argonaut as Json import Data.Argonaut as Json
import Data.Argonaut.Core (Json) import Data.Argonaut.Core (Json)
import Data.Either (hush) import Data.Either (hush)
import Data.Foldable (for_)
import Data.Function.Uncurried (Fn2, runFn2) import Data.Function.Uncurried (Fn2, runFn2)
import Data.Maybe (Maybe(..), fromJust) import Data.Maybe (Maybe(..), fromJust, fromMaybe)
import Data.Nullable (Nullable, null, toMaybe) import Data.Nullable (Nullable, null, toMaybe)
import Data.Tuple (Tuple(..)) import Data.Tuple (Tuple(..))
import Data.Tuple.Nested ((/\)) import Data.Tuple.Nested ((/\))
...@@ -23,6 +22,7 @@ import Effect.Aff (Aff, launchAff, launchAff_, killFiber) ...@@ -23,6 +22,7 @@ import Effect.Aff (Aff, launchAff, launchAff_, killFiber)
import Effect.Class (liftEffect) import Effect.Class (liftEffect)
import Effect.Exception (error) import Effect.Exception (error)
import Effect.Uncurried (EffectFn1, mkEffectFn1, mkEffectFn2, runEffectFn1) import Effect.Uncurried (EffectFn1, mkEffectFn1, mkEffectFn2, runEffectFn1)
import Effect.Unsafe (unsafePerformEffect)
import FFI.Simple ((..), (...), defineProperty, delay, args2, args3) import FFI.Simple ((..), (...), defineProperty, delay, args2, args3)
import Partial.Unsafe (unsafePartial) import Partial.Unsafe (unsafePartial)
import React (class ReactPropFields, Children, ReactClass, ReactElement) import React (class ReactPropFields, Children, ReactClass, ReactElement)
...@@ -267,25 +267,17 @@ type LocalStorageKey = String ...@@ -267,25 +267,17 @@ type LocalStorageKey = String
useLocalStorageState :: forall s. Argonaut.DecodeJson s => Argonaut.EncodeJson s => LocalStorageKey -> s -> R.Hooks (R.State s) useLocalStorageState :: forall s. Argonaut.DecodeJson s => Argonaut.EncodeJson s => LocalStorageKey -> s -> R.Hooks (R.State s)
useLocalStorageState key s = do useLocalStorageState key s = do
ref <- R.useRef s -- we need to synchronously get the initial state from local storage
Tuple state setState' <- R.useState \_ -> unsafePerformEffect do
R.useEffectOnce' do
item :: Maybe String <- getItem key =<< getls item :: Maybe String <- getItem key =<< getls
let json = hush <<< Argonaut.jsonParser =<< item let json = hush <<< Argonaut.jsonParser =<< item
let parsed = hush <<< Argonaut.decodeJson =<< json let parsed = hush <<< Argonaut.decodeJson =<< json
for_ parsed \(x :: s) -> R.setRef ref x pure $ fromMaybe s parsed
let init = R.readRef ref
Tuple state setState' <- R.useState' init
let let
setState update = do setState update = do
let new = update (R.readRef ref) let new = update state
setState' (\_ -> new) setState' (\_ -> new)
R.setRef ref new
let json = Json.stringify $ Argonaut.encodeJson new let json = Json.stringify $ Argonaut.encodeJson new
storage <- getls storage <- getls
setItem key json storage setItem key json storage
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment