thock-0.2.0.0: src/Client.hs
-- | This module allows a client to connect to and interact with the websocket server.
module Client
( runClient,
)
where
import Brick (customMain)
import Brick.BChan (newBChan, writeBChan)
import Control.Concurrent (forkFinally)
import Control.Monad (forever)
import qualified Data.Text as T
import qualified Graphics.Vty as V
import Network.Socket (withSocketsDo)
import qualified Network.WebSockets as WS
import Online
( ConnectionTick (ConnectionTick),
Online (WaitingRoom),
RoomClientState (RoomClientState),
WaitingRoomState (WaitingRoomState),
receiveJsonData,
sendJsonData,
)
import Thock (RoomFormData (RoomFormData), Username (Username))
import UI.Online (onlineApp)
-- | Sets up the initial state of the 'Online' state using the formData
-- based on if the player is creating the room.
createClientApp :: Bool -> RoomFormData -> WS.ClientApp (Maybe T.Text)
createClientApp isCreating formData@(RoomFormData (Username user) room) conn = do
_ <- sendJsonData conn (formData, isCreating)
if isCreating
then startRoom []
else do
res <- receiveJsonData conn
case res of
Right others -> startRoom others
Left msg -> return (Just msg) -- Stop connection due to error message received from server
where
localSt = RoomClientState user False
startRoom others = do
connChan <- newBChan 10
-- fork a thread that writes custom events when received from server
_ <-
forkFinally
( forever $ do
serverMessage <- receiveJsonData conn
writeBChan connChan (ConnectionTick serverMessage)
)
(const $ return ()) -- terminate when connection is closed and ignore any exceptions
let buildVty = V.mkVty V.defaultConfig
initialVty <- buildVty
let w = WaitingRoom (WaitingRoomState room localSt conn others)
_ <- customMain initialVty buildVty (Just connChan) onlineApp w
WS.sendClose conn ("Bye!" :: T.Text)
return Nothing -- Online connection finished successfully with no errors
-- | Connects to the websocket server and runs the client app
runClient :: Bool -> RoomFormData -> IO (Maybe T.Text)
runClient isCreating formData =
withSocketsDo $
WS.runClient "thock-server.herokuapp.com" 80 "/" (createClientApp isCreating formData)