diff --git a/Makefile b/Makefile index 0413614..b660248 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CABALFLAGS ?= --jobs --enable-optimization DATADIR := data TMPDIR := _tmp -BUILDDIR := _build +BUILDDIR := /srv/www/gallery INFONAME := info.yaml ROOT := https://gallery.niss.website INDEX := $(DATADIR)/index.yaml @@ -115,7 +115,6 @@ list-tags: $(MAKEPAGES) HOST ?= gallery.niss.website REMOTE_USER ?= www-data -IDFILE ?= ~/.ssh/xyz REMOTE_DIR ?= gallery .PHONY: upload @@ -123,7 +122,7 @@ upload: build @rsync --recursive --partial --progress --copy-links \ --compress --human-readable --hard-links --size-only \ --delete --delete-after \ - --rsh='ssh -l $(REMOTE_USER) -i $(IDFILE)' \ + --rsh='ssh -l $(REMOTE_USER)' \ $(BUILDDIR)/ $(HOST):$(REMOTE_DIR)/ @@ -142,7 +141,7 @@ endef define resize echo "[resize] "$@ mkdir -p "$(dir $@)" -convert -resize "$(1)x$(2)$(3)" -define webp:lossless=true $(4) "$^" "$@" +magick -define webp:lossless=true "$^" -resize "$(1)x$(2)$(3)" $(4) "$@" endef # no args diff --git a/make-pages/Depend.hs b/make-pages/Depend.hs index 0869e01..b9f439d 100644 --- a/make-pages/Depend.hs +++ b/make-pages/Depend.hs @@ -7,7 +7,7 @@ where import BuilderQQ hiding (CanBuild (..)) import Info hiding (Text) -import Data.Maybe (fromMaybe, mapMaybe) +import Data.Maybe (fromMaybe) import Data.Text.Lazy (Text) import Data.Foldable import System.FilePath @@ -32,7 +32,6 @@ dependSingle' yamlDir indexFile info prefix build nsfw = maybe [] (toList . allImages) $ if nsfw then Just $ info.images else sfwImages info - dls = mapMaybe (.download) images extras = info.extras dir = build prefix yamlDir @@ -41,7 +40,7 @@ dependSingle' yamlDir indexFile info prefix build nsfw = thumbFile (thumbnail info) : map pageFile images ++ map bigFile images ++ - dls ++ extras + extras dependGallery :: GalleryInfo -> FilePath -- ^ index file diff --git a/make-pages/Info.hs b/make-pages/Info.hs index 1b0b6fa..124bfd0 100644 --- a/make-pages/Info.hs +++ b/make-pages/Info.hs @@ -296,8 +296,10 @@ pageFile img = if canResize img then addSuffix "_med" img.path else img.path bigFile :: Image -> FilePath -bigFile img = - if canResize img then addSuffix "_big" img.path else img.path +bigFile img + | Just path <- img.download = path + | canResize img = addSuffix "_big" img.path + | otherwise = img.path addSuffix :: String -> FilePath -> FilePath addSuffix suf path = diff --git a/script/gallery.ts b/script/gallery.ts index 738f23b..38d3303 100644 --- a/script/gallery.ts +++ b/script/gallery.ts @@ -10,14 +10,14 @@ let showSingles = false; function fillSets(): [Set, Set] { - function checkedValues(boxes: Boxes) { + function checkedValues(boxes: Boxes): Set { return new Set([...boxes].filter(b => b.checked).map(b => b.value)); } return [checkedValues(reqBoxes), checkedValues(excBoxes)]; } -function updateItems() { +function updateItems(): void { const [reqTags, excTags] = fillSets(); const anyReq = reqTags.size > 0; @@ -37,7 +37,7 @@ function updateItems() { if (marker !== null) marker.hidden = hideMarker; } - function disp(pfx: string, tags: Iterable) { + function disp(pfx: string, tags: Iterable): string { return [...tags].map(x => pfx + x).join('\u2003'); // em space } const plus = disp('+\u2009', reqTags); // thin space @@ -46,12 +46,12 @@ function updateItems() { `${plus}\u2003${minus}`.trim(); } -function update() { +function update(): void { updateItems(); history.pushState(null, "", makeFragment()); } -function converseId(id: string) { +function converseId(id: string): string { if (id.match(/^require/)) { return id.replace('require', 'exclude'); } else { @@ -59,7 +59,7 @@ function converseId(id: string) { } } -function toggle(checkbox: HTMLInputElement) { +function toggle(checkbox: HTMLInputElement): void { if (checkbox.checked) { const converse = document.getElementById(converseId(checkbox.id)) as HTMLInputElement; converse.checked = false; @@ -68,17 +68,17 @@ function toggle(checkbox: HTMLInputElement) { } -function clearForm() { +function clearForm(): void { allBoxes.forEach(b => b.checked = b.defaultChecked); } -function clear(e: Event) { +function clear(e: Event): void { clearForm(); update(); e.preventDefault(); } -function toggleSingles(e: Event) { +function toggleSingles(e: Event): void { showSingles = !showSingles; const elems = Array.from(document.querySelectorAll('.filterlist li')) as HTMLElement[]; @@ -94,7 +94,7 @@ function toggleSingles(e: Event) { } -function makeFragment() { +function makeFragment(): string { const allBoxesArr = Array.from(allBoxes); const ids = allBoxesArr.filter(b => b.checked).map(b => b.id); if (ids.length == 0) { @@ -107,7 +107,7 @@ function makeFragment() { } -type Shortcuts = { [short: string]: Set }; +type Shortcuts = Record>; const shortcuts: Shortcuts = { summary: new Set(['require_artsummary']), colourexamples: new Set(['require_colourexample']), @@ -116,11 +116,26 @@ const shortcuts: Shortcuts = { iconexamples: new Set(['require_iconexample']), curated: new Set(['require_curated']), gecs: new Set(['require_niss', 'require_nisse']), + niss: new Set(['require_niss']), + nisse: new Set(['require_nisse']), qt: new Set(['require_q_t_']), + "q.t.": new Set(['require_q_t_']), 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() { +function useFragment(): void { const frag = decodeURIComponent(location.hash).replace(/^#/, ''); const details = document.getElementById('filters-details') as HTMLDetailsElement; const fromShortcut = shortcuts[frag]; @@ -145,8 +160,8 @@ function useFragment() { } -function sortFilters(cmp: (a: Node, b: Node) => number) { - function sort1(id: string) { +function sortFilters(cmp: (a: Node, b: Node) => number): void { + function sort1(id: string): void { const elt = document.getElementById(id); if (elt === null) return; @@ -162,7 +177,7 @@ function sortFilters(cmp: (a: Node, b: Node) => number) { sort1('exclude'); } -function sortFiltersAlpha(e: Event) { +function sortFiltersAlpha(e: Event): void { function getName(node: Node): string { if (node instanceof Element) { return node.getElementsByTagName('input')[0]?.value ?? ''; @@ -174,7 +189,7 @@ function sortFiltersAlpha(e: Event) { e.preventDefault(); } -function sortFiltersUses(e: Event) { +function sortFiltersUses(e: Event): void { function getUses(node: Node): number { if (node instanceof Element) { const countStr = node.getElementsByTagName('label')[0]?.dataset.count; @@ -188,7 +203,7 @@ function sortFiltersUses(e: Event) { } -function setup() { +function setup(): void { function inputs(id: string): Boxes { const iter = document.getElementById(id)!.getElementsByTagName('input'); return new Set(Array.from(iter)); @@ -216,7 +231,7 @@ function setup() { allBoxes.forEach(b => b.addEventListener('change', () => toggle(b))); - function addClick(id: string, f: (e: Event) => void) { + function addClick(id: string, f: (e: Event) => void): void { document.getElementById(id)!.addEventListener('click', f); } addClick('clear', clear); diff --git a/script/nsfw-warning.ts b/script/nsfw-warning.ts index 5b80e72..d219709 100644 --- a/script/nsfw-warning.ts +++ b/script/nsfw-warning.ts @@ -1,12 +1,12 @@ const nsfwOk = 'nsfw-ok'; const dialog = document.getElementById('nsfw-dialog')! as HTMLDialogElement; -function yes() { +function yes(): void { localStorage.setItem(nsfwOk, '1'); dialog.close(); } -function setup() { +function setup(): void { if (!localStorage.getItem(nsfwOk)) { (dialog.querySelector('#nsfw-yes') as HTMLElement).onclick = yes; // nsfw-no is a normal link diff --git a/script/single.ts b/script/single.ts index 0cd291a..17917e7 100644 --- a/script/single.ts +++ b/script/single.ts @@ -28,7 +28,7 @@ function setImage(id: string, src: string, href: string, if (curCw && !coverNew) { // keep old cover until load - function removeCover() { setTimeout(() => openCW(null, curCw!), 100); } + function removeCover(): void { setTimeout(() => openCW(null, curCw!), 100); } mainimg.addEventListener('load', removeCover, {once: true}); } else if (coverNew) { // place new cover @@ -82,7 +82,7 @@ function useFragment(firstLoad = false): void { } } -function setup() { +function setup(): void { mainfig = document.getElementById('mainfig')!; mainimg = document.getElementById('mainimg') as HTMLImageElement; mainlink = document.getElementById('mainlink') as HTMLAnchorElement; diff --git a/style/shiny/base.css b/style/shiny/base.css index 5a86f34..60f61b7 100644 --- a/style/shiny/base.css +++ b/style/shiny/base.css @@ -203,6 +203,12 @@ summary::after { summary::after { content: 'show'; } [open] summary::after { content: 'hide'; } +#filters-details { + summary::after { content: none; } + summary h2::before { content: 'show '; } + &[open] summary h2::before { content: 'hide '; } +} + dt { font-size: 120%; diff --git a/style/shiny/gallery.css b/style/shiny/gallery.css index 7d52bce..3972c47 100644 --- a/style/shiny/gallery.css +++ b/style/shiny/gallery.css @@ -43,6 +43,7 @@ font-weight: 500; font-size: 90%; grid-column-gap: 0.5em; + grid-row-gap: 0.3em; } .filterlist input { diff --git a/style/shiny/index.css b/style/shiny/index.css index eaba977..5511630 100644 --- a/style/shiny/index.css +++ b/style/shiny/index.css @@ -88,6 +88,14 @@ main { margin: 2em 0; } +footer { + text-align: center; +} +footer a { + text-decoration: none; + font-weight: 700; +} + @media (pointer: coarse) { .list { font-size: 300%; diff --git a/style/shiny/pkmn.css b/style/shiny/pkmn.css index 4dbff04..b0b7ba9 100644 --- a/style/shiny/pkmn.css +++ b/style/shiny/pkmn.css @@ -13,9 +13,10 @@ linear-gradient(105deg, var(--type-col) 0, var(--type-col) var(--offset), - #5d4e5d calc(var(--offset) + 1px) + #5d4e5d var(--offset) ); - --offset: calc(var(--icon-size) * 1.5); + --offset: calc(var(--icon-size) * 1.25); + border: 1px solid black; } .pkmn-move::before { @@ -28,7 +29,7 @@ } .pkmn-type + .pkmn-type { - margin-left: 0.25ex; + margin-left: 0.5ex; } .pkmn-species { @@ -43,6 +44,7 @@ } .pkmn-stats table { + table-layout: fixed; width: 80%; text-align: center; margin: 0; diff --git a/style/shiny/single.css b/style/shiny/single.css index 8454735..d883b3e 100644 --- a/style/shiny/single.css +++ b/style/shiny/single.css @@ -24,7 +24,6 @@ body { overflow: hidden; border: var(--border-thickness) solid var(--border-col); box-shadow: var(--text-shadow); - background: hsl(340, 45%, 65%); } #mainfig:focus-within { @@ -110,12 +109,13 @@ body { #info .floating { float: right; - margin-left: 0.8em; + margin: 0.2em 0 0.2em 2em; max-width: 40%; } #info .floating.left { float: left; + margin: 0.2em 2em 0.2em 0; } #info .shaped { @@ -130,9 +130,8 @@ body { text-align: right; } -#info h2, #info ul, #info ol, #info p, #info dl, #info details { - margin: 0.35em 0; -} +#info :is(h2, ul, ol, p, dl, details) { margin: 0.35em 0; } +#info :is(ul, ol) { padding-left: 1.5ch; } #info details > * { margin-left: 0; @@ -141,9 +140,10 @@ body { #updates dl, dl.inline { display: grid; grid-template-columns: max-content auto; - grid-gap: 1em; align-items: baseline; } +dl.inline { gap: .25em 1em; } +#updates dl { gap: 1em; } :is(#updates, .inline) dt { font-size: 100%;