support updates

This commit is contained in:
Rhiannon Morris 2020-09-19 07:51:52 +02:00
parent e296e41b8b
commit 7f91331195
7 changed files with 120 additions and 39 deletions

View File

@ -131,22 +131,27 @@ makeYearItems nsfw year infos = [b|@4
year' = show year & foldMap \c -> [b|<span class=y>$c</span>|]
makeItem :: Bool -> FilePath -> Info -> Builder
makeItem nsfw file info@(Info {title, bg, date}) = [b|@4
<li class="item post$nsfw'" data-tags="$tags'" data-date="$date'">
makeItem nsfw file info@(Info {title, bg}) = [b|@4
<li class="item post$nsfw'" data-date="$date'" data-updated="$updated'"
data-tags="$tags'">
<figure>
<a href="$dir">
<img src="$thumb"$bgStyle>
</a>
<figcaption>$title</figcaption>
<figcaption>
<span class=date>$date'</span>
<span class=title>$title</span>
</figcaption>
</figure>
|]
where
dir = takeDirectory file
thumb = getThumb dir info
nsfw' = if nsfw && #anyNsfw info then [b| nsfw|] else ""
tags' = fold $ intersperse ";" $ map fromText $ tagsFor nsfw info
date' = formatDateShort date
bgStyle = ifJust bg \col -> [b| style="background: $col"|]
dir = takeDirectory file
thumb = getThumb dir info
nsfw' = if nsfw && #anyNsfw info then [b| nsfw|] else ""
tags' = fold $ intersperse ";" $ map fromText $ tagsFor nsfw info
date' = formatDateShort $ #latestDate info
updated' = if #updated info then [b|true|] else [b|false|]
bgStyle = ifJust bg \col -> [b| style="background: $col"|]
formatDateShort :: Time.Day -> Builder
formatDateShort date = [b|$day $month|] where

View File

@ -19,6 +19,7 @@ import Data.Foldable (find)
import Data.Hashable (Hashable)
import Data.HashSet (HashSet)
import qualified Data.HashSet as HashSet
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (isJust, isNothing)
import Data.List (nub)
@ -40,6 +41,7 @@ data Info =
-- e.g. multiple things on the same day might have a,b,c in @sortEx@ to
-- put them in the right order in the gallery
sortEx :: !Text,
updates :: !(Map Day Text),
title :: !Text,
artist :: !(Maybe Artist), -- nothing = me, obv
nsfwOnly :: !Bool,
@ -109,6 +111,11 @@ instance HasField "year" Info Integer where getField = #first . #dmy
instance HasField "month" Info Int where getField = #second . #dmy
instance HasField "day" Info Int where getField = #third . #dmy
instance HasField "latestDate" Info Day where
getField (Info {date, updates}) = maximum (date : Map.keys updates)
instance HasField "updated" Info Bool where getField = not . Map.null . #updates
descFor :: Bool -> Info -> Maybe Text
descFor nsfw (Info {desc, nsfwDesc}) = desc <> (guard nsfw *> nsfwDesc)
@ -122,7 +129,7 @@ linksFor :: Bool -> Info -> [Link]
linksFor nsfw = if nsfw then #links else #sfwLinks
instance Ord Info where
compare = comparing \Info {date, sortEx, title} -> (date, sortEx, title)
compare = comparing \i -> (#latestDate i, #sortEx i, #title i)
newtype NoThumb = NoThumb FilePath
@ -150,7 +157,8 @@ addSuffix suf path =
instance FromYAML Info where
parseYAML = YAML.withMap "info" \m ->
Info <$> m .: "date"
<*> m .:? "sort" .!= ""
<*> m .:? "sort" .!= ""
<*> m .:? "updates" .!= []
<*> m .: "title"
<*> m .:? "artist"
<*> m .:? "nsfw-only" .!= False

View File

@ -5,10 +5,11 @@ import BuilderQQ
import Records ()
import Control.Exception
import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import qualified Data.Text as Strict
import qualified Data.Text.Lazy as Lazy
import qualified Data.Time.Calendar as Time
import qualified Data.Time as Time
import System.FilePath (joinPath, splitPath, (</>))
import qualified System.Process as Proc
import Text.Read (readMaybe)
@ -34,7 +35,8 @@ make root prefix nsfw dataDir dir info =
toLazyText <$> make' root prefix nsfw dataDir dir info
make' :: Text -> FilePath -> Bool -> FilePath -> FilePath -> Info -> IO Builder
make' root prefix nsfw dataDir dir info@(Info {date, title, artist, bg}) = do
make' root prefix nsfw dataDir dir
info@(Info {date, title, artist, bg, updates}) = do
images <- withSizes (dataDir </> dir) $ imagesFor nsfw info
let undir = joinPath (replicate (length (splitPath dir)) "..")
@ -53,6 +55,7 @@ make' root prefix nsfw dataDir dir info@(Info {date, title, artist, bg}) = do
let descSection = makeDesc $ descFor nsfw info
let tagsList = makeTags undir $ tagsFor nsfw info
let linksList = extLinks $ linksFor nsfw info
let updatesList = makeUpdates $ Map.toList updates
let makePrefetch (Image {path}) = [b|<link rel=prefetch href=$path>|]
let prefetches = map (makePrefetch . #first) $ tail images
@ -76,6 +79,9 @@ make' root prefix nsfw dataDir dir info@(Info {date, title, artist, bg}) = do
Nothing -> "by niss"
let thumb = getThumb "" info
let updateDate = ifJust (Map.lookupMax updates) \(formatDate -> u, _) ->
[b|<br> <span class=updated>updated $u</span>|]
pure [b|@0
<!DOCTYPE html>
<html lang=en>
@ -103,7 +109,9 @@ make' root prefix nsfw dataDir dir info@(Info {date, title, artist, bg}) = do
<header>
<h1>$title</h1>
$artistTag
<h2 id=date class="right corner">$formattedDate</h2>
<h2 id=date class="right corner">
$formattedDate $updateDate
</h2>
</header>
$buttonBar
@ -122,6 +130,8 @@ make' root prefix nsfw dataDir dir info@(Info {date, title, artist, bg}) = do
$tagsList
$linksList
$updatesList
</div>
</main>
@ -217,6 +227,25 @@ extLink (Link {title, url}) = [b|@8
</a>
|]
makeUpdates :: [(Day, Text)] -> Builder
makeUpdates ups =
if null ups then "" else [b|@4
<section id=updates class=info-section>
<h2>updates</h2>
<dl>
$8.updateList
</dl>
</section>
|]
where updateList = map (uncurry makeUpdate) ups
makeUpdate :: Day -> Text -> Builder
makeUpdate date txt = [b|@8
<dt>$date'
<dd>$txt
|]
where date' = Time.formatTime Time.defaultTimeLocale "%-d/%-m/%Y" date
formatDate :: Day -> Builder
formatDate date = [b|$week $day $month $year|] where
(year, month', day') = Time.toGregorian date

1
style/cake.svg Normal file
View File

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="1.5" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><metadata/><path d="m0 0h32v32h-32z" fill="none"/><path d="m15.086 6.532c.129-.53.401-1.019.793-1.411l1-1c.562-.562 1.325-.878 2.121-.878s1.559.316 2.121.878c.251.251.507.507.758.758.268.268.48.581.628.922 2.498.742 4.839 1.987 6.87 3.68.384.32.623.519.623.519v13l-28 7v-13z" fill="none" stroke="#000" stroke-width="4"/><path d="m2 19v-2l2-1 23-7 3 1v13l-2 .5z" fill="#ccc"/><path d="m28 18.5v5l-26 6.5v-5l1-1 24-6zm-26 4.5v-4l24.757-6.189c.299-.075.616-.008.858.182.243.189.385.48.385.788v2.719l-1 1.5-24 5.5-1-.5z" fill="#eaae53"/><path d="m28 18.5-26 6.5v-2l26-6.5z" fill="#da6363"/><path d="m2 17 15-12c4.523 0 8.903 1.586 12.377 4.481.384.32.623.519.623.519l-28 7z" fill="#fff"/><path d="m16 11c-.265 0-.52-.105-.707-.293-.188-.187-.293-.442-.293-.707v-2.757c0-.796.316-1.559.879-2.122l1-1c.562-.562 1.325-.878 2.121-.878s1.559.316 2.121.878c.251.251.507.507.758.758.562.562.878 1.325.878 2.121s-.316 1.559-.878 2.121c-.353.353-.702.702-1 1-.563.563-1.326.879-2.122.879-.85 0-1.964 0-2.757 0z" fill="#d72d35"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -116,17 +116,12 @@ body {
box-shadow: var(--focus-box);
}
.item[data-date]::before {
content: attr(data-date);
}
figure {
margin: 0;
padding: 0;
}
figcaption, .item::before {
figcaption .date, figcaption .title {
position: absolute;
width: 100%;
border: 1px solid var(--text-col);
@ -134,10 +129,11 @@ figcaption, .item::before {
text-align: center;
background: hsl(0, 0%, 0%, 75%);
font-size: 80%;
text-shadow: none;
}
figcaption { bottom: -1px; left: -1px; }
.item::before { top: -1px; left: -1px; }
figcaption .date { top: -1px; left: -1px; }
figcaption .title { bottom: -1px; left: -1px; }
.year-marker {
grid-area: auto / 1;
@ -164,19 +160,31 @@ figcaption { bottom: -1px; left: -1px; }
transform: scaleX(110%);
}
.item.nsfw::after {
--size: calc(1/4 * var(--image-size));
content: url(../18_plus_white.svg);
.item.nsfw::before, .item[data-updated="true"]::after {
height: var(--size);
width: var(--size);
display: inline-block;
position: absolute;
}
.item.nsfw::before {
--size: calc(1/4 * var(--image-size));
--base-transform: rotate(var(--nsfw-sticker-rotate));
content: url(../18_plus_white.svg);
top: calc(1em + 3px);
right: 3px;
transform: rotate(var(--nsfw-sticker-rotate));
mix-blend-mode: multiply;
transform: var(--base-transform);
}
.item[data-updated="true"]::after {
--size: calc(1/4 * var(--image-size));
content: url(../sparkles.svg);
bottom: calc(1em + 3px);
right: 3px;
mix-blend-mode: overlay;
}
footer {
@ -187,30 +195,33 @@ footer {
@media (hover) {
.item:hover figcaption, .item:hover::before {
.item:hover .date, .item:hover .title,
.item:hover::before, .item:hover::after {
filter: opacity(20%);
}
@media (prefers-reduced-motion) {
.item:hover figcaption {
transform: translateY(80%);
}
}
@media (prefers-reduced-motion: no-preference) {
figcaption, .item::before {
figcaption .date, figcaption .title, .item::before, .item::after {
transition-property: filter, transform;
transition-duration: 0.25s;
transition-duration: 0.15s;
transition-timing-function: ease-in-out;
}
.item:hover figcaption {
.item:hover .title {
transform: translate(-20%, 80%) rotateZ(7deg);
}
.item:hover::before {
.item:hover .date {
transform: translate(20%, -80%) rotateZ(7deg);
}
.item:hover::before {
transform: translate(1.5em, -1.5em) var(--base-transform);
}
.item:hover::after {
transform: translate(1.5em, 1.5em);
}
}
}
@ -219,10 +230,14 @@ footer {
height: min-content;
}
figcaption {
figcaption .date, figcaption .title {
position: initial;
}
figcaption .date::after {
content: ':';
}
.item a {
display: block;
height: var(--image-size);

View File

@ -132,6 +132,28 @@ body {
margin: 0.35em;
}
#updates dl {
display: grid;
grid-template-columns: min-content auto;
grid-gap: 0.5em;
align-items: baseline;
}
#updates dt {
font-size: 80%;
font-weight: 700;
grid-area: auto / 1;
}
#updates dd {
grid-area: auto / 2;
}
.updated {
font-size: 90%;
font-style: italic;
}
footer {
text-align: center;
margin-top: 1em;

1
style/sparkles.svg Normal file
View File

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="1.5" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><metadata/><g fill="none"><path d="m0 0h32v32h-32z"/><path d="m14 15 5.5-2.5 2.5-8.5 2.5 8.5 5.5 2.5-5.5 2.5-2.5 8.5-2.5-8.5z" stroke="#000" stroke-width="4"/><path d="m4 23 3.5-1.5 1.5-5.5 1.5 5.5 3.5 1.5-3.5 1.5-1.5 5.5-1.5-5.5z" stroke="#000" stroke-width="4"/><path d="m2 7 2-1 1-4 1 4 2 1-2 1-1 4-1-4z" stroke="#000" stroke-width="4"/></g><path d="m14 15 5.5-2.5 2.5-8.5 2.5 8.5 5.5 2.5-5.5 2.5-2.5 8.5-2.5-8.5z" fill="#fdef24"/><path d="m4 23 3.5-1.5 1.5-5.5 1.5 5.5 3.5 1.5-3.5 1.5-1.5 5.5-1.5-5.5z" fill="#fdef24"/><path d="m2 7 2-1 1-4 1 4 2 1-2 1-1 4-1-4z" fill="#fdef24"/></svg>

After

Width:  |  Height:  |  Size: 760 B