add more blog styles and fix fic styles
|
@ -1,4 +1,3 @@
|
|||
{
|
||||
"deno.enable": true,
|
||||
"typescript.tsdk": "node_modules/typescript/lib"
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import { defineAction, ActionError } from "astro:actions";
|
||||
import { db, Guestbook } from "astro:db";
|
||||
import { z } from "astro:schema";
|
||||
import { checkProfanity } from "./utils";
|
||||
|
||||
export const server = {
|
||||
guestbook: defineAction({
|
||||
|
@ -10,7 +9,7 @@ export const server = {
|
|||
username: z.string(),
|
||||
website: z.string().url().optional(),
|
||||
body: z.string(),
|
||||
honeypot: z.string().max(0).nullish(),
|
||||
password: z.string().regex(/\biliad/g),
|
||||
}),
|
||||
handler: async (input) => {
|
||||
if (input.username === "") {
|
||||
|
@ -27,26 +26,18 @@ export const server = {
|
|||
});
|
||||
}
|
||||
|
||||
if (input.honeypot !== undefined) {
|
||||
if (input.password !== "iliad") {
|
||||
throw new ActionError({
|
||||
code: "UNPROCESSABLE_CONTENT",
|
||||
message: "Oh dear, something went wrong!",
|
||||
message: "Whoops, something went wrong!",
|
||||
});
|
||||
}
|
||||
|
||||
const filter = await checkProfanity(input.body);
|
||||
if (filter) {
|
||||
return await db.insert(Guestbook).values({
|
||||
username: input.username,
|
||||
website: input.website,
|
||||
body: input.body,
|
||||
}).returning();
|
||||
} else {
|
||||
throw new ActionError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "You can't curse!",
|
||||
});
|
||||
}
|
||||
return await db.insert(Guestbook).values({
|
||||
username: input.username,
|
||||
website: input.website,
|
||||
body: input.body,
|
||||
}).returning();
|
||||
},
|
||||
}),
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
export async function checkProfanity(message: string) {
|
||||
try {
|
||||
const response = await fetch("https://vector.profanity.dev", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ message }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`There was an error checking your message: ${response.status}`);
|
||||
}
|
||||
|
||||
const json = await response.json();
|
||||
|
||||
if (json.isProfanity) {
|
||||
throw new Error("Please don't cuss!");
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function checkSpam(form: FormData) {
|
||||
const token = form.append("procaptcha-response", import.meta.env.SPAM_SITE_KEY);
|
||||
|
||||
}
|
Before Width: | Height: | Size: 585 B After Width: | Height: | Size: 429 B |
Before Width: | Height: | Size: 532 B |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 349 B |
Before Width: | Height: | Size: 865 B After Width: | Height: | Size: 330 B |
After Width: | Height: | Size: 310 B |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 945 B |
Before Width: | Height: | Size: 916 B After Width: | Height: | Size: 313 B |
Before Width: | Height: | Size: 790 B |
Before Width: | Height: | Size: 785 B |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 948 B After Width: | Height: | Size: 336 B |
Before Width: | Height: | Size: 541 B After Width: | Height: | Size: 319 B |
Before Width: | Height: | Size: 825 B |
Before Width: | Height: | Size: 853 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 559 B |
Before Width: | Height: | Size: 544 B |
Before Width: | Height: | Size: 796 B |
Before Width: | Height: | Size: 831 B |
Before Width: | Height: | Size: 879 B |
Before Width: | Height: | Size: 840 B |
Before Width: | Height: | Size: 848 B |
Before Width: | Height: | Size: 839 B |
Before Width: | Height: | Size: 557 B After Width: | Height: | Size: 306 B |
Before Width: | Height: | Size: 877 B |
Before Width: | Height: | Size: 866 B |
Before Width: | Height: | Size: 826 B After Width: | Height: | Size: 302 B |
Before Width: | Height: | Size: 871 B |
Before Width: | Height: | Size: 847 B |
Before Width: | Height: | Size: 802 B |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 560 B After Width: | Height: | Size: 297 B |
Before Width: | Height: | Size: 868 B After Width: | Height: | Size: 331 B |
|
@ -10,6 +10,8 @@
|
|||
--sans-font: "MLSS", 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
|
||||
--arial-font: "Arial Pixel", Arial, Helvetica, sans-serif;
|
||||
--pmd-font: "Wonder Mail", Inter, Roboto, 'Helvetica Neue', 'Arial Nova', 'Nimbus Sans', Arial, sans-serif;
|
||||
--mplus-10-font: "PixelMPlus 10", "MS Gothic", system-ui-ja, system-ui-zh-cn, system-ui-zh-tw, system-ui-zh-hk, system-ui-ko, sans-serif;
|
||||
--mplus-12-font: "PixelMPlus 12", "MS Gothic", system-ui-ja, system-ui-zh-cn, system-ui-zh-tw, system-ui-zh-hk, system-ui-ko, sans-serif;
|
||||
|
||||
@media screen and (prefers-color-scheme: light) {
|
||||
--bg-color: #e6f2ef;
|
||||
|
|
|
@ -28,6 +28,30 @@
|
|||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "PixelMPlus 10";
|
||||
src: url("/fonts/PixelMplus10-Regular.woff2") format("woff");
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "PixelMPlus 10";
|
||||
src: url("/fonts/PixelMplus10-Bold.woff2") format("woff");
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "PixelMPlus 12";
|
||||
src: url("/fonts/PixelMplus12-Regular.woff2") format("woff");
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "PixelMPlus 12";
|
||||
src: url("/fonts/PixelMplus12-Bold.woff2") format("woff");
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Redaction 35";
|
||||
src: url("/fonts/Redaction_35-Regular.woff2") format("woff2");
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
import { defineCollection, z } from "astro:content";
|
||||
import { glob } from "astro/loaders";
|
||||
import { rssSchema } from "@astrojs/rss";
|
||||
import MarkdownIt from "markdown-it";
|
||||
import moods from "@/utils/moods";
|
||||
const parser = new MarkdownIt({
|
||||
html: true,
|
||||
breaks: true,
|
||||
});
|
||||
|
||||
const blog = defineCollection({
|
||||
loader: glob({ pattern: "*.md", base: "./src/content/blog" }),
|
||||
|
@ -16,32 +21,32 @@ const blog = defineCollection({
|
|||
}),
|
||||
});
|
||||
|
||||
function generateFicSlug({ entry, data }: { entry: string, data: any }): string {
|
||||
if (data.slug) {
|
||||
return data.slug as string;
|
||||
}
|
||||
return entry.split("/")[0];
|
||||
}
|
||||
|
||||
const source = "./src/content/fics";
|
||||
const chapters = defineCollection({
|
||||
loader: glob({ pattern: "**/*.{md,mdx,mdoc}", base: source }),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
publishedAt: z.coerce.date(),
|
||||
notes: z.ostring(),
|
||||
notes: z.ostring().transform(notes => parser.renderInline(notes ?? "", {})),
|
||||
lastModified: z.coerce.date().optional(),
|
||||
sortOrder: z.number(),
|
||||
}),
|
||||
});
|
||||
|
||||
const fics = defineCollection({
|
||||
loader: glob({ pattern: "**/*.{yml,yaml}", base: source, generateId: generateFicSlug }),
|
||||
loader: glob({
|
||||
pattern: "**/*.{yml,yaml}",
|
||||
base: source,
|
||||
generateId: ({entry, data}) => {
|
||||
if (data.slug) return data.slug as string;
|
||||
return entry.split("/")[0];
|
||||
}
|
||||
}),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
series: z.array(z.string()),
|
||||
publishedAt: z.coerce.date(),
|
||||
summary: z.string(),
|
||||
summary: z.string().transform(summary => parser.renderInline(summary, {})),
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ title: not a sin
|
|||
publishedAt: 2024-02-01
|
||||
sortOrder: 1
|
||||
notes:
|
||||
hello is this is a <em>test</em>, this is going to be a really long text! this is where all the author's notes will go.
|
||||
hello is this is a *test*, this is going to be a really long text! this is where all the author's notes will go.
|
||||
|
||||
fhi
|
||||
---
|
||||
|
|
|
@ -3,8 +3,9 @@ title: this IS a sin
|
|||
publishedAt: 2024-03-02
|
||||
sortOrder: 2
|
||||
notes:
|
||||
<p>hey there this is just a test </p>
|
||||
<p>him!!! <em>lol!!!</em></p>
|
||||
hey there this is just a test
|
||||
|
||||
him!!! *lol!!!*
|
||||
---
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis **reprehenderit** provident ullam sint *explicabo* quas esse velit, voluptatum eveniet, tempora illum expedita, eum voluptate! Odio excepturi similique ex quos tenetur.
|
||||
|
||||
|
|
|
@ -81,30 +81,32 @@ dayjs.extend(utc);
|
|||
|
||||
{currently && (
|
||||
<aside>
|
||||
<h2>Current</h2>
|
||||
{currently?.mood && (
|
||||
<dl>
|
||||
<dt>Current mood</dt>
|
||||
<dd>
|
||||
<Image src={`/src/assets/moods/${moods.find(mood => mood === currently?.mood)}.png`} width="32" height="32" alt={currently.mood} />
|
||||
</dd>
|
||||
<dt class="title">Mood</dt>
|
||||
<dd class="desc">
|
||||
<Image src={`/src/assets/moods/${moods.find(mood => mood === currently?.mood)}.png`} width={36} height={36} alt="" />
|
||||
{currently.mood}
|
||||
</dd>
|
||||
</dl>
|
||||
)}
|
||||
{currently.playing && (
|
||||
<dl>
|
||||
<dt>Currently playing</dt>
|
||||
<dd>{currently.playing}</dd>
|
||||
<dt class="title">Game</dt>
|
||||
<dd class="desc">{currently.playing}</dd>
|
||||
</dl>
|
||||
)}
|
||||
{currently.watching && (
|
||||
<dl>
|
||||
<dt>Currently watching</dt>
|
||||
<dd>{currently.watching}</dd>
|
||||
<dt class="title">Show</dt>
|
||||
<dd class="desc">{currently.watching}</dd>
|
||||
</dl>
|
||||
)}
|
||||
{currently.reading && (
|
||||
<dl>
|
||||
<dt>Currently reading</dt>
|
||||
<dd>{currently.reading}</dd>
|
||||
<dt class="title">Book</dt>
|
||||
<dd class="desc">{currently.reading}</dd>
|
||||
</dl>
|
||||
)}
|
||||
{currently.listening && (
|
||||
|
@ -135,13 +137,18 @@ dayjs.extend(utc);
|
|||
--bg-7: #ccddee;
|
||||
--bg-8: #8888bb;
|
||||
--border-0: #000;
|
||||
--border-1: #6699aa;
|
||||
--border-2: #7799bb;
|
||||
--border-3: #88aabb;
|
||||
--border-4: #99bbcc;
|
||||
--border-5: #bbccdd;
|
||||
--border-1: #334466;
|
||||
--border-2: #6699aa;
|
||||
--border-3: #7799bb;
|
||||
--border-4: #88aabb;
|
||||
--border-5: #99bbcc;
|
||||
--border-6: #bbccdd;
|
||||
}
|
||||
h1 { font: bold 1rem var(--arial-font); }
|
||||
h2 {
|
||||
font: normal 1.5rem var(--mplus-12-font);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
main {
|
||||
font: 1rem var(--arial-font);
|
||||
display: grid;
|
||||
|
@ -172,17 +179,19 @@ dayjs.extend(utc);
|
|||
background-color: var(--bg-3);
|
||||
padding: 2px;
|
||||
margin: 18px 6px;
|
||||
border: 2px solid var(--border-5);
|
||||
border: 2px solid var(--border-6);
|
||||
}
|
||||
|
||||
h1 {
|
||||
padding: 6px 2px;
|
||||
border-block: 2px solid var(--border-2);
|
||||
border-block: 2px solid var(--border-3);
|
||||
|
||||
.title {
|
||||
display: inline-block;
|
||||
background-color: var(--bg-8);
|
||||
color: var(--bg-0);
|
||||
font-weight: normal;
|
||||
text-transform: uppercase;
|
||||
padding: 5px 2px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
|
@ -200,6 +209,8 @@ dayjs.extend(utc);
|
|||
border-bottom: 2px solid var(--bg-4);
|
||||
|
||||
.item {
|
||||
font-family: var(--mplus-10-font);
|
||||
font-size: 1.254rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
@ -219,7 +230,7 @@ dayjs.extend(utc);
|
|||
|
||||
&:hover {
|
||||
a { background-color: var(--bg-7); }
|
||||
time { background-color: var(--border-5); }
|
||||
time { background-color: var(--border-6); }
|
||||
}
|
||||
}
|
||||
&:last-child { border: none; }
|
||||
|
@ -232,7 +243,7 @@ dayjs.extend(utc);
|
|||
|
||||
&:first-child { margin-top: 4px; }
|
||||
&:last-child {
|
||||
border-bottom: 2px solid var(--border-1);
|
||||
border-bottom: 2px solid var(--border-2);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
@ -251,13 +262,25 @@ dayjs.extend(utc);
|
|||
padding: 36px 16px 74px 20px;
|
||||
|
||||
.inner {
|
||||
border: 2px solid var(--border-1);
|
||||
border: 2px solid var(--border-2);
|
||||
border-image: var(--innerBorder) 3 2 2 fill / 6px 4px 4px;
|
||||
margin: 14px 4px 8px;
|
||||
padding: 4px 2px 2px;
|
||||
background-color: var(--bg-0);
|
||||
}
|
||||
|
||||
.title {
|
||||
font: normal 1.5rem var(--mplus-12-font);
|
||||
background-color: var(--bg-2);
|
||||
padding: 2px 6px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
background-color: var(--bg-4);
|
||||
padding: 4px 6px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
header {
|
||||
border-bottom: 2px solid var(--bg-6);
|
||||
|
||||
|
@ -265,39 +288,26 @@ dayjs.extend(utc);
|
|||
text-align: center;
|
||||
margin: 6px 2px;
|
||||
padding: 2px 0;
|
||||
background-color: var(--border-5);
|
||||
background-color: var(--border-6);
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 2px;
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
border-top-color: var(--bg-2);
|
||||
border-right-color: var(--bg-2);
|
||||
border-left-color: var(--bg-1);
|
||||
border-bottom-color: var(--bg-1);
|
||||
border-color: var(--bg-2) var(--bg-2) var(--bg-1) var(--bg-1);
|
||||
padding: 2px 4px;
|
||||
|
||||
time, .section {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
background-color: var(--bg-2);
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
background-color: var(--bg-4);
|
||||
padding: 4px 6px;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
background-color: var(--border-4);
|
||||
background-color: var(--border-5);
|
||||
border: none;
|
||||
height: 2px;
|
||||
}
|
||||
|
@ -328,27 +338,39 @@ dayjs.extend(utc);
|
|||
}
|
||||
|
||||
aside {
|
||||
border-top: 2px solid var(--border-3);
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
grid-template-rows: repeat(4, auto);
|
||||
border-top: 2px solid var(--border-4);
|
||||
|
||||
h2 {
|
||||
display: grid;
|
||||
place-content: center;
|
||||
grid-area: 1 / 1 / -1;
|
||||
padding-top: -2px;
|
||||
padding-left: 2px;
|
||||
height: 100%;
|
||||
border-top: 2px solid var(--border-1);
|
||||
border-right: 2px solid var(--border-4);
|
||||
background-color: var(--bg-7);
|
||||
}
|
||||
|
||||
dl {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2px 6px;
|
||||
border-bottom: 2px solid var(--border-3);
|
||||
border-bottom: 2px solid var(--border-4);
|
||||
border-top: 2px solid var(--border-1);
|
||||
border-left: 2px solid var(--border-1);
|
||||
|
||||
dt {
|
||||
background-color: var(--bg-2);
|
||||
padding: 4px 6px;
|
||||
&:first-of-type > dd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin: -2px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
dd {
|
||||
background-color: var(--bg-4);
|
||||
padding: 4px 6px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&:first-child > dt ~ dd { padding: 0 6px; }
|
||||
&:last-child { border: none; }
|
||||
&:last-child { border-bottom: none; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ interface Props {
|
|||
title: string;
|
||||
ficTitle: string;
|
||||
date: Date;
|
||||
notes?: string;
|
||||
notes?: any;
|
||||
lastModified?: Date;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ dayjs.extend(utc);
|
|||
)}
|
||||
{notes && (
|
||||
<blockquote>
|
||||
<Fragment set:html={notes.split("\n").join("<br />")} />
|
||||
<Fragment set:html={notes} />
|
||||
</blockquote>
|
||||
)}
|
||||
</header>
|
||||
|
|
|
@ -38,7 +38,7 @@ dayjs.extend(utc);
|
|||
<div>
|
||||
<span class="title">Summary</span>
|
||||
<blockquote class="data">
|
||||
<Fragment set:html={fic.data.summary.split("\n").join("<br />")} />
|
||||
<Fragment set:html={fic.data.summary} />
|
||||
</blockquote>
|
||||
</div>
|
||||
<div class="links">
|
||||
|
|
|
@ -14,7 +14,9 @@ export const GET: APIRoute = async (context) => {
|
|||
const fic = fics.find(({ id }) => id === context.params.ficId);
|
||||
return rss({
|
||||
title: `${fic?.data.title}`,
|
||||
description: `${fic?.data.summary}`,
|
||||
description: sanitize(parser.render(fic?.data.summary!), {
|
||||
allowedTags: sanitize.defaults.allowedTags.concat(["br"]),
|
||||
}),
|
||||
site: context.site!,
|
||||
items: chapters.map(chapter => ({
|
||||
link: `/fics/${chapter.id}`,
|
||||
|
@ -23,7 +25,7 @@ export const GET: APIRoute = async (context) => {
|
|||
content: sanitize(parser.render(chapter.body!), {
|
||||
allowedTags: sanitize.defaults.allowedTags.concat(["img"]),
|
||||
}),
|
||||
categories: fic?.data.series,
|
||||
categories: fic?.data.series.concat(fic.data.title),
|
||||
})),
|
||||
stylesheet: "/pretty-feed-v3.xsl",
|
||||
});
|
||||
|
|
|
@ -18,10 +18,15 @@ entries.sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
|||
<ThemeSwitch />
|
||||
<main>
|
||||
<h1>Guestbook</h1>
|
||||
<details>
|
||||
<summary>click me for a secret!</summary>
|
||||
<noscript>you should put ILIAD, but in all lowercase, in the password field!</noscript>
|
||||
<p id="cool-surprise"></p>
|
||||
</details>
|
||||
|
||||
<form action={actions.guestbook} method="post">
|
||||
<label for="username">Username</label>
|
||||
<input type="text" name="username" id="username" required aria-describedby="username-error" />
|
||||
<input type="text" name="username" id="username" aria-describedby="username-error" required />
|
||||
{errors.username && <p id="username-error">{errors.username.join(",")}</p>}
|
||||
|
||||
<label for="website">Website (optional)</label>
|
||||
|
@ -29,23 +34,26 @@ entries.sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
|||
{errors.website && <p id="website-error">{errors.website.join(",")}</p>}
|
||||
|
||||
<label for="body">Message</label>
|
||||
<textarea name="body" id="body" rows="5" required aria-describedby="body-error"></textarea>
|
||||
<textarea name="body" id="body" rows="5" aria-describedby="body-error" required></textarea>
|
||||
{errors.body && <p id="body-error">{errors.body.join(",")}</p>}
|
||||
|
||||
<input type="hidden" name="honeypot" tabindex="-1" autocomplete="off" style="display:none" />
|
||||
<button type="submit">Post</button>
|
||||
<label for="password">Do you know the password?</label>
|
||||
<input type="text" name="password" id="password" value="yes!" aria-describedby="password-error" required />
|
||||
{errors.password && <p id="password-error">{errors.password.join(",")}</p>}
|
||||
|
||||
{errors.honeypot && <p>{errors.honeypot.join(",")}</p>}
|
||||
<button type="submit">Post</button>
|
||||
</form>
|
||||
|
||||
{entries.map(({ username, website, body, date }) => (
|
||||
<article class="entry">
|
||||
<h1>{username}</h1>
|
||||
{website && <p><a href={website} target="_blank" referrerpolicy="no-referrer">website</a></p>}
|
||||
<time datetime={dayjs(date).utc(true).toISOString()}>{dayjs(date).utc(true).format("MMMM DD, YYYY")}</time>
|
||||
<div>
|
||||
{body}
|
||||
</div>
|
||||
<header>
|
||||
<h1>{username}</h1>
|
||||
<time datetime={dayjs(date).utc(true).toISOString()}>
|
||||
Posted on {dayjs(date).utc(true).format("MMMM DD, YYYY")}
|
||||
</time>
|
||||
{website && <a href={website} target="_blank" referrerpolicy="no-referrer">website</a>}
|
||||
</header>
|
||||
{body}
|
||||
</article>
|
||||
))}
|
||||
</main>
|
||||
|
@ -81,4 +89,34 @@ entries.sort((a, b) => b.date.valueOf() - a.date.valueOf());
|
|||
padding: 2px 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
details {
|
||||
& > summary {
|
||||
list-style: none;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
|
||||
&::after {
|
||||
content: "[+]";
|
||||
}
|
||||
|
||||
[open] &::after {
|
||||
content: "[_]";
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const details = document.getElementsByTagName("details").item(0);
|
||||
const pw = document.getElementById("cool-surprise");
|
||||
let initial = "vyvnq";
|
||||
details?.addEventListener("toggle", e => {
|
||||
if ((e.target as HTMLDetailsElement).open) {
|
||||
pw!.innerHTML = `if you read this, put <strong>${initial.replace(/[a-zA-Z]/g, c => {
|
||||
// @ts-expect-error the below code works
|
||||
return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);
|
||||
})}</strong> for the password field!`
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -1,3 +1,15 @@
|
|||
function aliasMood(emotion: string) {
|
||||
switch (emotion) {
|
||||
case "aggravated":
|
||||
case "annoyed":
|
||||
case "devious":
|
||||
return "angry";
|
||||
case "apathetic":
|
||||
|
||||
return "blah";
|
||||
}
|
||||
};
|
||||
|
||||
export default [
|
||||
"accomplished",
|
||||
"aggravated",
|
||||
|
|
|
@ -9,4 +9,4 @@
|
|||
"~/*": ["src/components/*"],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|