module Loadable ( Loadable (..) , fromEvent , view ) where import Reflex.Dom (MonadWidget) import qualified Reflex.Dom as R import Data.Functor (Functor) import Data.Text (Text) import Reflex.Dom (Dynamic, Event, MonadWidget) import qualified Reflex.Dom as R data Loadable t = Loading | Error Text | Loaded t deriving Show instance Functor Loadable where fmap f Loading = Loading fmap f (Error e) = Error e fmap f (Loaded x) = Loaded (f x) instance Applicative Loadable where pure x = Loaded x Loading <*> _ = Loading (Error e) <*> _ = Error e (Loaded f) <*> Loading = Loading (Loaded f) <*> (Error e) = Error e (Loaded f) <*> (Loaded x) = Loaded (f x) instance Monad Loadable where Loading >>= f = Loading (Error e) >>= f = Error e (Loaded x) >>= f = f x fromEvent :: forall t m a. MonadWidget t m => Event t (Either Text a) -> m (Dynamic t (Loadable a)) fromEvent = R.foldDyn (\res _ -> case res of Left err -> Error err Right t -> Loaded t ) Loading view :: forall t m a b. MonadWidget t m => (a -> m b) -> Loadable a -> m (Maybe b) view _ Loading = (R.divClass "pageSpinner" $ R.divClass "spinner" $ R.blank) >> return Nothing view _ (Error e) = R.text e >> return Nothing view f (Loaded x) = Just <$> f x