diff --git a/src/App/WS.purs b/src/App/WS.purs index f6ca879..0ca53b8 100644 --- a/src/App/WS.purs +++ b/src/App/WS.purs @@ -1,7 +1,7 @@ +-- | This component handles all WS operations. +-- | This includes telling when a connection is established or closed, and notify a message has been received. module App.WS where -{- This component handles all WS operations. -} - import Prelude (Unit, bind, discard, pure, show, void, when, ($), (&&), (<$>), (<>), (>>=), (>=>), (<<<), map) import Control.Monad.Except (runExcept) @@ -30,38 +30,53 @@ import Web.Socket.WebSocket as WS import App.LogMessage - -- Input is the WS url. type Input = String --- MessageReceived (Tuple URL message) +-- | The component can perform 4 actions: log messages, notify that a message has been received, +-- | notify when a connection has been established or when it has been closed. data Output +-- | MessageReceived (Tuple URL message) = MessageReceived (Tuple String ArrayBuffer) -- Provide a received message to the parent. | WSJustConnected -- Inform the parent the connection is up. | WSJustClosed -- Inform the parent the connection is down. | Log LogMessage +-- | The component can receive a single action from other components: sending a message throught the websocket. +data Query a = ToSend ArrayBuffer a + type Slot = H.Slot Query Output -data Query a - = ToSend ArrayBuffer a - data Action + -- | `Initialize` opens the connection (URL is received as an `input` of this component). = Initialize + + -- | The component provides a log each time a message failed to be parsed. | WebSocketParseError String + + -- | The component shows buttons when the connection is dropped for some reason. + -- | To reconnect, the button is clicked, and the `ConnectWebSocket` action is performed. | ConnectWebSocket + -- | `SendMessage` effectively sends a message through the ws connection. | SendMessage ArrayBuffer + -- | `Finalize` is the action performed once the component is destroyed, ending the connection. | Finalize + + -- | Every received websocket message and notification is handled in `HandleWebSocket`. | HandleWebSocket (WebSocketEvent WebSocketMessageType) +-- | The type `WSInfo` helps handle a websocket. +-- | `WSInfo` is composed of an URL, an actual socket and a boolean +-- | to inform if the connection has to be re-established. type WSInfo = { url :: String , connection :: Maybe WS.WebSocket , reconnect :: Boolean } +-- | The state of this component only is composed of the websocket. type State = { wsInfo :: WSInfo } component :: forall m. MonadAff m => H.Component Query Input Output m @@ -85,6 +100,7 @@ initialState url = } } +-- | The component shows a string when the connection is established, or a button when the connection has closed. render :: forall m. State -> H.ComponentHTML Action () m render { wsInfo } = HH.div_ @@ -149,11 +165,9 @@ handleAction action = do HandleWebSocket wsEvent -> do case wsEvent of WebSocketMessage received_message -> do - -- H.raise $ Log $ SimpleLog $ "[😈] Received a message" H.raise $ MessageReceived $ Tuple wsInfo.url received_message.message WebSocketOpen -> do - -- H.raise $ Log $ SystemLog ("Successfully connected to \"" <> wsInfo.url <> "\"!🎉") H.raise $ WSJustConnected WebSocketClose { code, reason, wasClean } -> do @@ -163,9 +177,9 @@ handleAction action = do H.modify_ _ { wsInfo { connection = Nothing, reconnect = true } } H.raise $ WSJustClosed - WebSocketError errorType -> + WebSocketError errorType -> do H.raise $ Log $ SystemLog $ renderError errorType - -- TODO: MAYBE inform the parent the connection is closed (if it's the case). + H.raise $ WSJustClosed where renderCloseMessage