diff --git a/src/Gargantext/Components/App.purs b/src/Gargantext/Components/App.purs index 5fee8d67c418793cd2b8cd0d68860d02a66bee6c..77f463822ca29715b06b878a932ea08a9cba4913 100644 --- a/src/Gargantext/Components/App.purs +++ b/src/Gargantext/Components/App.purs @@ -31,5 +31,8 @@ appCpt = here.component "app" cpt where tasksReductor <- GAT.useTasks boxes.reloadRoot boxes.reloadForest R.useEffectOnce' $ do T.write (Just tasksReductor) tasks + R.useEffectOnce' $ do + R2.loadLocalStorageState R2.openNodesKey boxes.forestOpen + T.listen (R2.listenLocalStorageState R2.openNodesKey) boxes.forestOpen useHashRouter Router.router boxes.route -- Install router to window pure $ router { boxes, tasks } -- Render router component diff --git a/src/Gargantext/Components/Forest.purs b/src/Gargantext/Components/Forest.purs index bef82ff7b3991a7a137bfb8ba40b544a23aa7d71..8c6d91e71d57ef21026aa89be56926fc6e903f10 100644 --- a/src/Gargantext/Components/Forest.purs +++ b/src/Gargantext/Components/Forest.purs @@ -5,7 +5,7 @@ module Gargantext.Components.Forest , forestLayoutMain , forestLayoutRaw , Common - , LayoutProps + , Props ) where import Data.Array as A @@ -41,18 +41,15 @@ type Common = , tasks :: T.Box (Maybe GAT.Reductor) ) -type LayoutProps = +type Props = ( backend :: T.Box (Maybe Backend) + , forestOpen :: T.Box OpenNodes , reloadForest :: T.Box T2.Reload , sessions :: T.Box Sessions , showLogin :: T.Box Boolean | Common ) -type Props = ( - forestOpen :: T.Box OpenNodes - | LayoutProps ) - type TreeExtra = ( forestOpen :: T.Box OpenNodes , session :: Session @@ -129,10 +126,10 @@ plus handed showLogin backend = H.div { className: "row" } "btn btn-primary col-5 " <> switchHanded "ml-1 mr-auto" "mr-1 ml-auto" handed -forestLayout :: R2.Component LayoutProps +forestLayout :: R2.Component Props forestLayout = R.createElement forestLayoutCpt -forestLayoutCpt :: R.Component LayoutProps +forestLayoutCpt :: R.Component Props forestLayoutCpt = here.component "forestLayout" cpt where cpt props@{ handed } children = pure $ R.fragment @@ -141,10 +138,10 @@ forestLayoutCpt = here.component "forestLayout" cpt where -- Renders its first child component in the top bar and the rest in -- the main view. -forestLayoutWithTopBar :: R2.Component LayoutProps +forestLayoutWithTopBar :: R2.Component Props forestLayoutWithTopBar = R.createElement forestLayoutWithTopBarCpt -forestLayoutWithTopBarCpt :: R.Component LayoutProps +forestLayoutWithTopBarCpt :: R.Component Props forestLayoutWithTopBarCpt = here.component "forestLayoutWithTopBar" cpt where cpt props@{ handed } children = do let { head: topBarChild, tail: mainChildren } = @@ -153,19 +150,20 @@ forestLayoutWithTopBarCpt = here.component "forestLayoutWithTopBar" cpt where [ topBar { handed } [ topBarChild ] , forestLayoutMain props mainChildren ] -forestLayoutMain :: R2.Component LayoutProps +forestLayoutMain :: R2.Component Props forestLayoutMain = R.createElement forestLayoutMainCpt -forestLayoutMainCpt :: R.Component LayoutProps +forestLayoutMainCpt :: R.Component Props forestLayoutMainCpt = here.component "forestLayoutMain" cpt where cpt props children = pure $ forestLayoutRaw props [ mainPage {} children ] -forestLayoutRaw :: R2.Component LayoutProps +forestLayoutRaw :: R2.Component Props forestLayoutRaw = R.createElement forestLayoutRawCpt -forestLayoutRawCpt :: R.Component LayoutProps +forestLayoutRawCpt :: R.Component Props forestLayoutRawCpt = here.component "forestLayoutRaw" cpt where cpt p@{ backend + , forestOpen , frontends , reloadForest , reloadRoot @@ -174,15 +172,14 @@ forestLayoutRawCpt = here.component "forestLayoutRaw" cpt where , showLogin , tasks } children = do handed' <- T.useLive T.unequal p.handed - forestOpen <- T.useBox $ Set.empty pure $ R2.row $ reverseHanded ([ H.div { className: "col-md-2 forest-layout-raw-tree" } - [ forest' p.handed forestOpen ] + [ forest' p.handed ] ] <> children ) handed' where - forest' handed forestOpen = + forest' handed = forest { backend , frontends , forestOpen diff --git a/src/Gargantext/Components/Nodes/Lists.purs b/src/Gargantext/Components/Nodes/Lists.purs index 919088b70335bf452f9ad73e031385f9bb59ff70..57854ea57fc3dbda5692d77ed7df2217a7070879 100644 --- a/src/Gargantext/Components/Nodes/Lists.purs +++ b/src/Gargantext/Components/Nodes/Lists.purs @@ -34,7 +34,7 @@ here :: R2.Here here = R2.here "Gargantext.Components.Nodes.Lists" type ListsWithForest = - ( forestProps :: Record Forest.LayoutProps + ( forestProps :: Record Forest.Props , listsProps :: Record CommonProps ) diff --git a/src/Gargantext/Components/Nodes/Texts.purs b/src/Gargantext/Components/Nodes/Texts.purs index 5f846ef61654b696c63e27ff8eb5a56d984a7c34..954ea563bc99054ee80a6568c2dcf991e2e2ebd4 100644 --- a/src/Gargantext/Components/Nodes/Texts.purs +++ b/src/Gargantext/Components/Nodes/Texts.purs @@ -41,7 +41,7 @@ here = R2.here "Gargantext.Components.Nodes.Texts" -------------------------------------------------------- type TextsWithForest = ( - forestProps :: Record Forest.LayoutProps + forestProps :: Record Forest.Props , textsProps :: Record CommonProps ) diff --git a/src/Gargantext/Components/Router.purs b/src/Gargantext/Components/Router.purs index 833ec7b639171e262b2c09b0a9225e58caf5771b..7bb0fad31beb327b987ecc799878cfa866d2058e 100644 --- a/src/Gargantext/Components/Router.purs +++ b/src/Gargantext/Components/Router.purs @@ -92,8 +92,16 @@ forested = R.createElement forestedCpt forestedCpt :: R.Component Props forestedCpt = here.component "forested" cpt where - cpt { boxes: { backend, handed, reloadForest, reloadRoot, route, sessions, showLogin }, tasks } children = do + cpt { boxes: { backend + , forestOpen + , handed + , reloadForest + , reloadRoot + , route + , sessions + , showLogin }, tasks } children = do pure $ forestLayout { backend + , forestOpen , frontends: defaultFrontends , handed , reloadForest @@ -189,12 +197,13 @@ lists = R.createElement listsCpt listsCpt :: R.Component SessionNodeProps listsCpt = here.component "lists" cpt where cpt props@{ boxes: { backend - , handed - , reloadForest - , reloadRoot - , route - , sessions - , showLogin } + , forestOpen + , handed + , reloadForest + , reloadRoot + , route + , sessions + , showLogin } , nodeId , session , sessionId @@ -204,6 +213,7 @@ listsCpt = here.component "lists" cpt where pure $ authed sessionProps $ Lists.listsWithForest { forestProps: { backend + , forestOpen , frontends , handed , reloadForest @@ -291,12 +301,13 @@ textsCpt :: R.Component SessionNodeProps textsCpt = here.component "texts" cpt where cpt props@{ boxes: { backend - , handed - , reloadForest - , reloadRoot - , route - , sessions - , showLogin } + , forestOpen + , handed + , reloadForest + , reloadRoot + , route + , sessions + , showLogin } , nodeId , session , sessionId @@ -306,6 +317,7 @@ textsCpt = here.component "texts" cpt pure $ authed sessionProps $ Texts.textsWithForest { forestProps: { backend + , forestOpen , frontends , handed , route diff --git a/src/Gargantext/Utils/Reactix.purs b/src/Gargantext/Utils/Reactix.purs index 0d12bef0df3e571123f701c76f4c23b3087468b2..0fb2a8a727b9dc44af51782383060341e8a72284 100644 --- a/src/Gargantext/Utils/Reactix.purs +++ b/src/Gargantext/Utils/Reactix.purs @@ -35,6 +35,7 @@ import Reactix.DOM.HTML as H import Reactix.React (react) import Reactix.SyntheticEvent as RE import Reactix.Utils (currySecond, hook, tuple) +import Toestand as T import Unsafe.Coerce (unsafeCoerce) import Web.File.Blob (Blob) import Web.File.File as WF @@ -327,24 +328,21 @@ openNodesKey = "garg-open-nodes" type LocalStorageKey = String -useLocalStorageState :: forall s. Argonaut.DecodeJson s => Argonaut.EncodeJson s => LocalStorageKey -> s -> R.Hooks (R.State s) -useLocalStorageState key s = 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 - pure $ fromMaybe s parsed - - let - setState update = do - let new = update state - setState' (\_ -> new) - let json = Json.stringify $ Argonaut.encodeJson new - storage <- getls - setItem key json storage - - pure (Tuple state setState) +loadLocalStorageState :: forall s. Argonaut.DecodeJson s => LocalStorageKey -> T.Box s -> Effect Unit +loadLocalStorageState key cell = do + storage <- getls + item :: Maybe String <- getItem key storage + let json = hush <<< Argonaut.jsonParser =<< item + let parsed = hush <<< Argonaut.decodeJson =<< json + case parsed of + Nothing -> pure unit + Just p -> void $ T.write p cell + +listenLocalStorageState :: forall s. Argonaut.EncodeJson s => LocalStorageKey -> T.Change s -> Effect Unit +listenLocalStorageState key { old, new } = do + let json = Json.stringify $ Argonaut.encodeJson new + storage <- getls + setItem key json storage getMessageDataStr :: DE.MessageEvent -> String getMessageDataStr = getMessageData