module Web.Front where

import           Data.Text                 (Text)

import           Bridge
import           Text.Blaze.Front
import           Text.Blaze.Front.Renderer

import qualified Data.Text                 as T

data ClientTaskType = OnlyHtml | OnlyEvents | BothHtmlEvents | None
  deriving (ClientTaskType -> ClientTaskType -> Bool
(ClientTaskType -> ClientTaskType -> Bool)
-> (ClientTaskType -> ClientTaskType -> Bool) -> Eq ClientTaskType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ClientTaskType -> ClientTaskType -> Bool
$c/= :: ClientTaskType -> ClientTaskType -> Bool
== :: ClientTaskType -> ClientTaskType -> Bool
$c== :: ClientTaskType -> ClientTaskType -> Bool
Eq, Int -> ClientTaskType -> ShowS
[ClientTaskType] -> ShowS
ClientTaskType -> String
(Int -> ClientTaskType -> ShowS)
-> (ClientTaskType -> String)
-> ([ClientTaskType] -> ShowS)
-> Show ClientTaskType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ClientTaskType] -> ShowS
$cshowList :: [ClientTaskType] -> ShowS
show :: ClientTaskType -> String
$cshow :: ClientTaskType -> String
showsPrec :: Int -> ClientTaskType -> ShowS
$cshowsPrec :: Int -> ClientTaskType -> ShowS
Show)

-- | Generate message that will be pushed to client(s) based on underlying communication.
createTask
  :: Show a
  => Text -- ^ DOM Element Id.
  -> ClientTaskType -- ^ Type of task to execute on client.
  -> (t -> Markup a) -- ^ How to render state.
  -> t -- ^ State to render.
  -> ClientTask a -- ^ Message that will be pushed to client(s).
createTask :: Text -> ClientTaskType -> (t -> Markup a) -> t -> ClientTask a
createTask eid :: Text
eid taskType :: ClientTaskType
taskType renderer :: t -> Markup a
renderer state :: t
state = ClientTask a
task
  where rhtml :: RenderHtml
rhtml = Text -> Text -> RenderHtml
AttachText Text
eid (String -> Text
T.pack (String -> Text) -> (Markup a -> String) -> Markup a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Markup a -> String
forall act. Show act => Markup act -> String
renderHtml (Markup a -> Text) -> Markup a -> Text
forall a b. (a -> b) -> a -> b
$ Markup a
markup)
        markup :: Markup a
markup = t -> Markup a
renderer t
state
        (html :: [RenderHtml]
html, events :: Markup a
events) = case ClientTaskType
taskType of
          OnlyHtml       -> ([RenderHtml
rhtml], Markup a
forall a. Monoid a => a
mempty)
          OnlyEvents     -> ([], Markup a
markup)
          BothHtmlEvents -> ([RenderHtml
rhtml], Markup a
markup)
          None           -> ([], Markup a
forall a. Monoid a => a
mempty)
        task :: ClientTask a
task = ClientTask :: forall a.
[RenderHtml] -> [CallbackAction a] -> [Text] -> ClientTask a
ClientTask
          { executeRenderHtml :: [RenderHtml]
executeRenderHtml = [RenderHtml]
html
          , executeAction :: [CallbackAction a]
executeAction = Markup a -> [CallbackAction a] -> [CallbackAction a]
forall a. Markup a -> [CallbackAction a] -> [CallbackAction a]
registerEvents Markup a
events []
          , executeScript :: [Text]
executeScript = []
          }

emptyTask :: ClientTask a
emptyTask :: ClientTask a
emptyTask = ClientTask :: forall a.
[RenderHtml] -> [CallbackAction a] -> [Text] -> ClientTask a
ClientTask { executeRenderHtml :: [RenderHtml]
executeRenderHtml = [], executeAction :: [CallbackAction a]
executeAction = [], executeScript :: [Text]
executeScript = [] }