feat/generator: add RSS feed generation

This commit is contained in:
Kentai Radiquum 2025-02-23 05:36:01 +05:00
parent 0efe83047c
commit f88efb6816
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
8 changed files with 286 additions and 15 deletions

View file

@ -8,6 +8,7 @@ import exec from "child_process";
import Base from "./templates/Base";
import YearPhotos from "./templates/YearPhotos";
import Tags from "./templates/Tags";
import { rss } from "./templates/RSS/RSSBase";
const log = new Log();
@ -57,6 +58,7 @@ export type Years = Record<string, Image[]>;
let tags: string[] = [];
let items: Record<string, Image[]> = {};
let rssItems: Image[] = [];
function addTag(tag: string) {
if (tags.includes(tag)) {
@ -68,7 +70,8 @@ function addTag(tag: string) {
if (
!fs.existsSync("data") ||
!fs.existsSync("data/tags.json") ||
!fs.existsSync("data/items.json")
!fs.existsSync("data/items.json") ||
!fs.existsSync("data/rssItems.json")
) {
log.warn("data/tags.json or data/items.json does not exist");
await db
@ -95,7 +98,23 @@ if (
thumbnail: {
"512": `${ENDPOINT}/${BUCKET}/${path}/${path}-512.${ext}`,
"1024": `${ENDPOINT}/${BUCKET}/${path}/${path}-1024.${ext}`,
"2048": `${ENDPOINT}/${BUCKET}/${path}/${path}-2048.${ext}`
"2048": `${ENDPOINT}/${BUCKET}/${path}/${path}-2048.${ext}`,
},
alt: data.alt,
tags: data.tags,
urls: data.urls,
mimetype: data.mimetype,
width: data.width,
height: data.height,
date: data.date,
});
rssItems.push({
id: doc.id,
image: `${ENDPOINT}/${BUCKET}/${path}/${path}.${ext}`,
thumbnail: {
"512": `${ENDPOINT}/${BUCKET}/${path}/${path}-512.${ext}`,
"1024": `${ENDPOINT}/${BUCKET}/${path}/${path}-1024.${ext}`,
"2048": `${ENDPOINT}/${BUCKET}/${path}/${path}-2048.${ext}`,
},
alt: data.alt,
tags: data.tags,
@ -110,10 +129,12 @@ if (
if (!fs.existsSync("data")) fs.mkdirSync("data");
fs.writeFileSync("data/tags.json", JSON.stringify(tags));
fs.writeFileSync("data/items.json", JSON.stringify(items));
fs.writeFileSync("data/rssItems.json", JSON.stringify(rssItems));
} else {
log.warn("using cached data");
tags = JSON.parse(fs.readFileSync("data/tags.json", "utf-8"));
items = JSON.parse(fs.readFileSync("data/items.json", "utf-8"));
rssItems = JSON.parse(fs.readFileSync("data/rssItems.json", "utf-8"));
}
Object.keys(items).forEach((year) => {
@ -124,7 +145,10 @@ const html = renderToString(
<Base isDev={ENVIRONMENT == "dev"}>
<Tags tags={tags} />
<div className="container mx-auto p-4 flex flex-col gap-4 flex-1">
{Object.keys(items).sort().reverse().map((year) => (
{Object.keys(items)
.sort()
.reverse()
.map((year) => (
<YearPhotos
year={year}
images={items[year]}
@ -161,4 +185,9 @@ if (ENVIRONMENT == "dev") {
);
}
fs.writeFileSync("out/index.html", `<!DOCTYPE html />${html}`);
rssItems.sort((a, b) => b.date - a.date);
rssItems = rssItems.slice(0, 10);
fs.writeFileSync("out/feed.xml", `<?xml version="1.0" encoding="utf-8"?>${rss(rssItems)}`);
log.info("Build finished!");

View file

@ -11,7 +11,7 @@
"chokidar": "^4.0.3",
"express": "^4.21.2",
"firebase-admin": "^13.1.0",
"lightgallery": "^2.8.2",
"jsx-xml": "^0.3.0",
"picocolors": "^1.1.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",
@ -64,6 +64,14 @@
"@js-sdsl/ordered-map": ["@js-sdsl/ordered-map@4.4.2", "", {}, "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="],
"@oozcitak/dom": ["@oozcitak/dom@1.15.10", "", { "dependencies": { "@oozcitak/infra": "1.0.8", "@oozcitak/url": "1.0.4", "@oozcitak/util": "8.3.8" } }, "sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ=="],
"@oozcitak/infra": ["@oozcitak/infra@1.0.8", "", { "dependencies": { "@oozcitak/util": "8.3.8" } }, "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg=="],
"@oozcitak/url": ["@oozcitak/url@1.0.4", "", { "dependencies": { "@oozcitak/infra": "1.0.8", "@oozcitak/util": "8.3.8" } }, "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw=="],
"@oozcitak/util": ["@oozcitak/util@8.3.8", "", {}, "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ=="],
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
"@parcel/watcher": ["@parcel/watcher@2.5.1", "", { "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^7.0.0" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-freebsd-x64": "2.5.1", "@parcel/watcher-linux-arm-glibc": "2.5.1", "@parcel/watcher-linux-arm-musl": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-ia32": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1" } }, "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg=="],
@ -198,6 +206,8 @@
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
"array-flatten": ["array-flatten@1.1.1", "", {}, "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="],
"arrify": ["arrify@2.0.1", "", {}, "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="],
@ -284,6 +294,8 @@
"escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="],
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
"etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
"event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
@ -374,18 +386,20 @@
"jose": ["jose@4.15.9", "", {}, "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA=="],
"js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="],
"json-bigint": ["json-bigint@1.0.0", "", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="],
"jsonwebtoken": ["jsonwebtoken@9.0.2", "", { "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ=="],
"jsx-xml": ["jsx-xml@0.3.0", "", { "dependencies": { "react-is": "^18.3.1", "xmlbuilder2": "^3.1.1" } }, "sha512-KXzxJw7FVURJKZiMOCwxa9oGd9mztLeIeQmUmfvt8lu+t31eRBm26czfz2SPh+0IgklJgt3Cebk96XYJ4y+dMw=="],
"jwa": ["jwa@2.0.0", "", { "dependencies": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA=="],
"jwks-rsa": ["jwks-rsa@3.1.0", "", { "dependencies": { "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.2", "debug": "^4.3.4", "jose": "^4.14.6", "limiter": "^1.1.5", "lru-memoizer": "^2.2.0" } }, "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg=="],
"jws": ["jws@4.0.0", "", { "dependencies": { "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg=="],
"lightgallery": ["lightgallery@2.8.2", "", {}, "sha512-6BV7joQtgdHUhDgNPeGu/RWqcGvmvwbyJpTdB5jgKX5nhU5yGEG3PVaETIlAEEV15Uop+8p+F3PqnokFUlywZA=="],
"lightningcss": ["lightningcss@1.29.1", "", { "dependencies": { "detect-libc": "^1.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.29.1", "lightningcss-darwin-x64": "1.29.1", "lightningcss-freebsd-x64": "1.29.1", "lightningcss-linux-arm-gnueabihf": "1.29.1", "lightningcss-linux-arm64-gnu": "1.29.1", "lightningcss-linux-arm64-musl": "1.29.1", "lightningcss-linux-x64-gnu": "1.29.1", "lightningcss-linux-x64-musl": "1.29.1", "lightningcss-win32-arm64-msvc": "1.29.1", "lightningcss-win32-x64-msvc": "1.29.1" } }, "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.29.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw=="],
@ -498,6 +512,8 @@
"react-dom": ["react-dom@19.0.0", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ=="],
"react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
"readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
@ -530,6 +546,8 @@
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
"sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="],
"statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
"stream-events": ["stream-events@1.0.5", "", { "dependencies": { "stubs": "^3.0.0" } }, "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg=="],
@ -592,6 +610,8 @@
"ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="],
"xmlbuilder2": ["xmlbuilder2@3.1.1", "", { "dependencies": { "@oozcitak/dom": "1.15.10", "@oozcitak/infra": "1.0.8", "@oozcitak/util": "8.3.8", "js-yaml": "3.14.1" } }, "sha512-WCSfbfZnQDdLQLiMdGUQpMxxckeQ4oZNMNhLVkcekTu7xhD4tuUDyAPoY8CwXvBYE6LwBHd6QW2WZXlOWr1vCw=="],
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
"yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],

View file

@ -16,6 +16,7 @@
"chokidar": "^4.0.3",
"express": "^4.21.2",
"firebase-admin": "^13.1.0",
"jsx-xml": "^0.3.0",
"picocolors": "^1.1.1",
"react": "^19.0.0",
"react-dom": "^19.0.0",

View file

@ -527,12 +527,18 @@
.absolute {
position: absolute;
}
.fixed {
position: fixed;
}
.relative {
position: relative;
}
.static {
position: static;
}
.sticky {
position: sticky;
}
.right-0 {
right: calc(var(--spacing) * 0);
}
@ -542,6 +548,9 @@
.left-0 {
left: calc(var(--spacing) * 0);
}
.isolate {
isolation: isolate;
}
.container {
width: 100%;
@media (width >= 40rem) {
@ -560,6 +569,9 @@
max-width: 96rem;
}
}
.m-1 {
margin: calc(var(--spacing) * 1);
}
.mx-auto {
margin-inline: auto;
}
@ -593,6 +605,9 @@
.block {
display: block;
}
.contents {
display: contents;
}
.flex {
display: flex;
}
@ -602,6 +617,9 @@
.hidden {
display: none;
}
.inline {
display: inline;
}
.inline-flex {
display: inline-flex;
}
@ -614,6 +632,9 @@
.aspect-square {
aspect-ratio: 1 / 1;
}
.h-1 {
height: calc(var(--spacing) * 1);
}
.h-16 {
height: calc(var(--spacing) * 16);
}
@ -671,6 +692,9 @@
.overflow-x-auto {
overflow-x: auto;
}
.rounded {
border-radius: 0.25rem;
}
.rounded-lg {
border-radius: var(--radius-lg);
}
@ -726,6 +750,9 @@
.object-cover {
object-fit: cover;
}
.p-1 {
padding: calc(var(--spacing) * 1);
}
.p-2 {
padding: calc(var(--spacing) * 2);
}
@ -766,22 +793,52 @@
.text-white {
color: var(--color-white);
}
.capitalize {
text-transform: capitalize;
}
.lowercase {
text-transform: lowercase;
}
.uppercase {
text-transform: uppercase;
}
.underline {
text-decoration-line: underline;
}
.shadow {
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.outline {
outline-style: var(--tw-outline-style);
outline-width: 1px;
}
.\!filter {
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,) !important;
}
.filter {
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
.backdrop-filter {
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
}
.transition {
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
}
.scrollbar-thumb-gray-700 {
--scrollbar-thumb: oklch(0.373 0.034 259.733);
}
.scrollbar-track-gray-900 {
--scrollbar-track: oklch(0.21 0.034 264.665);
}
.md\:block {
@media (width >= 48rem) {
display: block;
}
}
.md\:flex-row {
@media (width >= 48rem) {
flex-direction: row;
@ -945,6 +1002,61 @@
syntax: "*";
inherits: false;
}
@property --tw-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-shadow-color {
syntax: "*";
inherits: false;
}
@property --tw-inset-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-inset-shadow-color {
syntax: "*";
inherits: false;
}
@property --tw-ring-color {
syntax: "*";
inherits: false;
}
@property --tw-ring-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-inset-ring-color {
syntax: "*";
inherits: false;
}
@property --tw-inset-ring-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-ring-inset {
syntax: "*";
inherits: false;
}
@property --tw-ring-offset-width {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}
@property --tw-ring-offset-color {
syntax: "*";
inherits: false;
initial-value: #fff;
}
@property --tw-ring-offset-shadow {
syntax: "*";
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-outline-style {
syntax: "*";
inherits: false;
@ -990,3 +1102,39 @@
syntax: "*";
inherits: false;
}
@property --tw-backdrop-blur {
syntax: "*";
inherits: false;
}
@property --tw-backdrop-brightness {
syntax: "*";
inherits: false;
}
@property --tw-backdrop-contrast {
syntax: "*";
inherits: false;
}
@property --tw-backdrop-grayscale {
syntax: "*";
inherits: false;
}
@property --tw-backdrop-hue-rotate {
syntax: "*";
inherits: false;
}
@property --tw-backdrop-invert {
syntax: "*";
inherits: false;
}
@property --tw-backdrop-opacity {
syntax: "*";
inherits: false;
}
@property --tw-backdrop-saturate {
syntax: "*";
inherits: false;
}
@property --tw-backdrop-sepia {
syntax: "*";
inherits: false;
}

View file

@ -1,10 +1,29 @@
export default function Header() {
return (
<header className="bg-[#FF478B] text-white w-full rounded-b-lg">
<div className="flex items-center container mx-auto p-4 gap-4">
<div className="flex flex-col md:flex-row md:items-center justify-between container mx-auto p-4 gap-4">
<a href="/" className="flex items-center gap-4">
<img src="https://radiquum.wah.su/static/avatar_512.jpg" alt="" className="w-16 h-16 rounded-lg" />
<h1 className="text-2xl font-bold xl:text-3xl 2xl:text-4xl inter-semibold">KENTAI RADIQUUM</h1>
<img
src="https://radiquum.wah.su/static/avatar_512.jpg"
alt=""
className="w-16 h-16 rounded-lg"
/>
<h1 className="text-2xl font-bold xl:text-3xl 2xl:text-4xl inter-semibold">
KENTAI RADIQUUM
</h1>
</a>
<a href="./feed.xml" className="hidden md:block">
<svg
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 24 24"
>
<path
fill="#ffffff"
d="M5 21q-.825 0-1.412-.587T3 19t.588-1.412T5 17t1.413.588T7 19t-.587 1.413T5 21m12 0q0-2.925-1.1-5.462t-3-4.438t-4.437-3T3 7V4q3.55 0 6.625 1.325t5.4 3.65t3.65 5.4T20 21zm-6 0q0-1.675-.625-3.113T8.65 15.35t-2.537-1.725T3 13v-3q2.3 0 4.288.863t3.487 2.362t2.363 3.488T14 21z"
/>
</svg>
</a>
</div>
</header>

View file

@ -0,0 +1,31 @@
/** @jsxImportSource jsx-xml */
import { render } from "jsx-xml";
import RSSItem from "./RSSItem";
import { type Image } from "../../build";
export const rss = (images: Image[]) => {
return render(
<RSS lastPostDate={images[0].date}>
{images.map((image) => (
<RSSItem Image={image} />
))}
</RSS>
).end({ headless: true });
};
function RSS({ children, lastPostDate }: any) {
return (
<rss version="2.0">
<channel>
<title>Radiquum Photos</title>
<description>Online Gallery of @radiquum</description>
<link>https://radiquum.wah.su/photos/</link>
<language>en-us</language>
<category>Photography</category>
<copyright>CC BY-SA 4.0</copyright>
<lastBuildDate>{new Date().toUTCString()}</lastBuildDate>
<pubDate>{new Date(lastPostDate).toUTCString()}</pubDate>
</channel>
{children}
</rss>
);
}

View file

@ -0,0 +1,22 @@
/** @jsxImportSource jsx-xml */
import { type Image } from "../../build";
interface RSSItemProps {
Image: Image;
}
export default function RSSItem({ Image }: RSSItemProps) {
return (
<item>
<title>{Image.id}</title>
<description>
{Image.alt}{" "}
{`<br> <img src="${Image.thumbnail[1024]}" alt="" width="512"> <br>`}
</description>
<link>{Image.image}</link>
<guid isPermaLink="false">{Image.id}</guid>
<pubDate>{new Date(Image.date).toUTCString()}</pubDate>
</item>
);
}

1
generate/templates/RSS/index.d.ts vendored Normal file
View file

@ -0,0 +1 @@
namespace JSX { interface IntrinsicElements { [elemName: string]: any } }