module Gargantext.Utils.Toestand ( class Reloadable, reload, Reload, ReloadS, newReload, InitReload(..), ready, useMemberBox ) where import Prelude (class Ord, Unit, bind, pure, unit, (+)) import Data.Set as Set import Data.Set (Set) import Effect (Effect) import Reactix as R import Toestand as T -- | Reload is a simple counter that can be used to force an update. type Reload = Int type ReloadS = T.Box Reload class Reloadable t where reload :: t -> Effect Unit -- | An empty Reload is zero as it has not yet been reloaded. newReload :: Reload newReload = 0 instance Reloadable (T.Box Int) where reload box = T.modify_ (_ + 1) box instance Reloadable (c Reload) => Reloadable (T.Box (InitReload c)) where reload box = do val <- T.read box case val of Init -> pure unit Ready r -> reload r -- inner is a Box wrapping a Reload data InitReload (inner :: Type -> Type) = Init | Ready (inner Reload) -- | Initialises an InitReload box with the Reload box it contains, -- | if it has not already been initialised. ready :: forall box c. T.ReadWrite box (InitReload c) => T.ReadWrite (c Reload) Reload => box -> (c Reload) -> Effect Unit ready box with = do val <- T.read box case val of Init -> T.write_ (Ready with) box Ready _ -> pure unit -- | Creates a cursor which presents a Boolean over whether the member -- | is in the set. Adjusting the value will toggle whether the value -- | is in the underlying set. useMemberBox :: forall box v. Ord v => T.ReadWrite box (Set v) => v -> box -> R.Hooks (T.Box Boolean) useMemberBox val box = T.useFocused (Set.member val) (toggleSet val) box -- utility for useMemberBox toggleSet :: forall s. Ord s => s -> Boolean -> Set s -> Set s toggleSet val true set = Set.insert val set toggleSet val false set = Set.delete val set