Add a basic HTML interface

This commit is contained in:
Emi Simpson 2022-11-08 22:42:02 -05:00
parent 257712bfae
commit 831b361eda
Signed by: Emi
GPG Key ID: A12F2C2FFDC3D847
5 changed files with 151 additions and 3 deletions

128
index.html Normal file
View File

@ -0,0 +1,128 @@
<!Doctype HTML>
<html>
<head>
<style>
body {
margin: 0;
padding: 0;
background: #201b27;
color: white;
font-family: sans-serif;
}
#thumbnails {
display: flex;
flex-wrap: wrap;
gap: 30px;
justify-content: center;
}
.thumbnail-card {
height: 400px;
}
#focused-panel {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 60%);
display: grid;
justify-items: center;
align-items: center;
box-sizing: border-box;
overflow: auto;
}
#focused-panel > img {
max-height: 80vh;
max-width: 60vw;
padding: 50px;
}
#spinner {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
#loader-text {
position: absolute;
width: fit-content;
height: fit-content;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto auto;
text-align: center;
font-size: 31px;
}
/* Yoinked from https://codepen.io/AdamDipinto/pen/eYOaGvY
with modifications */
.loader {
position: relative;
width: 350px;
height: 350px;
border-radius: 50%;
background: linear-gradient(#ff52bf, #f1f1f1, #1ed3ec);
animation: animate 1.2s linear infinite;
}
@keyframes animate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.loader span {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
background: linear-gradient(#ff52bf, #f1f1f1, #1ed3ec);
}
.loader span:nth-child(1) {
filter: blur(5px);
}
.loader span:nth-child(2) {
filter: blur(10px);
}
.loader span:nth-child(3) {
filter: blur(25px);
}
.loader span:nth-child(4) {
filter: blur(50px);
}
.loader:after {
content: '';
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
background: #201b27;
border-radius: 50%;
}
</style>
<script src="/index.js"></script>
<script src="https://unpkg.com/rescript-blurhash@0.4.0/dist/production.min.js"></script>
</head>
<body>
<div id="spinner">
<div class="loader">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div id="loader-text">Downloading<br/>Gallery...</div>
</div>
</body>
</html>

View File

@ -1,6 +1,7 @@
module Main where
import Prelude
import Aviary.FFI (removeSpinner)
import Aviary.UI (component)
import Aviary.Logic (fetch_and_decrypt_gallery, get_parameters)
import Aviary.Model (Model(..))
@ -8,6 +9,7 @@ import Aviary.Model (Model(..))
import Data.Either (Either(..))
import Effect (Effect)
import Effect.Aff (Aff, launchAff)
import Effect.Class (liftEffect)
import Halogen.Aff (awaitBody)
import Halogen.VDom.Driver (runUI)
@ -18,6 +20,7 @@ main_aff = do
gallery <- case parameters of
Left e -> pure $ GError e
Right parameters' -> fetch_and_decrypt_gallery parameters'
_ <- liftEffect $ removeSpinner
_ <- runUI (component gallery) unit body
pure unit

View File

@ -25,6 +25,7 @@ data Event = LoadThumbs
| ThumbLoaded Int ImageData
| FullLoaded Int ImageData
| Focus Int
| Unfocus
component :: forall query input. Model -> H.Component query input Event Aff
component initialState = H.mkComponent
@ -52,8 +53,8 @@ renderThumbnail pos image =
renderFocused :: forall m. Image -> H.ComponentHTML Event () m
renderFocused image =
HH.div
[ HP.class_ $ ClassName "focused-panel"
, HP.class_ $ ClassName "visible"
[ HP.id $ "focused-panel"
, HE.onClick \_ -> Unfocus
]
( [ HH.img $
maybe [] (HP.src >>> pure) (fullOrBlurhash image)
@ -107,11 +108,18 @@ update (Focus newFocus) = do
Just focusedImage' -> fetchFullAction newFocus focusedImage'
Nothing ->
H.put $ GError $ UnexpectedError "Focus event raised with an out of bounds index!"
update Unfocus = H.modify_ \model -> case model of
GError e -> GError e
GLoaded gal -> GLoaded gal { focus = Nothing }
render :: forall m. Model -> H.ComponentHTML Event () m
render (GError e) = HH.p_ [ HH.text $ show e ]
render (GLoaded {title, desc, images, focus}) = HH.div_
((maybe [] (HH.text >>> pure >>> HH.h1_ >>> pure) title) <>
(maybe [] (HH.text >>> pure >>> HH.p_ >>> pure) desc) <>
(mapWithIndex renderThumbnail images) <>
[ HH.div
[ HP.id "thumbnails"
]
(mapWithIndex renderThumbnail images)
] <>
(maybe [] (renderFocused >>> pure) (index images =<< focus)))

View File

@ -21,3 +21,7 @@ export function decodeBlurhashImpl(just) {
}
}
}
export function removeSpinner() {
document.getElementById("spinner").remove()
}

View File

@ -1,7 +1,10 @@
module Aviary.FFI where
import Prelude
import Data.ArrayBuffer.Types (ArrayBuffer)
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Web.File.Blob (Blob)
-- mimeType :: String
@ -15,3 +18,5 @@ decodeBlurhash :: Int -> Int -> String -> Maybe String
decodeBlurhash = decodeBlurhashImpl Just Nothing
decodeBlurhash32 :: String -> Maybe String
decodeBlurhash32 = decodeBlurhash 32 32
foreign import removeSpinner :: Effect Unit