Compare commits

..

No commits in common. "387618038a2a79fef3e433a5c08c61a0acff505c" and "45e0de758a9ecb4060c3d58840d1083f65c8eddd" have entirely different histories.

11 changed files with 40 additions and 72 deletions

View file

@ -2,7 +2,7 @@ CABALFLAGS ?= --jobs --enable-optimization
DATADIR := data DATADIR := data
TMPDIR := _tmp TMPDIR := _tmp
BUILDDIR := /srv/www/gallery BUILDDIR := _build
INFONAME := info.yaml INFONAME := info.yaml
ROOT := https://gallery.niss.website ROOT := https://gallery.niss.website
INDEX := $(DATADIR)/index.yaml INDEX := $(DATADIR)/index.yaml
@ -115,6 +115,7 @@ list-tags: $(MAKEPAGES)
HOST ?= gallery.niss.website HOST ?= gallery.niss.website
REMOTE_USER ?= www-data REMOTE_USER ?= www-data
IDFILE ?= ~/.ssh/xyz
REMOTE_DIR ?= gallery REMOTE_DIR ?= gallery
.PHONY: upload .PHONY: upload
@ -122,7 +123,7 @@ upload: build
@rsync --recursive --partial --progress --copy-links \ @rsync --recursive --partial --progress --copy-links \
--compress --human-readable --hard-links --size-only \ --compress --human-readable --hard-links --size-only \
--delete --delete-after \ --delete --delete-after \
--rsh='ssh -l $(REMOTE_USER)' \ --rsh='ssh -l $(REMOTE_USER) -i $(IDFILE)' \
$(BUILDDIR)/ $(HOST):$(REMOTE_DIR)/ $(BUILDDIR)/ $(HOST):$(REMOTE_DIR)/
@ -141,7 +142,7 @@ endef
define resize define resize
echo "[resize] "$@ echo "[resize] "$@
mkdir -p "$(dir $@)" mkdir -p "$(dir $@)"
magick -define webp:lossless=true "$^" -resize "$(1)x$(2)$(3)" $(4) "$@" convert -resize "$(1)x$(2)$(3)" -define webp:lossless=true $(4) "$^" "$@"
endef endef
# no args # no args

View file

@ -7,7 +7,7 @@ where
import BuilderQQ hiding (CanBuild (..)) import BuilderQQ hiding (CanBuild (..))
import Info hiding (Text) import Info hiding (Text)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe, mapMaybe)
import Data.Text.Lazy (Text) import Data.Text.Lazy (Text)
import Data.Foldable import Data.Foldable
import System.FilePath import System.FilePath
@ -32,6 +32,7 @@ dependSingle' yamlDir indexFile info prefix build nsfw =
maybe [] (toList . allImages) $ maybe [] (toList . allImages) $
if nsfw then Just $ info.images else sfwImages info if nsfw then Just $ info.images else sfwImages info
dls = mapMaybe (.download) images
extras = info.extras extras = info.extras
dir = build </> prefix </> yamlDir dir = build </> prefix </> yamlDir
@ -40,7 +41,7 @@ dependSingle' yamlDir indexFile info prefix build nsfw =
thumbFile (thumbnail info) : thumbFile (thumbnail info) :
map pageFile images ++ map pageFile images ++
map bigFile images ++ map bigFile images ++
extras dls ++ extras
dependGallery :: GalleryInfo dependGallery :: GalleryInfo
-> FilePath -- ^ index file -> FilePath -- ^ index file

View file

@ -296,10 +296,8 @@ pageFile img =
if canResize img then addSuffix "_med" img.path else img.path if canResize img then addSuffix "_med" img.path else img.path
bigFile :: Image -> FilePath bigFile :: Image -> FilePath
bigFile img bigFile img =
| Just path <- img.download = path if canResize img then addSuffix "_big" img.path else img.path
| canResize img = addSuffix "_big" img.path
| otherwise = img.path
addSuffix :: String -> FilePath -> FilePath addSuffix :: String -> FilePath -> FilePath
addSuffix suf path = addSuffix suf path =

View file

@ -10,14 +10,14 @@ let showSingles = false;
function fillSets(): [Set<string>, Set<string>] { function fillSets(): [Set<string>, Set<string>] {
function checkedValues(boxes: Boxes): Set<string> { function checkedValues(boxes: Boxes) {
return new Set([...boxes].filter(b => b.checked).map(b => b.value)); return new Set([...boxes].filter(b => b.checked).map(b => b.value));
} }
return [checkedValues(reqBoxes), checkedValues(excBoxes)]; return [checkedValues(reqBoxes), checkedValues(excBoxes)];
} }
function updateItems(): void { function updateItems() {
const [reqTags, excTags] = fillSets(); const [reqTags, excTags] = fillSets();
const anyReq = reqTags.size > 0; const anyReq = reqTags.size > 0;
@ -37,7 +37,7 @@ function updateItems(): void {
if (marker !== null) marker.hidden = hideMarker; if (marker !== null) marker.hidden = hideMarker;
} }
function disp(pfx: string, tags: Iterable<string>): string { function disp(pfx: string, tags: Iterable<string>) {
return [...tags].map(x => pfx + x).join('\u2003'); // em space return [...tags].map(x => pfx + x).join('\u2003'); // em space
} }
const plus = disp('+\u2009', reqTags); // thin space const plus = disp('+\u2009', reqTags); // thin space
@ -46,12 +46,12 @@ function updateItems(): void {
`${plus}\u2003${minus}`.trim(); `${plus}\u2003${minus}`.trim();
} }
function update(): void { function update() {
updateItems(); updateItems();
history.pushState(null, "", makeFragment()); history.pushState(null, "", makeFragment());
} }
function converseId(id: string): string { function converseId(id: string) {
if (id.match(/^require/)) { if (id.match(/^require/)) {
return id.replace('require', 'exclude'); return id.replace('require', 'exclude');
} else { } else {
@ -59,7 +59,7 @@ function converseId(id: string): string {
} }
} }
function toggle(checkbox: HTMLInputElement): void { function toggle(checkbox: HTMLInputElement) {
if (checkbox.checked) { if (checkbox.checked) {
const converse = document.getElementById(converseId(checkbox.id)) as HTMLInputElement; const converse = document.getElementById(converseId(checkbox.id)) as HTMLInputElement;
converse.checked = false; converse.checked = false;
@ -68,17 +68,17 @@ function toggle(checkbox: HTMLInputElement): void {
} }
function clearForm(): void { function clearForm() {
allBoxes.forEach(b => b.checked = b.defaultChecked); allBoxes.forEach(b => b.checked = b.defaultChecked);
} }
function clear(e: Event): void { function clear(e: Event) {
clearForm(); clearForm();
update(); update();
e.preventDefault(); e.preventDefault();
} }
function toggleSingles(e: Event): void { function toggleSingles(e: Event) {
showSingles = !showSingles; showSingles = !showSingles;
const elems = Array.from(document.querySelectorAll('.filterlist li')) as HTMLElement[]; const elems = Array.from(document.querySelectorAll('.filterlist li')) as HTMLElement[];
@ -94,7 +94,7 @@ function toggleSingles(e: Event): void {
} }
function makeFragment(): string { function makeFragment() {
const allBoxesArr = Array.from(allBoxes); const allBoxesArr = Array.from(allBoxes);
const ids = allBoxesArr.filter(b => b.checked).map(b => b.id); const ids = allBoxesArr.filter(b => b.checked).map(b => b.id);
if (ids.length == 0) { if (ids.length == 0) {
@ -107,7 +107,7 @@ function makeFragment(): string {
} }
type Shortcuts = Record<string, Set<string>>; type Shortcuts = { [short: string]: Set<string> };
const shortcuts: Shortcuts = { const shortcuts: Shortcuts = {
summary: new Set(['require_artsummary']), summary: new Set(['require_artsummary']),
colourexamples: new Set(['require_colourexample']), colourexamples: new Set(['require_colourexample']),
@ -116,26 +116,11 @@ const shortcuts: Shortcuts = {
iconexamples: new Set(['require_iconexample']), iconexamples: new Set(['require_iconexample']),
curated: new Set(['require_curated']), curated: new Set(['require_curated']),
gecs: new Set(['require_niss', 'require_nisse']), gecs: new Set(['require_niss', 'require_nisse']),
niss: new Set(['require_niss']),
nisse: new Set(['require_nisse']),
qt: new Set(['require_q_t_']), qt: new Set(['require_q_t_']),
"q.t.": new Set(['require_q_t_']),
kesi: new Set(['require_kesi']), kesi: new Set(['require_kesi']),
bip: new Set(['require_bip']),
60309: new Set(['require_IEC60309']),
velzek: new Set(['require_velzek']),
pricklypear: new Set(['require_pricklypear']),
prickly_pear: new Set(['require_pricklypear']),
goo: new Set(['require_thegoo']),
the_goo: new Set(['require_thegoo']),
thegoo: new Set(['require_thegoo']),
kiki: new Set(['require_kiki']),
nex: new Set(['require_nex']),
kezda: new Set(['require_kezda']),
marigold: new Set(['require_marigold']),
}; };
function useFragment(): void { function useFragment() {
const frag = decodeURIComponent(location.hash).replace(/^#/, ''); const frag = decodeURIComponent(location.hash).replace(/^#/, '');
const details = document.getElementById('filters-details') as HTMLDetailsElement; const details = document.getElementById('filters-details') as HTMLDetailsElement;
const fromShortcut = shortcuts[frag]; const fromShortcut = shortcuts[frag];
@ -160,8 +145,8 @@ function useFragment(): void {
} }
function sortFilters(cmp: (a: Node, b: Node) => number): void { function sortFilters(cmp: (a: Node, b: Node) => number) {
function sort1(id: string): void { function sort1(id: string) {
const elt = document.getElementById(id); const elt = document.getElementById(id);
if (elt === null) return; if (elt === null) return;
@ -177,7 +162,7 @@ function sortFilters(cmp: (a: Node, b: Node) => number): void {
sort1('exclude'); sort1('exclude');
} }
function sortFiltersAlpha(e: Event): void { function sortFiltersAlpha(e: Event) {
function getName(node: Node): string { function getName(node: Node): string {
if (node instanceof Element) { if (node instanceof Element) {
return node.getElementsByTagName('input')[0]?.value ?? ''; return node.getElementsByTagName('input')[0]?.value ?? '';
@ -189,7 +174,7 @@ function sortFiltersAlpha(e: Event): void {
e.preventDefault(); e.preventDefault();
} }
function sortFiltersUses(e: Event): void { function sortFiltersUses(e: Event) {
function getUses(node: Node): number { function getUses(node: Node): number {
if (node instanceof Element) { if (node instanceof Element) {
const countStr = node.getElementsByTagName('label')[0]?.dataset.count; const countStr = node.getElementsByTagName('label')[0]?.dataset.count;
@ -203,7 +188,7 @@ function sortFiltersUses(e: Event): void {
} }
function setup(): void { function setup() {
function inputs(id: string): Boxes { function inputs(id: string): Boxes {
const iter = document.getElementById(id)!.getElementsByTagName('input'); const iter = document.getElementById(id)!.getElementsByTagName('input');
return new Set(Array.from(iter)); return new Set(Array.from(iter));
@ -231,7 +216,7 @@ function setup(): void {
allBoxes.forEach(b => b.addEventListener('change', () => toggle(b))); allBoxes.forEach(b => b.addEventListener('change', () => toggle(b)));
function addClick(id: string, f: (e: Event) => void): void { function addClick(id: string, f: (e: Event) => void) {
document.getElementById(id)!.addEventListener('click', f); document.getElementById(id)!.addEventListener('click', f);
} }
addClick('clear', clear); addClick('clear', clear);

View file

@ -1,12 +1,12 @@
const nsfwOk = 'nsfw-ok'; const nsfwOk = 'nsfw-ok';
const dialog = document.getElementById('nsfw-dialog')! as HTMLDialogElement; const dialog = document.getElementById('nsfw-dialog')! as HTMLDialogElement;
function yes(): void { function yes() {
localStorage.setItem(nsfwOk, '1'); localStorage.setItem(nsfwOk, '1');
dialog.close(); dialog.close();
} }
function setup(): void { function setup() {
if (!localStorage.getItem(nsfwOk)) { if (!localStorage.getItem(nsfwOk)) {
(dialog.querySelector('#nsfw-yes') as HTMLElement).onclick = yes; (dialog.querySelector('#nsfw-yes') as HTMLElement).onclick = yes;
// nsfw-no is a normal link // nsfw-no is a normal link

View file

@ -28,7 +28,7 @@ function setImage(id: string, src: string, href: string,
if (curCw && !coverNew) { if (curCw && !coverNew) {
// keep old cover until load // keep old cover until load
function removeCover(): void { setTimeout(() => openCW(null, curCw!), 100); } function removeCover() { setTimeout(() => openCW(null, curCw!), 100); }
mainimg.addEventListener('load', removeCover, {once: true}); mainimg.addEventListener('load', removeCover, {once: true});
} else if (coverNew) { } else if (coverNew) {
// place new cover // place new cover
@ -82,7 +82,7 @@ function useFragment(firstLoad = false): void {
} }
} }
function setup(): void { function setup() {
mainfig = document.getElementById('mainfig')!; mainfig = document.getElementById('mainfig')!;
mainimg = document.getElementById('mainimg') as HTMLImageElement; mainimg = document.getElementById('mainimg') as HTMLImageElement;
mainlink = document.getElementById('mainlink') as HTMLAnchorElement; mainlink = document.getElementById('mainlink') as HTMLAnchorElement;

View file

@ -203,12 +203,6 @@ summary::after {
summary::after { content: 'show'; } summary::after { content: 'show'; }
[open] summary::after { content: 'hide'; } [open] summary::after { content: 'hide'; }
#filters-details {
summary::after { content: none; }
summary h2::before { content: 'show '; }
&[open] summary h2::before { content: 'hide '; }
}
dt { dt {
font-size: 120%; font-size: 120%;

View file

@ -43,7 +43,6 @@
font-weight: 500; font-weight: 500;
font-size: 90%; font-size: 90%;
grid-column-gap: 0.5em; grid-column-gap: 0.5em;
grid-row-gap: 0.3em;
} }
.filterlist input { .filterlist input {

View file

@ -88,14 +88,6 @@ main {
margin: 2em 0; margin: 2em 0;
} }
footer {
text-align: center;
}
footer a {
text-decoration: none;
font-weight: 700;
}
@media (pointer: coarse) { @media (pointer: coarse) {
.list { .list {
font-size: 300%; font-size: 300%;

View file

@ -13,10 +13,9 @@
linear-gradient(105deg, linear-gradient(105deg,
var(--type-col) 0, var(--type-col) 0,
var(--type-col) var(--offset), var(--type-col) var(--offset),
#5d4e5d var(--offset) #5d4e5d calc(var(--offset) + 1px)
); );
--offset: calc(var(--icon-size) * 1.25); --offset: calc(var(--icon-size) * 1.5);
border: 1px solid black;
} }
.pkmn-move::before { .pkmn-move::before {
@ -29,7 +28,7 @@
} }
.pkmn-type + .pkmn-type { .pkmn-type + .pkmn-type {
margin-left: 0.5ex; margin-left: 0.25ex;
} }
.pkmn-species { .pkmn-species {
@ -44,7 +43,6 @@
} }
.pkmn-stats table { .pkmn-stats table {
table-layout: fixed;
width: 80%; width: 80%;
text-align: center; text-align: center;
margin: 0; margin: 0;

View file

@ -24,6 +24,7 @@ body {
overflow: hidden; overflow: hidden;
border: var(--border-thickness) solid var(--border-col); border: var(--border-thickness) solid var(--border-col);
box-shadow: var(--text-shadow); box-shadow: var(--text-shadow);
background: hsl(340, 45%, 65%);
} }
#mainfig:focus-within { #mainfig:focus-within {
@ -109,13 +110,12 @@ body {
#info .floating { #info .floating {
float: right; float: right;
margin: 0.2em 0 0.2em 2em; margin-left: 0.8em;
max-width: 40%; max-width: 40%;
} }
#info .floating.left { #info .floating.left {
float: left; float: left;
margin: 0.2em 2em 0.2em 0;
} }
#info .shaped { #info .shaped {
@ -130,8 +130,9 @@ body {
text-align: right; text-align: right;
} }
#info :is(h2, ul, ol, p, dl, details) { margin: 0.35em 0; } #info h2, #info ul, #info ol, #info p, #info dl, #info details {
#info :is(ul, ol) { padding-left: 1.5ch; } margin: 0.35em 0;
}
#info details > * { #info details > * {
margin-left: 0; margin-left: 0;
@ -140,10 +141,9 @@ body {
#updates dl, dl.inline { #updates dl, dl.inline {
display: grid; display: grid;
grid-template-columns: max-content auto; grid-template-columns: max-content auto;
grid-gap: 1em;
align-items: baseline; align-items: baseline;
} }
dl.inline { gap: .25em 1em; }
#updates dl { gap: 1em; }
:is(#updates, .inline) dt { :is(#updates, .inline) dt {
font-size: 100%; font-size: 100%;