This repository has been archived on 2024-10-24. You can view files and clone it, but cannot push or open issues or pull requests.
fradrive-old/src/Utils/Frontend/Modal.hs
Gregor Kleen 67e3b38834 chore: bump versions
BREAKING CHANGE: yesod >=1.6
2019-09-25 13:46:10 +02:00

75 lines
2.5 KiB
Haskell

module Utils.Frontend.Modal
( Modal(..)
, customModal
, modal, msgModal
, addMessageModal
) where
import ClassyPrelude.Yesod
import Control.Lens
import Utils.Route
import Utils.Message
import Settings (widgetFile)
import Control.Monad.Random.Class (uniform)
import Control.Monad.Trans.Random (evalRandTIO)
data Modal site = Modal
{ modalTriggerId
, modalId :: Maybe Text
, modalTrigger :: Maybe Text {- Dynamic URL -} -> Text {- TriggerId -} -> WidgetFor site ()
, modalContent :: Either (SomeRoute site) (WidgetFor site ())
}
customModal :: Modal site -> WidgetFor site ()
customModal Modal{..} = do
triggerId' <- maybe newIdent return modalTriggerId
$(widgetFile "widgets/modal/modal")
route <- traverse toTextUrl $ modalContent ^? _Left
modalTrigger route triggerId'
-- | Create a link to a modal
modal :: WidgetFor site () -- ^ Widget that represents the link
-> Either (SomeRoute site) (WidgetFor site ()) -- ^ Modal contant: either dynamic link or static widget
-> WidgetFor site () -- ^ result widget
modal modalTrigger' modalContent = customModal Modal{..}
where
modalTriggerId = Nothing
modalId = Nothing
modalTrigger mRoute triggerId = $(widgetFile "widgets/modal/trigger")
-- | Variant of `modal` for use in messages (uses a different id generator to avoid collisions)
msgModal :: WidgetFor site ()
-> Either (SomeRoute site) (WidgetFor site ())
-> WidgetFor site ()
msgModal modalTrigger' modalContent = do
let
randomIdentifier :: MonadIO m => m Text
-- ^ Generates valid CSS-Identifiers with roughly 128 bits of entropy
--
-- See https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
randomIdentifier = fmap pack . evalRandTIO $ do
prefix <- uniform $ ['a'..'z'] ++ ['A'..'Z']
suffix <- replicateM 21 . uniform $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9']
return $ prefix : suffix
modalTriggerId <- Just <$> randomIdentifier
modalId <- Just <$> randomIdentifier
customModal Modal{..}
where
modalTrigger mRoute triggerId = $(widgetFile "widgets/modal/trigger")
-- | add message alert with a short trigger widget, whose larger content is displayed in a modal
addMessageModal :: forall m site.
( MonadHandler m
, HandlerSite m ~ site
, Yesod site
) => MessageStatus -> WidgetFor site () -> Either (SomeRoute site) (WidgetFor site ()) -> m ()
addMessageModal ms trigger content = addMessageWidget ms $ msgModal trigger content