style & layout updates
This commit is contained in:
parent
ebd08fb2e5
commit
485b90fb46
9 changed files with 65 additions and 159 deletions
|
@ -1,7 +1,7 @@
|
|||
module Date
|
||||
(Date (..),
|
||||
Day (..), dayNum, exact,
|
||||
formatLong, formatShort, formatRSS, formatSlash,
|
||||
formatLong, formatShort, formatRSS, formatSlash, formatTooltip,
|
||||
parseP, parseS, parseA)
|
||||
where
|
||||
|
||||
|
@ -9,7 +9,7 @@ import Control.Applicative
|
|||
import qualified Text.ParserCombinators.ReadP as ReadP
|
||||
import Text.ParserCombinators.ReadP (ReadP, readS_to_P, readP_to_S, (<++))
|
||||
import Data.Time hiding (Day)
|
||||
import Data.Char (isSpace)
|
||||
import Data.Char (isSpace, toLower)
|
||||
import BuilderQQ
|
||||
import Data.Function (on)
|
||||
import Data.Maybe (fromMaybe)
|
||||
|
@ -60,6 +60,15 @@ formatShort (Date {month, day}) = [b|$day'$month'|] where
|
|||
Unknown -> ""
|
||||
month' = formatTime defaultTimeLocale "%b" $ fromGregorian 1 month 1
|
||||
|
||||
formatTooltip :: Date -> Builder
|
||||
formatTooltip (Date {year, month, day}) = [b|$day'$month' $year|] where
|
||||
day' = case day of
|
||||
Exact d -> [b|$d $&|]
|
||||
Approx d -> [b|$d? $&|]
|
||||
Unknown -> ""
|
||||
month' = map toLower $
|
||||
formatTime defaultTimeLocale "%b" $ fromGregorian 1 month 1
|
||||
|
||||
formatRSS :: Date -> Builder
|
||||
formatRSS = fromString . format . toTime where
|
||||
format = formatTime defaultTimeLocale "%a, %d %b %_Y %T GMT"
|
||||
|
|
|
@ -12,7 +12,7 @@ import Data.Function (on, (&))
|
|||
import qualified Data.HashMap.Strict as HashMap
|
||||
import Data.HashSet (HashSet)
|
||||
import qualified Data.HashSet as HashSet
|
||||
import Data.List (intersperse, groupBy, sortBy, sortOn)
|
||||
import Data.List (intersperse, groupBy, sortBy, sort)
|
||||
import Data.Maybe
|
||||
import qualified Data.Text.Lazy as Lazy
|
||||
import System.FilePath (takeDirectory, joinPath, splitPath)
|
||||
|
@ -52,9 +52,8 @@ make' root (GalleryInfo {title, desc, prefix, filters, hidden}) infos = [b|@0
|
|||
<div class=page>
|
||||
<header>
|
||||
<h1>$title</h1>
|
||||
<h2 class="right corner">
|
||||
<a href=rss.xml>rss</a>
|
||||
</h2>
|
||||
<a class="right corner" href=rss.xml>rss</a>
|
||||
<a class="left corner" href=$undir>back</a>
|
||||
</header>
|
||||
|
||||
<nav id=filters>
|
||||
|
@ -86,10 +85,6 @@ make' root (GalleryInfo {title, desc, prefix, filters, hidden}) infos = [b|@0
|
|||
$6.items
|
||||
</ul>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<a href=$undir>all galleries</a>
|
||||
</footer>
|
||||
</div>
|
||||
|]
|
||||
where
|
||||
|
@ -110,7 +105,7 @@ make' root (GalleryInfo {title, desc, prefix, filters, hidden}) infos = [b|@0
|
|||
allTags = infos
|
||||
& concatMap (map (,1) . tagsFor nsfw . #second)
|
||||
& HashMap.fromListWith (+) & HashMap.toList
|
||||
& sortOn (\(tag, count) -> (Down count, tag))
|
||||
& sort
|
||||
|
||||
requireFilters = map (uncurry $ makeFilter "require" mempty) allTags
|
||||
excludeFilters = map (uncurry $ makeFilter "exclude" hidden) allTags
|
||||
|
@ -153,18 +148,12 @@ makeYearItems nsfw year infos = [b|@0
|
|||
|
||||
makeItem :: Bool -> FilePath -> Info -> Builder
|
||||
makeItem nsfw file info@(Info {bg}) = [b|@0
|
||||
<li class="item post$nsfw'" data-date="$date'" data-year=$year'
|
||||
data-updated="$updated'"
|
||||
<li class="item post$nsfw'" data-year=$year' data-updated="$updated'"
|
||||
data-tags="$tags'">
|
||||
<figure>
|
||||
<a href="$dir">
|
||||
<img src="$thumb" loading=lazy$bgStyle>
|
||||
<img src="$thumb" loading=lazy$bgStyle
|
||||
title="$tooltip">
|
||||
</a>
|
||||
<figcaption>
|
||||
<span class=date>$date'</span>
|
||||
<span class=title>$title</span>
|
||||
</figcaption>
|
||||
</figure>
|
||||
|]
|
||||
where
|
||||
title = fromMaybe (#title info) $ #galleryTitle info
|
||||
|
@ -173,7 +162,10 @@ makeItem nsfw file info@(Info {bg}) = [b|@0
|
|||
nsfw' = if nsfw && #anyNsfw info then [b| nsfw|] else ""
|
||||
tags' = fold $ intersperse ";" $ map fromText $ tagsFor nsfw info
|
||||
date = #latestDate info nsfw
|
||||
date' = formatShort date
|
||||
date' = formatTooltip date
|
||||
year' = #year date
|
||||
updated' = if #updated info nsfw then [b|true|] else [b|false|]
|
||||
bgStyle = case bg of Other col -> [b| style="background: $col"|]; _ -> ""
|
||||
tooltip =
|
||||
let upd = if #updated info nsfw then "updated " else "" :: Builder in
|
||||
[b|$title ($upd$date')|]
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
{-# OPTIONS_GHC -Wno-orphans #-}
|
||||
module Info
|
||||
(Info (..),
|
||||
tagsFor, descFor, imagesFor, linksFor, updatesFor, compareFor, sortFor,
|
||||
tagsFor, descFor, imagesFor, linksFor, updatesFor, lastUpdate,
|
||||
compareFor, sortFor,
|
||||
Artist (..), Images' (..), Images, Image (..), Desc (..), DescField (..),
|
||||
Link (..), Update (..), Bg (..),
|
||||
GalleryInfo (..), GalleryFilters (..), ArtistFilter (..), NsfwFilter (..),
|
||||
|
@ -219,6 +220,10 @@ linksFor nsfw = if nsfw then #links else #sfwLinks
|
|||
updatesFor :: Bool -> Info -> [(Date, [Update])]
|
||||
updatesFor nsfw = if nsfw then #updates else #sfwUpdates
|
||||
|
||||
lastUpdate :: Bool -> Info -> Maybe Date
|
||||
lastUpdate nsfw info =
|
||||
case updatesFor nsfw info of [] -> Nothing; us -> Just $ fst $ last us
|
||||
|
||||
compareFor :: Bool -> Info -> Info -> Ordering
|
||||
compareFor nsfw = comparing \i -> (#latestDate i nsfw, #sortEx i, #title i)
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ make' root siteName prefix nsfw _dataDir dir
|
|||
<h2 id=date class="right corner">
|
||||
$formattedDate $updateDate
|
||||
</h2>
|
||||
<a class="left corner" href=$undir>back to gallery</a>
|
||||
</header>
|
||||
|
||||
$2.buttonBar
|
||||
|
@ -180,10 +181,6 @@ make' root siteName prefix nsfw _dataDir dir
|
|||
$6.tagsList
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<a href=$undir>back to gallery</a>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<template id=cw-template>
|
||||
|
|
|
@ -130,7 +130,7 @@ function sortFilters(cmp) {
|
|||
sort1('exclude');
|
||||
}
|
||||
|
||||
function sortFiltersAlpha() {
|
||||
function sortFiltersAlpha(e) {
|
||||
function getName(x) {
|
||||
if (x.nodeType == Node.ELEMENT_NODE) {
|
||||
return x.getElementsByTagName('input')[0].value;
|
||||
|
@ -139,9 +139,10 @@ function sortFiltersAlpha() {
|
|||
}
|
||||
}
|
||||
sortFilters((a, b) => getName(a).localeCompare(getName(b)));
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function sortFiltersUses() {
|
||||
function sortFiltersUses(e) {
|
||||
function getUses(x) {
|
||||
if (x.nodeType == Node.ELEMENT_NODE) {
|
||||
return parseInt(x.getElementsByTagName('label')[0].dataset.count);
|
||||
|
@ -150,6 +151,7 @@ function sortFiltersUses() {
|
|||
}
|
||||
}
|
||||
sortFilters((a, b) => getUses(b) - getUses(a));
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
|
||||
|
@ -160,8 +162,8 @@ function setup() {
|
|||
}
|
||||
|
||||
let items = Array.from(document.getElementsByClassName('post'));
|
||||
itemsByYear = new Map;
|
||||
|
||||
itemsByYear = new Map;
|
||||
for (let item of items) {
|
||||
let year = item.dataset.year;
|
||||
if (!itemsByYear.has(year)) itemsByYear.set(year, new Set);
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
--text-col: white;
|
||||
--text-shadow-col: hsl(0, 0%, 0%, 75%);
|
||||
--text-shadow: 2px 2px 3px var(--text-shadow-col);
|
||||
--nsfw-sticker-rotate: 15deg;
|
||||
|
||||
--focus-box: 0 0 5px hsl(55deg, 60%, 90%, 80%);
|
||||
--focus-text: hsl(334deg, 87%, 90%);
|
||||
|
@ -53,6 +52,8 @@
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
body { margin: 0; }
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -65,12 +66,10 @@ h3 { font-size: 110%; }
|
|||
|
||||
.page {
|
||||
background: var(--background);
|
||||
border: var(--border);
|
||||
position: relative;
|
||||
|
||||
padding: 2em 4em;
|
||||
margin: 3em auto 3.5em;
|
||||
border-radius: var(--border-radius);
|
||||
margin: 0 auto;
|
||||
|
||||
color: var(--text-col);
|
||||
text-shadow: var(--text-shadow);
|
||||
|
@ -112,7 +111,7 @@ figure > img {
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
top: 0.5em;
|
||||
top: 1em;
|
||||
|
||||
font-size: 100%;
|
||||
font-weight: 500;
|
||||
|
|
|
@ -3,13 +3,18 @@
|
|||
|
||||
:root {
|
||||
--image-size: 200px;
|
||||
--gap: 1em;
|
||||
--badge-size: calc(1/4 * var(--image-size));
|
||||
--gap: 0em;
|
||||
}
|
||||
|
||||
@media (min-width: 1000px) {
|
||||
.page { max-width: 80%; }
|
||||
}
|
||||
|
||||
.page {
|
||||
padding: 2em calc(1/4 * var(--image-size));
|
||||
}
|
||||
|
||||
#filters {
|
||||
margin: 1em 0 2em 0;
|
||||
}
|
||||
|
@ -33,7 +38,6 @@
|
|||
.filterlist {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
/* justify-content: space-between; */
|
||||
padding: 0;
|
||||
|
||||
font-weight: 500;
|
||||
|
@ -54,10 +58,7 @@
|
|||
}
|
||||
|
||||
.filterlist label {
|
||||
padding: 0.15em 0.4em;
|
||||
border-radius: var(--button-radius);
|
||||
background: var(--button-bg);
|
||||
border: var(--button-border);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.filterlist label::before {
|
||||
|
@ -154,35 +155,18 @@
|
|||
|
||||
.item:not(.year-marker) {
|
||||
box-shadow: var(--text-shadow);
|
||||
border: var(--border-thickness) solid var(--border-col);
|
||||
border-radius: 0.5em;
|
||||
background: hsl(340, 45%, 65%);
|
||||
outline: var(--border-thickness) solid var(--border-col);
|
||||
background: hsl(0, 0%, 0%, 50%);
|
||||
clip-path: polygon(5% 0, 95% 10%, 95% 100%, 5% 90%);
|
||||
}
|
||||
.item img {
|
||||
clip-path: polygon(7% 2%, 93% 12%, 93% 98%, 7% 88%);
|
||||
}
|
||||
|
||||
.item:focus-within {
|
||||
box-shadow: var(--focus-box);
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
figcaption .date, figcaption .title {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
border: 1px solid var(--border-col);
|
||||
display: block;
|
||||
text-align: center;
|
||||
background: hsl(0, 0%, 0%, 75%);
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
figcaption .date { top: -1px; left: -1px; }
|
||||
figcaption .title { bottom: -1px; left: -1px; }
|
||||
|
||||
.date { text-transform: lowercase; }
|
||||
|
||||
.year-marker {
|
||||
/* uncomment to reenable line breaks before year markers */
|
||||
/* grid-area: auto / 1; */
|
||||
|
@ -210,9 +194,8 @@ figcaption .title { bottom: -1px; left: -1px; }
|
|||
}
|
||||
|
||||
.item.nsfw::before, .item[data-updated="true"]::after {
|
||||
height: var(--size);
|
||||
width: var(--size);
|
||||
transform: var(--base-transform);
|
||||
height: var(--badge-size);
|
||||
width: var(--badge-size);
|
||||
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
|
@ -221,19 +204,18 @@ figcaption .title { bottom: -1px; left: -1px; }
|
|||
}
|
||||
|
||||
.item.nsfw::before {
|
||||
--size: calc(1/4 * var(--image-size));
|
||||
--base-transform: rotate(var(--nsfw-sticker-rotate));
|
||||
transform: rotate(15deg);
|
||||
content: url(../18_plus_white.svg);
|
||||
top: calc(1em + 3px);
|
||||
right: 3px;
|
||||
top: 11%;
|
||||
right: 7%;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.item[data-updated="true"]::after {
|
||||
--size: calc(1/4 * var(--image-size));
|
||||
--base-transform: rotate(-8deg);
|
||||
transform: rotate(-8deg);
|
||||
content: url(../sparkles.svg);
|
||||
bottom: calc(1em + 3px);
|
||||
right: 3px;
|
||||
bottom: 4%;
|
||||
right: 7%;
|
||||
}
|
||||
|
||||
footer {
|
||||
|
@ -242,68 +224,6 @@ footer {
|
|||
margin-top: 1em;
|
||||
}
|
||||
|
||||
|
||||
@media (hover) and (pointer: fine) {
|
||||
.item:hover .date, .item:hover .title,
|
||||
.item:hover::before, .item:hover::after {
|
||||
filter: opacity(20%);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
figcaption .date, figcaption .title, .item::before, .item::after {
|
||||
transition-property: filter, transform;
|
||||
transition-duration: 0.15s;
|
||||
transition-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
.item:hover .title {
|
||||
transform: translate(-20%, 80%) rotateZ(7deg);
|
||||
}
|
||||
|
||||
.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) var(--base-transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (not hover), (pointer: coarse) {
|
||||
.item:not(.year-marker) {
|
||||
height: min-content;
|
||||
}
|
||||
|
||||
figcaption .date, figcaption .title {
|
||||
position: initial;
|
||||
}
|
||||
|
||||
figcaption .date {
|
||||
border-bottom: none;
|
||||
}
|
||||
figcaption .title {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
figcaption .date::after {
|
||||
content: ':';
|
||||
}
|
||||
|
||||
.item a {
|
||||
display: block;
|
||||
height: var(--image-size);
|
||||
}
|
||||
|
||||
.item img {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (pointer: coarse) {
|
||||
#filters label {
|
||||
font-size: 150%;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
.page {
|
||||
width: 37.5em;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
#title::before, #title::after {
|
||||
|
@ -30,12 +31,11 @@
|
|||
}
|
||||
|
||||
|
||||
@media screen {
|
||||
@media not speech {
|
||||
.nsfw::after {
|
||||
content: url(../18_plus_white.svg);
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
transform: rotate(var(--nsfw-sticker-rotate));
|
||||
mix-blend-mode: hard-light;
|
||||
margin-left: 0.3em;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@
|
|||
|
||||
@media speech {
|
||||
.nsfw::after {
|
||||
content: ' (some nsfw)';
|
||||
content: ' (contains adult content)';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
position: relative;
|
||||
overflow: hidden;
|
||||
border: var(--border-thickness) solid var(--border-col);
|
||||
border-radius: 1em;
|
||||
box-shadow: var(--text-shadow);
|
||||
background: hsl(340, 45%, 65%);
|
||||
}
|
||||
|
@ -76,20 +75,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
.nsfw-label::after {
|
||||
content: url(../18_plus_white.svg);
|
||||
display: inline-block;
|
||||
height: 0.9em; width: 0.9em;
|
||||
vertical-align: -0.07em;
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
|
||||
:checked ~ .nsfw-label::after {
|
||||
content: url(../18_plus.svg);
|
||||
}
|
||||
*/
|
||||
|
||||
#date { text-transform: lowercase; }
|
||||
|
||||
#info {
|
||||
|
@ -104,9 +89,6 @@
|
|||
align-items: baseline;
|
||||
}
|
||||
|
||||
/* 'display: contents' removes things from the accessibility tree
|
||||
* which is probably only a problem for screen readers?
|
||||
*/
|
||||
@media not speech {
|
||||
.info-section {
|
||||
display: contents;
|
||||
|
|
Loading…
Reference in a new issue