aviary-ps/src/UI.purs

75 lines
2.5 KiB
Plaintext

module Aviary.UI where
import Prelude
import Aviary.Logic (fetchThumb)
import Aviary.Model (GalleryError(..), Image, ImageData(..), Model(..))
import Control.Parallel (parSequence_)
import Data.Array (mapWithIndex, modifyAt)
import Data.Maybe (maybe, Maybe(..))
import Effect.Aff (Aff)
import Halogen as H
import Halogen.HTML as HH
import Halogen.HTML.Properties as HP
import Web.HTML.Common (ClassName(..))
data Event = LoadThumbs
| ThumbLoaded Int ImageData
component :: forall query input. Model -> H.Component query input Event Aff
component initialState = H.mkComponent
{ initialState: \_ -> initialState
, render
, eval: H.mkEval $ H.defaultEval { handleAction = update, initialize = Just LoadThumbs }
}
placeholderBlurhash :: forall r i. String -> HH.IProp r i
placeholderBlurhash = HH.attr (HH.AttrName "data-blurhash")
renderThumbnail :: forall m. Image -> H.ComponentHTML Event () m
renderThumbnail {blurhash, thumb} =
HH.div
[ HP.class_ $ ClassName "thumbnail-card"
]
( [ HH.img
( [ placeholderBlurhash blurhash
, HP.width 400
, HP.height 400
] <> case thumb of
ILoaded url -> [HP.src url]
_ -> []
)
] <> case thumb of
Unloaded _ -> [HH.p_ [HH.text "Loading..."]]
IError e -> [HH.p_ [HH.text $ "Error! " <> (show e)]]
_ -> []
)
setThumb :: Int -> ImageData -> Model -> Model
setThumb pos newThumb (GLoaded title desc images) =
case modifyAt pos (\i -> i{thumb=newThumb}) images of
Just newImages -> GLoaded title desc newImages
Nothing -> GError $ UnexpectedError "setThumb called with an invalid index!"
setThumb _ _ model = model
fetchThumbAction :: Int -> Image -> H.HalogenM Model Event () Event Aff Unit
fetchThumbAction position image = do
newData <- H.liftAff $ fetchThumb image
update $ ThumbLoaded position newData
update :: Event -> H.HalogenM Model Event () Event Aff Unit
update LoadThumbs = do
model <- H.get
case model of
GError _ -> pure unit
GLoaded _ _ images -> parSequence_ $ mapWithIndex fetchThumbAction images
update (ThumbLoaded pos newData) = H.modify_ $ setThumb pos newData
render :: forall m. Model -> H.ComponentHTML Event () m
render (GError e) = HH.p_ [ HH.text $ show e ]
render (GLoaded title desc images) = HH.div_
((maybe [] (HH.text >>> pure >>> HH.h1_ >>> pure) title) <>
(maybe [] (HH.text >>> pure >>> HH.p_ >>> pure) desc) <>
(renderThumbnail <$> images))