{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecursiveDo #-} -- | Load time manipulation module Reflex.Bulmex.Load ( pageLoader , prerenderLoad -- * Load tricks , withReadyEvt , postpone , getReady ) where import Control.Monad (void) import Control.Monad.IO.Class (MonadIO) import qualified Data.Text as Text import Reflex import Reflex.Bulmex.Event import Reflex.Bulmex.Tag.Abstract import Reflex.Dom.Builder.Class import Reflex.Dom.Prerender import qualified Reflex.Dom.Widget.Basic as Dom import qualified Reflex.Tags as T -- | Bulma loading screen with help of extension: -- https://wikiki.github.io/elements/pageloader/ pageLoader :: DomBuilder t m => Text.Text -> m a -> m a pageLoader = partialDiv "pageloader" -- | show input monad while JS is loading, for example a spinning image prerenderLoad :: (Prerender js t m, DomBuilder t m) => m () -> m () prerenderLoad spinner = void $ prerender (T.divClass "prerender-load" $ spinner) Dom.blank -- | Don't display something untill event occurs, -- combine with getready to delay loading of non-critical components postpone :: (DomBuilder t m, MonadHold t m) => Event t () -> m () -> m () postpone evt m = holdEvent_ evt (const m) -- | This doesn't work always, -- When finished use: https://github.com/reflex-frp/reflex-dom/pull/273 -- postbuild is imediate for sampling, adding a delay makes it after -- widget completes see: https://github.com/reflex-frp/reflex-dom-semui/issues/18 getReady :: ( PostBuild t m , PerformEvent t m , TriggerEvent t m , MonadIO (Performable m) ) => m (Event t ()) getReady = getPostBuild >>= delay 0 -- | attach the ready event to the widget, which fires once it's usuable withReadyEvt :: ( PostBuild t m , PerformEvent t m , TriggerEvent t m , MonadIO (Performable m) ) => m b -> m (b, Event t ()) withReadyEvt mb = do res <- mb evt <- getReady pure (res, evt)