Add "Playing It Safe" draft and improve type-checking
- Remove most type assertions and improve types - Validate wordCount property - Add "Vore Day" tag - Add licenses
This commit is contained in:
parent
17ef8c652c
commit
fe908a4989
37 changed files with 1309 additions and 841 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import rss, { type RSSFeedItem } from "@astrojs/rss";
|
||||
import type { APIRoute } from "astro";
|
||||
import { getCollection, type CollectionEntry } from "astro:content";
|
||||
import { getCollection, getEntries, type CollectionEntry, type CollectionKey } from "astro:content";
|
||||
import { markdown } from "@astropub/md";
|
||||
import sanitizeHtml from "sanitize-html";
|
||||
import { t } from "../i18n";
|
||||
|
|
@ -8,11 +8,12 @@ import type { Lang } from "../content/config";
|
|||
import { markdownToPlaintext } from "../utils/markdown_to_plaintext";
|
||||
import { getUsernameForLang } from "../utils/get_username_for_lang";
|
||||
|
||||
type FeedItem = RSSFeedItem & {
|
||||
pubDate: Date;
|
||||
};
|
||||
type FeedItem = RSSFeedItem &
|
||||
Required<Pick<RSSFeedItem, "title" | "pubDate" | "link" | "description" | "categories" | "content">>;
|
||||
|
||||
const MAX_ITEMS = 8;
|
||||
type EntryWithPubDate<C extends CollectionKey> = CollectionEntry<C> & { data: { pubDate: Date } };
|
||||
|
||||
const MAX_ITEMS = 6;
|
||||
|
||||
function toNoonUTCDate(date: Date) {
|
||||
const adjustedDate = new Date(date);
|
||||
|
|
@ -30,13 +31,19 @@ const getLinkForUser = (user: CollectionEntry<"users">, lang: Lang) => {
|
|||
};
|
||||
|
||||
export const GET: APIRoute = async ({ site }) => {
|
||||
const stories = (await getCollection("stories", (story) => !story.data.isDraft && story.data.pubDate))
|
||||
.sort((a, b) => b.data.pubDate!.getTime() - a.data.pubDate!.getTime())
|
||||
const stories = (
|
||||
(await getCollection(
|
||||
"stories",
|
||||
(story) => !story.data.isDraft && story.data.pubDate,
|
||||
)) as EntryWithPubDate<"stories">[]
|
||||
)
|
||||
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
|
||||
.slice(0, MAX_ITEMS);
|
||||
const games = (await getCollection("games", (game) => !game.data.isDraft && game.data.pubDate))
|
||||
.sort((a, b) => b.data.pubDate!.getTime() - a.data.pubDate!.getTime())
|
||||
const games = (
|
||||
(await getCollection("games", (game) => !game.data.isDraft && game.data.pubDate)) as EntryWithPubDate<"games">[]
|
||||
)
|
||||
.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime())
|
||||
.slice(0, MAX_ITEMS);
|
||||
const users = await getCollection("users");
|
||||
|
||||
return rss({
|
||||
title: "Gallery | Bad Manners",
|
||||
|
|
@ -46,34 +53,38 @@ export const GET: APIRoute = async ({ site }) => {
|
|||
await Promise.all(
|
||||
stories.map<Promise<FeedItem>>(async ({ data, slug, body }) => ({
|
||||
title: `New story! "${data.title}"`,
|
||||
pubDate: toNoonUTCDate(data.pubDate!),
|
||||
pubDate: toNoonUTCDate(data.pubDate),
|
||||
link: `/stories/${slug}`,
|
||||
description:
|
||||
`${t(data.lang, "story/warnings", data.wordCount, data.contentWarning.trim())}\n\n${markdownToPlaintext(data.description)}`
|
||||
.replaceAll(/[\n ]+/g, " ")
|
||||
.trim(),
|
||||
`${t(data.lang, "story/warnings", data.wordCount, data.contentWarning)}\n\n${markdownToPlaintext(data.description)}`.replaceAll(
|
||||
/[\n ]+/g,
|
||||
" ",
|
||||
),
|
||||
categories: ["story"],
|
||||
content: sanitizeHtml(
|
||||
`<h1>${data.title}</h1>` +
|
||||
`<p>${t(
|
||||
data.lang,
|
||||
"story/authors",
|
||||
[data.authors].flatMap((authorArray) => {
|
||||
if (!Array.isArray(authorArray)) {
|
||||
authorArray = [authorArray];
|
||||
}
|
||||
return authorArray.map((author) =>
|
||||
getLinkForUser(users.find((user) => user.id === author.id)!, data.lang),
|
||||
);
|
||||
}),
|
||||
(await getEntries(data.authors)).map((author) => getLinkForUser(author, data.lang)),
|
||||
)}</p>` +
|
||||
(data.requester
|
||||
? `<p>${t(data.lang, "export_story/request_for", getLinkForUser(users.find((user) => user.id === data.requester!.id)!, data.lang))}</p>`
|
||||
? `<p>${t(
|
||||
data.lang,
|
||||
"story/requested_by",
|
||||
(await getEntries(data.requester)).map((requester) => getLinkForUser(requester, data.lang)),
|
||||
)}</p>`
|
||||
: "") +
|
||||
(data.commissioner
|
||||
? `<p>${t(data.lang, "export_story/commissioned_by", getLinkForUser(users.find((user) => user.id === data.commissioner!.id)!, data.lang))}</p>`
|
||||
? `<p>${t(
|
||||
data.lang,
|
||||
"story/commissioned_by",
|
||||
(await getEntries(data.commissioner)).map((commissioner) =>
|
||||
getLinkForUser(commissioner, data.lang),
|
||||
),
|
||||
)}</p>`
|
||||
: "") +
|
||||
`<hr><p><em>${t(data.lang, "story/warnings", data.wordCount || "???", data.contentWarning.trim())}</em></p>` +
|
||||
`<hr><p><em>${t(data.lang, "story/warnings", data.wordCount, data.contentWarning)}</em></p>` +
|
||||
`<hr>${await markdown(body)}` +
|
||||
`<hr>${await markdown(data.description)}`,
|
||||
),
|
||||
|
|
@ -82,29 +93,23 @@ export const GET: APIRoute = async ({ site }) => {
|
|||
await Promise.all(
|
||||
games.map<Promise<FeedItem>>(async ({ data, slug, body }) => ({
|
||||
title: `New game! "${data.title}"`,
|
||||
pubDate: toNoonUTCDate(data.pubDate!),
|
||||
pubDate: toNoonUTCDate(data.pubDate),
|
||||
link: `/games/${slug}`,
|
||||
description:
|
||||
`${t(data.lang, "game/warnings", data.platforms, data.contentWarning)}\n\n${markdownToPlaintext(data.description)}`
|
||||
.replaceAll(/[\n ]+/g, " ")
|
||||
.trim(),
|
||||
`${t(data.lang, "game/warnings", data.platforms, data.contentWarning)}\n\n${markdownToPlaintext(data.description)}`.replaceAll(
|
||||
/[\n ]+/g,
|
||||
" ",
|
||||
),
|
||||
categories: ["game"],
|
||||
content: sanitizeHtml(
|
||||
`<h1>${data.title}</h1>` +
|
||||
`<p>${t(
|
||||
data.lang,
|
||||
"story/authors",
|
||||
[data.authors].flatMap((authorArray) => {
|
||||
if (!Array.isArray(authorArray)) {
|
||||
authorArray = [authorArray];
|
||||
}
|
||||
return authorArray.map((author) =>
|
||||
getLinkForUser(users.find((user) => user.id === author.id)!, data.lang),
|
||||
);
|
||||
}),
|
||||
(await getEntries(data.authors)).map((author) => getLinkForUser(author, data.lang)),
|
||||
)}</p>` +
|
||||
`<hr><p>${t(data.lang, "game/platforms", data.platforms)}</p>` +
|
||||
`<hr><p><em>${data.contentWarning.trim()}</em></p>` +
|
||||
`<hr><p><em>${data.contentWarning}</em></p>` +
|
||||
`<hr>${await markdown(body)}` +
|
||||
`<hr>${await markdown(data.description)}`,
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue