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
import Gargantext.Prelude
import Data.Array as A
import Data.Maybe (Maybe(..))
import Data.Set (Set)
import Data.Set as Set
import Data.Tuple (fst)
import Data.Tuple.Nested ((/\))
import Gargantext.Components.Forest.Tree (treeView)
import Gargantext.Components.Login.Types (TreeId)
import Gargantext.Ends (Frontends)
import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (Session(..), Sessions, unSessions)
import Gargantext.Utils.Reactix as R2
import Prelude (const, pure, ($), (<$>))
import Reactix as R
import Reactix.DOM.HTML as H
......@@ -24,13 +29,15 @@ forest props = R.createElement forestCpt props []
forestCpt :: R.Component Props
forestCpt = R.hooksComponent "G.C.Forest.forest" cpt where
cpt {frontends, route, sessions, showLogin } _ = R2.useCache (frontends /\ route /\ sessions) (cpt' showLogin)
cpt' showLogin (frontends /\ route /\ sessions) =
cpt {frontends, route, sessions, showLogin } _ = do
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
where
trees = tree <$> unSessions sessions
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 showLogin =
......
......@@ -20,7 +20,6 @@ import Gargantext.Ends (Frontends)
import Gargantext.Routes (AppRoute)
import Gargantext.Sessions (Session)
import Gargantext.Types (AsyncTask(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
......@@ -29,6 +28,7 @@ type Props = ( root :: ID
, mCurrentRoute :: Maybe AppRoute
, session :: Session
, frontends :: Frontends
, openNodes :: R.State (Set TreeId)
)
treeView :: Record Props -> R.Element
......@@ -37,10 +37,9 @@ treeView props = R.createElement treeViewCpt props []
treeViewCpt :: R.Component Props
treeViewCpt = R.hooksComponent "G.C.Tree.treeView" cpt
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
reload <- R.useState' (0 :: Reload)
openNodes <- R2.useLocalStorageState R2.openNodesKey (Set.empty :: Set TreeId)
pure $ treeLoadView
{ root, mCurrentRoute, session, frontends, openNodes, reload }
......
......@@ -12,9 +12,8 @@ import Data.Argonaut as Argonaut
import Data.Argonaut as Json
import Data.Argonaut.Core (Json)
import Data.Either (hush)
import Data.Foldable (for_)
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.Tuple (Tuple(..))
import Data.Tuple.Nested ((/\))
......@@ -23,6 +22,7 @@ import Effect.Aff (Aff, launchAff, launchAff_, killFiber)
import Effect.Class (liftEffect)
import Effect.Exception (error)
import Effect.Uncurried (EffectFn1, mkEffectFn1, mkEffectFn2, runEffectFn1)
import Effect.Unsafe (unsafePerformEffect)
import FFI.Simple ((..), (...), defineProperty, delay, args2, args3)
import Partial.Unsafe (unsafePartial)
import React (class ReactPropFields, Children, ReactClass, ReactElement)
......@@ -267,25 +267,17 @@ type LocalStorageKey = String
useLocalStorageState :: forall s. Argonaut.DecodeJson s => Argonaut.EncodeJson s => LocalStorageKey -> s -> R.Hooks (R.State s)
useLocalStorageState key s = do
ref <- R.useRef s
R.useEffectOnce' do
-- we need to synchronously get the initial state from local storage
Tuple state setState' <- R.useState \_ -> unsafePerformEffect do
item :: Maybe String <- getItem key =<< getls
let json = hush <<< Argonaut.jsonParser =<< item
let parsed = hush <<< Argonaut.decodeJson =<< json
for_ parsed \(x :: s) -> R.setRef ref x
let init = R.readRef ref
Tuple state setState' <- R.useState' init
pure $ fromMaybe s parsed
let
setState update = do
let new = update (R.readRef ref)
let new = update state
setState' (\_ -> new)
R.setRef ref new
let json = Json.stringify $ Argonaut.encodeJson new
storage <- getls
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