wikimusic-ssr-1.0.1.6: src/WikiMusic/SSR/View/HtmlUtil.hs
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE NoFieldSelectors #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module WikiMusic.SSR.View.HtmlUtil where
import Principium
import Text.Blaze.Html5 as H hiding (map)
import Text.Blaze.Html5.Attributes as A
import WikiMusic.SSR.View.Components.Footer
import WikiMusic.SSR.View.Components.PageTop
newtype SimplePageTitle = SimplePageTitle {value :: Text} deriving (Eq, Show)
makeFieldLabelsNoPrefix ''SimplePageTitle
mkSharedHead :: (MonadIO m) => Env -> ViewVars -> SimplePageTitle -> m Html
mkSharedHead _ _ pageTitle = do
pure $ H.head $ do
H.meta ! charset "utf-8"
H.meta ! lang "en"
H.title . text $ (pageTitle ^. #value)
meta ! name "viewport" ! content "width=device-width, initial-scale=1"
H.style
. text
$ [trimming|
@import url('https://fonts.cdnfonts.com/css/liberation-sans');
@import url('https://fonts.cdnfonts.com/css/liberation-serif');
@font-face {
font-family: 'Intel One Mono';
font-style: normal;
font-weight: 400;
src: url('/static/ttf/IntelOneMono-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'Intel One Mono';
font-style: italic;
font-weight: 400;
src: url('/static/ttf/IntelOneMono-Italic.ttf') format('truetype');
}
@font-face {
font-family: 'Intel One Mono';
font-style: normal;
font-weight: 500;
src: url('/static/ttf/IntelOneMono-Medium.ttf') format('truetype');
}
@font-face {
font-family: 'Intel One Mono';
font-style: italic;
font-weight: 500;
src: url('/static/ttf/IntelOneMono-MediumItalic.ttf') format('truetype');
}
@font-face {
font-family: 'Intel One Mono';
font-style: normal;
font-weight: 700;
src: url('/static/ttf/IntelOneMono-Bold.ttf') format('truetype');
}
@font-face {
font-family: 'Intel One Mono';
font-style: italic;
font-weight: 700;
src: url('/static/ttf/IntelOneMono-BoldItalic.ttf') format('truetype');
}
@font-face {
font-family: 'Intel One Mono';
font-style: normal;
font-weight: 300;
src: url('/static/ttf/IntelOneMono-Light.ttf') format('truetype');
}
@font-face {
font-family: 'Intel One Mono';
font-style: italic;
font-weight: 300;
src: url('/static/ttf/IntelOneMono-LightItalic.ttf') format('truetype');
}
|]
H.script ! src "https://cdn.tailwindcss.com?plugins=forms,typography,aspect-ratio,container-queries" $ ""
H.script
. text
$ [trimming|
tailwind.config = {
theme: {
container: { center: true },
fontFamily: {
sans: ['Liberation Sans', 'sans-serif'],
serif: ['Liberation Serif', 'serif'],
mono: ['Intel One Mono', 'monospace']
},
}
}
|]
simplePage :: (MonadIO m) => Env -> ViewVars -> SimplePageTitle -> Html -> m Html
simplePage env vv title' body' = do
sharedHead <- mkSharedHead env vv title'
pure $ H.html $ do
sharedHead
bodyWithFooter vv $ do
sharedPageTop Nothing vv
(H.div ! css' ["text-center", "my-4"]) $ do
(H.h2 ! css' ["text-xl", "text-slate-600", "font-mono", "font-bold"]) . text $ title' ^. #value
body'
paginationOffsetJS :: Text -> Text -> Text
paginationOffsetJS offset' newOffset =
[trimming|(function(){
if(/offset/.test(window.location.toString())){
window.location = window.location.toString()
.replace("offset=$offset'", "offset=$newOffset");
}else{
window.location = window.location + "?offset=$newOffset";
}
})
()|]
maybeNextPaginationButton :: ViewVars -> Limit -> Offset -> Int -> Html
maybeNextPaginationButton _ _ _ 0 = pure ()
maybeNextPaginationButton _ (Limit 0) _ _ = pure ()
maybeNextPaginationButton vv (Limit limit) (Offset offset) itemSize =
when (itemSize == limit)
$ H.button
! css (cssButton vv)
! onclick (textToAttrValue . minify $ paginationOffsetJS offset' newOffset)
$ "("
<> pageNum
<> ") next page >"
where
offset' = show offset
newOffset = show $ offset + limit
pageNum = show $ (offset `Principium.div` limit) + 1
minify =
replaceText
"\n"
""
maybePrevPaginationButton :: ViewVars -> Limit -> Offset -> Int -> Html
maybePrevPaginationButton _ (Limit 0) _ _ = pure ()
maybePrevPaginationButton vv (Limit limit) (Offset offset) _ =
when (offset > 0)
$ H.button
! css (cssButton vv)
! onclick (textToAttrValue . minify $ paginationOffsetJS offset' newOffset)
$ "< previous page ("
<> pageNum
<> ")"
where
offset' = show offset
newOffset = show $ offset - limit
pageNum = show $ (offset `Principium.div` limit) - 1
minify = replaceText "\n" ""