{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
-----------------------------------------------------------------------------
-- |
-- Module : MisoActionLogger
-- Copyright : (C) 2019 Sviat Chumakov
-- License : BSD3-style (see the file LICENSE)
-- Maintainer : Sviat Chumakov <svchumakov@gmail.com>
-- Stability : experimental
-- Portability : non-portable
----------------------------------------------------------------------------
module MisoActionLogger
( mkActionLogger
, defaultActionLogger
, defaultGroupFormat
, defaultStateFormat
, defaultActionFormat
, ActionLoggerOptions
) where
import Data.Aeson
import Miso (Effect(..))
import Miso.String hiding (head, words)
import GHCJS.Types
import GHCJS.Marshal
import GHCJS.Marshal.Pure
import MisoActionLogger.FFI
-- | Configuration for mkActionLogger.
data ActionLoggerOptions action model = ActionLoggerOptions
{ groupFormat :: action -> IO JSVal
-- ^ Function to format the log group title
, previousStateFormat :: model -> IO JSVal
-- ^ Function to format the previous state
, actionFormat :: action -> IO JSVal
-- ^ Function to format the action
, nextStateFormat :: model -> IO JSVal
-- ^ Function to format the next state
}
-- | Create an action logger with custom settings.
-- Returns a logger that wraps around your 'update' function when you construct a Miso app.
mkActionLogger
:: (Show action, ToJSON model)
=> ActionLoggerOptions action model
-> (action -> model -> Effect action model)
-> action -> model -> Effect action model
mkActionLogger ActionLoggerOptions{..} update action oldModel = Effect newModel (logSub : subs)
where
Effect newModel subs = update action oldModel
logSub _ = do
groupVal <- groupFormat action
oldVal <- previousStateFormat oldModel
actionVal <- actionFormat action
newVal <- nextStateFormat newModel
consoleGroupCollapsed groupVal
consoleLog oldVal
consoleLog actionVal
consoleLog newVal
consoleGroupEnd
-- | Action logger with default settings.
-- Wraps around your 'update' function when you construct a Miso app.
defaultActionLogger
:: (Show action, ToJSON model)
=> (action -> model -> Effect action model)
-> action -> model -> Effect action model
defaultActionLogger = mkActionLogger ActionLoggerOptions
{ groupFormat = defaultGroupFormat
, previousStateFormat = defaultStateFormat defaultPreviousStateLabel defaultPreviousStateStyle
, actionFormat = defaultActionFormat
, nextStateFormat = defaultStateFormat defaultNextStateLabel defaultNextStateStyle
}
defaultPreviousStateLabel :: MisoString
defaultPreviousStateLabel = "%cprev state %c"
defaultNextStateLabel :: MisoString
defaultNextStateLabel = "%cnext state %c"
defaultPreviousStateStyle :: MisoString
defaultPreviousStateStyle = "color: #9E9E9E; font-weight: bold;"
defaultNextStateStyle :: MisoString
defaultNextStateStyle = "color: #4CAF50; font-weight: bold;"
defaultGroupFormat :: Show action => action -> IO JSVal
defaultGroupFormat action =
toJSVal
[ "%caction %c" <> ((ms . head . words . show) action)
, "color: gray; font-weight: lighter;"
, ""
]
defaultStateFormat :: ToJSON model => MisoString -> MisoString -> model -> IO JSVal
defaultStateFormat label style model = do
modelVal <- toJSVal (toJSON model)
toJSVal
[ pToJSVal label
, pToJSVal style
, pToJSVal ("" :: MisoString)
, modelVal
]
defaultActionFormat :: Show action => action -> IO JSVal
defaultActionFormat action =
toJSVal
[ pToJSVal ("%caction %c" :: MisoString)
, pToJSVal ("color: #03A9F4; font-weight: bold;" :: MisoString)
, pToJSVal ("" :: MisoString)
, pToJSVal $ show action
]