diff --git a/src/App/Container.purs b/src/App/Container.purs index 133a1cf..3f82b60 100644 --- a/src/App/Container.purs +++ b/src/App/Container.purs @@ -166,6 +166,10 @@ handleAction = case _ of DomainListInterface.MessageToSend message -> H.tell _ws_dns unit (WS.ToSend message) DomainListInterface.Log message -> H.tell _log unit (Log.Log message) DomainListInterface.DNSManagerReconnect -> handleAction AuthenticateToDNSManager + DomainListInterface.StoreState s -> H.modify_ _ { store_DomainListInterface_state = Just s } + DomainListInterface.AskState -> do + state <- H.get + H.tell _dli unit (DomainListInterface.ProvideState state.store_DomainListInterface_state) -- TODO: depending on the current page, we should provide the received message to different components. AuthenticationDaemonEvent ev -> case ev of diff --git a/src/App/DomainListInterface.purs b/src/App/DomainListInterface.purs index 8e2c2e7..010d520 100644 --- a/src/App/DomainListInterface.purs +++ b/src/App/DomainListInterface.purs @@ -1,5 +1,3 @@ -module App.DomainListInterface where - -- | `App.DomainListInterface` is a simple component with the list of own domains -- | and a form to add a new domain. -- | @@ -11,6 +9,8 @@ module App.DomainListInterface where -- | - TODO: ask for confirmation -- | - TODO: switch to the interface to show and modify the content of a Zone +module App.DomainListInterface where + import Prelude (Unit, bind, discard, map, otherwise, pure, ($), (/=), (<<<), (<>)) import CSSClasses as CSSClasses @@ -37,20 +37,33 @@ import App.Messages.DNSManagerDaemon as DNSManager -- | -- | Also, this component can log messages and ask its parent (`App.Container`) to -- | reconnect the websocket to `dnsmanagerd`. +-- | +-- | Finally, the component can ask its state to its parent. +-- | The reason is quite simple. +-- | The component can be deleted, meaning that it loses its state. +-- | Instead of asking `dnsmanagerd` the list of available domains and the list of owned domains +-- | each time the component is instanciated, the parent stores the component's state when the +-- | component is removed. This way, the data is conserved. data Output = MessageToSend ArrayBuffer | Log LogMessage | DNSManagerReconnect + | AskState + | StoreState State -- | `App.DomainListInterface` can receive messages from `dnsmanagerd`. -- | -- | The component is also informed when the connection is lost or up again. +-- | +-- | Finally, its entire state can be provided by its parent. +-- | See the explanation for the `Output` data type. data Query a = MessageReceived ArrayBuffer a | ConnectionIsDown a | ConnectionIsUp a + | ProvideState (Maybe State) a type Slot = H.Slot Query Output @@ -83,6 +96,9 @@ data Action | RemoveDomain String | EnterDomain String + | Initialize + | Finalize + -- | The form only has two elements: -- | the subdomain name input and the selected TLD. @@ -108,8 +124,10 @@ component = { initialState , render , eval: H.mkEval $ H.defaultEval - { handleAction = handleAction + { initialize = Just Initialize + , handleAction = handleAction , handleQuery = handleQuery + , finalize = Just Finalize } } @@ -177,6 +195,13 @@ render { accepted_domains, my_domains, newDomainForm, wsUp } handleAction :: forall m. MonadAff m => Action -> H.HalogenM State Action () Output m Unit handleAction = case _ of + Initialize -> do + H.raise $ AskState + + Finalize -> do + state <- H.get + H.raise $ StoreState state + UpdateAcceptedDomains domains -> do H.modify_ _ { accepted_domains = domains } @@ -216,6 +241,13 @@ handleAction = case _ of handleQuery :: forall a m. MonadAff m => Query a -> H.HalogenM State Action () Output m (Maybe a) handleQuery = case _ of + ProvideState maybe_state a -> do + case maybe_state of + Nothing -> pure Nothing + Just s -> do + H.put s + pure (Just a) + MessageReceived message a -> do receivedMessage <- H.liftEffect $ DNSManager.deserialize message case receivedMessage of