{-|
Module: IHP.FlashMessages.ControllerFunctions
Description: Success and error messages for your application
Copyright: (c) digitally induced GmbH, 2020
-}
module IHP.FlashMessages.ControllerFunctions where

import IHP.Prelude
import IHP.FlashMessages.Types
import IHP.Controller.Context
import IHP.Controller.Session
import qualified Data.Maybe as Maybe

-- | Sets a flash messages. This is shown to the user when the next view is rendered.
--
-- Will be rendered in a bootstrap alert, with the @alert-success@ styling.
-- Take a look at https://getbootstrap.com/docs/4.5/components/alerts/ for how this will look like.
--
-- This requires 'IHP.ViewSupport.renderFlashMessages' to be placed somewhere in the layout or page of the next view.
-- For example:
--
-- > myLayout view = [hsx|
-- >     {renderFlashMessages}
-- >     <main>{view}</main>
-- > |]
setSuccessMessage :: (?context :: ControllerContext) => Text -> IO ()
setSuccessMessage :: Text -> IO ()
setSuccessMessage = (?context::ControllerContext) => Text -> Text -> IO ()
Text -> Text -> IO ()
setSession Text
successMessageKey

-- | Sets a flash messages. This is shown to the user when the next view is rendered.
--
-- Will be rendered in a bootstrap alert, with the @alert-danger@ styling.
-- Take a look at https://getbootstrap.com/docs/4.5/components/alerts/ for how this will look like.
--
-- This requires 'IHP.ViewSupport.renderFlashMessages' to be placed somewhere in the layout or page of the next view.
-- For example:
--
-- > myLayout view = [hsx|
-- >     {renderFlashMessages}
-- >     <main>{view}</main>
-- > |]
setErrorMessage :: (?context :: ControllerContext) => Text -> IO ()
setErrorMessage :: Text -> IO ()
setErrorMessage = (?context::ControllerContext) => Text -> Text -> IO ()
Text -> Text -> IO ()
setSession Text
errorMessageKey

-- | Returns the flash message currently set
getSuccessMessage :: (?context :: ControllerContext) => IO (Maybe Text)
getSuccessMessage :: IO (Maybe Text)
getSuccessMessage = (?context::ControllerContext) => Text -> IO (Maybe Text)
Text -> IO (Maybe Text)
getSession Text
successMessageKey

-- | Removes the current flash message
clearSuccessMessage :: (?context :: ControllerContext) => IO ()
clearSuccessMessage :: IO ()
clearSuccessMessage = (?context::ControllerContext) => Text -> Text -> IO ()
Text -> Text -> IO ()
setSession Text
successMessageKey Text
""

-- Returns a list of all flash messages which need to be displayed to the user
--
-- Then clears the flash messages so they won't be displayed again.
getAndClearFlashMessages :: (?context :: ControllerContext) => IO [FlashMessage]
getAndClearFlashMessages :: IO [FlashMessage]
getAndClearFlashMessages = do
    Maybe Text
successMessage <- IO (Maybe Text)
(?context::ControllerContext) => IO (Maybe Text)
getSuccessMessage
    Maybe Text
errorMessage <- (?context::ControllerContext) => Text -> IO (Maybe Text)
Text -> IO (Maybe Text)
getSession Text
errorMessageKey
    case Maybe Text
successMessage of
        Just Text
value | Text
value Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"" -> (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
setSuccessMessage Text
""
        Maybe Text
_ -> () -> IO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    case Maybe Text
errorMessage of
        Just Text
value | Text
value Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"" -> (?context::ControllerContext) => Text -> IO ()
Text -> IO ()
setErrorMessage Text
""
        Maybe Text
_ -> () -> IO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    [FlashMessage] -> IO [FlashMessage]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([FlashMessage] -> IO [FlashMessage])
-> [FlashMessage] -> IO [FlashMessage]
forall a b. (a -> b) -> a -> b
$ [Maybe FlashMessage] -> [FlashMessage]
forall a. [Maybe a] -> [a]
Maybe.catMaybes (((Text -> FlashMessage) -> Maybe Text -> Maybe FlashMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> FlashMessage
SuccessFlashMessage Maybe Text
successMessage)Maybe FlashMessage -> [Maybe FlashMessage] -> [Maybe FlashMessage]
forall a. a -> [a] -> [a]
:((Text -> FlashMessage) -> Maybe Text -> Maybe FlashMessage
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> FlashMessage
ErrorFlashMessage Maybe Text
errorMessage)Maybe FlashMessage -> [Maybe FlashMessage] -> [Maybe FlashMessage]
forall a. a -> [a] -> [a]
:[])

successMessageKey :: Text
successMessageKey :: Text
successMessageKey = Text
"flashSuccessMessage"

errorMessageKey :: Text
errorMessageKey :: Text
errorMessageKey = Text
"flashErrorMessage"

initFlashMessages :: (?context :: ControllerContext) => IO ()
initFlashMessages :: IO ()
initFlashMessages = do
    [FlashMessage]
flashMessages <- IO [FlashMessage]
(?context::ControllerContext) => IO [FlashMessage]
getAndClearFlashMessages
    [FlashMessage] -> IO ()
forall value.
(?context::ControllerContext, Typeable value) =>
value -> IO ()
putContext [FlashMessage]
flashMessages