{-# LANGUAGE UndecidableInstances #-} module IHP.ServerSideComponent.Controller.ComponentsController where import IHP.ControllerPrelude import IHP.ServerSideComponent.Types as SSC import IHP.ServerSideComponent.ControllerFunctions as SSC import qualified Data.Aeson as Aeson import qualified Text.Blaze.Html.Renderer.Text as Blaze instance (Component component controller, FromJSON controller) => WSApp (ComponentsController component) where initialState :: ComponentsController component initialState = forall {k} (components :: k). ComponentsController components ComponentsController run :: (?state::IORef (ComponentsController component), ?context::ControllerContext, ?applicationContext::ApplicationContext, ?modelContext::ModelContext, ?connection::Connection) => IO () run = do let component state :: component = forall state action. Component state action => state SSC.initialState IORef (ComponentInstance component) instanceRef <- forall a. a -> IO (IORef a) newIORef (ComponentInstance { component $sel:state:ComponentInstance :: component state :: component state }) let ?instanceRef = IORef (ComponentInstance component) instanceRef component nextState <- forall state action. (Component state action, ?instanceRef::IORef (ComponentInstance state), ?connection::Connection, ?context::ControllerContext, ?modelContext::ModelContext) => state -> IO state componentDidMount component state forall state action. (?instanceRef::IORef (ComponentInstance state), ?connection::Connection, Component state action, ?context::ControllerContext) => state -> IO () SSC.setState component nextState forall (f :: * -> *) a b. Applicative f => f a -> f b forever do LByteString actionPayload :: LByteString <- forall a. (?connection::Connection, WebSocketsData a) => IO a receiveData let theAction :: Either String controller theAction = forall a. FromJSON a => LByteString -> Either String a Aeson.eitherDecode @controller LByteString actionPayload case Either String controller theAction of Right controller theAction -> do component currentState <- forall {a} {b}. (HasField "state" a b, ?instanceRef::IORef a) => IO b SSC.getState component nextState <- forall state action. (Component state action, ?instanceRef::IORef (ComponentInstance state), ?connection::Connection, ?context::ControllerContext, ?modelContext::ModelContext) => state -> action -> IO state SSC.action component currentState controller theAction forall state action. (?instanceRef::IORef (ComponentInstance state), ?connection::Connection, Component state action, ?context::ControllerContext) => state -> IO () SSC.setState component nextState Left String error -> Text -> IO () putStrLn (forall a b. ConvertibleStrings a b => a -> b cs String error)