1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-04-26 06:45:23 -04:00

consistent arrow functions

This commit is contained in:
Jake Jarvis 2025-03-12 18:10:11 -04:00
parent 6a57fde2f1
commit e61ca889a7
Signed by: jake
SSH Key Fingerprint: SHA256:nCkvAjYA6XaSPUqc4TfbBQTpzr8Xj7ritg/sGInCdkc
39 changed files with 121 additions and 126 deletions

View File

@ -15,7 +15,7 @@ NEXT_PUBLIC_UMAMI_WEBSITE_ID=
# optional. the base URL of a self-hosted Umami instance (including https://) to proxy requests to. if the website ID is
# set but this isn't, the managed Umami Cloud endpoint is used.
# https://umami.is/docs/bypass-ad-blockers
NEXT_PUBLIC_UMAMI_HOST=
NEXT_PUBLIC_UMAMI_URL=
# optional. enables comments on blog posts via GitHub discussions.
# https://giscus.app/

View File

@ -4,12 +4,12 @@ import type { hits as Hits } from "@prisma/client";
export const revalidate = 900; // 15 mins
export async function GET(): Promise<
export const GET = async (): Promise<
NextResponse<{
total: Pick<Hits, "hits">;
pages: Hits[];
}>
> {
> => {
// fetch all rows from db sorted by most hits
const pages = await prisma.hits.findMany({
orderBy: [
@ -28,4 +28,4 @@ export async function GET(): Promise<
});
return NextResponse.json({ total, pages });
}
};

View File

@ -20,7 +20,7 @@ export const metadata: Metadata = {
},
};
export default function Page() {
const Page = () => {
return (
<>
<PageTitle canonical="/birthday">1996.mov</PageTitle>
@ -28,4 +28,6 @@ export default function Page() {
<Video src={["/static/birthday/birthday.webm", "/static/birthday/birthday.mp4"]} poster={thumbnail.src} />
</>
);
}
};
export default Page;

View File

@ -3,7 +3,7 @@
import { headers } from "next/headers";
import { z } from "zod";
import { Resend } from "resend";
import config from "../../lib/config/constants";
import config from "../../lib/config";
const schema = z.object({
name: z.string().min(1, { message: "Name is required" }),
@ -12,7 +12,7 @@ const schema = z.object({
["cf-turnstile-response"]: z.string().min(1, { message: "CAPTCHA not completed" }),
});
export async function sendMessage(
export const sendMessage = async (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
prevState: any,
formData: FormData
@ -21,7 +21,7 @@ export async function sendMessage(
message: string;
errors?: z.inferFormattedError<typeof schema>;
payload?: FormData;
}> {
}> => {
try {
const validatedFields = schema.safeParse(Object.fromEntries(formData));
@ -85,4 +85,4 @@ export async function sendMessage(
payload: formData,
};
}
}
};

View File

@ -71,7 +71,7 @@ const ContactForm = () => {
}}
xmlns="http://www.w3.org/2000/svg"
>
<path d="M22.27 19.385H1.73A1.73 1.73 0 010 17.655V6.345a1.73 1.73 0 011.73-1.73h20.54A1.73 1.73 0 0124 6.345v11.308a1.73 1.73 0 01-1.73 1.731zM5.769 15.923v-4.5l2.308 2.885 2.307-2.885v4.5h2.308V8.078h-2.308l-2.307 2.885-2.308-2.885H3.46v7.847zM21.232 12h-2.309V8.077h-2.307V12h-2.308l3.461 4.039z"></path>
<path d="M22.27 19.385H1.73A1.73 1.73 0 010 17.655V6.345a1.73 1.73 0 011.73-1.73h20.54A1.73 1.73 0 0124 6.345v11.308a1.73 1.73 0 01-1.73 1.731zM5.769 15.923v-4.5l2.308 2.885 2.307-2.885v4.5h2.308V8.078h-2.308l-2.307 2.885-2.308-2.885H3.46v7.847zM21.232 12h-2.309V8.077h-2.307V12h-2.308l3.461 4.039z" />
</svg>{" "}
Basic{" "}
<Link href="https://commonmark.org/help/" title="Markdown reference sheet" style={{ fontWeight: 600 }}>

View File

@ -18,7 +18,7 @@ export const metadata: Metadata = {
},
};
export default function Page() {
const Page = () => {
return (
<div
style={{
@ -46,4 +46,6 @@ export default function Page() {
<ContactForm />
</div>
);
}
};
export default Page;

View File

@ -21,7 +21,7 @@ export const metadata: Metadata = {
},
};
export default function Page() {
const Page = () => {
return (
<>
<PageTitle canonical="/hillary">HRC.mov</PageTitle>
@ -60,4 +60,6 @@ export default function Page() {
</p>
</>
);
}
};
export default Page;

View File

@ -4,7 +4,7 @@ import { ThemeProvider } from "../contexts/ThemeContext";
import Header from "../components/Header";
import Footer from "../components/Footer";
import { SkipToContentLink, SkipToContentTarget } from "../components/SkipToContent";
import config from "../lib/config/constants";
import config from "../lib/config";
import type { Metadata } from "next";
import type { Person, WithContext } from "schema-dts";
@ -37,9 +37,14 @@ export const metadata: Metadata = {
{
url: meJpg.src,
alt: `${config.siteName} ${config.shortDescription}`,
width: meJpg.width,
height: meJpg.height,
},
],
},
twitter: {
creator: `@${config.authorSocial?.twitter}`,
},
alternates: {
canonical: "/",
types: {
@ -83,7 +88,7 @@ const jsonLd: WithContext<Person> = {
],
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
const RootLayout = ({ children }: { children: React.ReactNode }) => {
return (
<html lang={config.siteLocale} suppressHydrationWarning>
<head>
@ -110,4 +115,6 @@ export default function RootLayout({ children }: { children: React.ReactNode })
</body>
</html>
);
}
};
export default RootLayout;

View File

@ -21,7 +21,7 @@ export const metadata: Metadata = {
},
};
export default function Page() {
const Page = () => {
return (
<>
<PageTitle canonical="/leo">TheLab.mov</PageTitle>
@ -49,4 +49,6 @@ export default function Page() {
</p>
</>
);
}
};
export default Page;

View File

@ -1,4 +1,4 @@
import config from "../lib/config/constants";
import config from "../lib/config";
import type { MetadataRoute } from "next";
const manifest = (): MetadataRoute.Manifest => {

View File

@ -11,7 +11,7 @@ export const metadata: Metadata = {
},
};
export default async function Page() {
const Page = () => {
return (
<div style={{ textAlign: "center" }}>
<Video
@ -28,4 +28,6 @@ export default async function Page() {
<Link href="/">Go home?</Link>
</div>
);
}
};
export default Page;

View File

@ -8,7 +8,7 @@ import Loading from "../../../components/Loading";
import HitCounter from "./counter";
import { getPostSlugs, getFrontMatter } from "../../../lib/helpers/posts";
import { metadata as defaultMetadata } from "../../layout";
import config from "../../../lib/config/constants";
import config from "../../../lib/config";
import type { Metadata, Route } from "next";
import type { Article, WithContext } from "schema-dts";
@ -20,16 +20,16 @@ export const dynamicParams = false;
// https://nextjs.org/docs/app/building-your-application/rendering/partial-prerendering#using-partial-prerendering
export const experimental_ppr = true;
export async function generateStaticParams() {
export const generateStaticParams = async () => {
const slugs = await getPostSlugs();
// map slugs into a static paths object required by next.js
return slugs.map((slug) => ({
slug,
}));
}
};
export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
export const generateMetadata = async ({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> => {
const { slug } = await params;
const frontmatter = await getFrontMatter(slug);
@ -54,9 +54,9 @@ export async function generateMetadata({ params }: { params: Promise<{ slug: str
canonical: `/notes/${slug}`,
},
};
}
};
export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
const Page = async ({ params }: { params: Promise<{ slug: string }> }) => {
const { slug } = await params;
const frontmatter = await getFrontMatter(slug);
@ -153,4 +153,6 @@ export default async function Page({ params }: { params: Promise<{ slug: string
)}
</>
);
}
};
export default Page;

View File

@ -1,7 +1,7 @@
import Link from "../../components/Link";
import Time from "../../components/Time";
import { getAllPosts } from "../../lib/helpers/posts";
import config from "../../lib/config/constants";
import config from "../../lib/config";
import { metadata as defaultMetadata } from "../layout";
import type { ReactElement } from "react";
import type { Metadata, Route } from "next";
@ -23,7 +23,7 @@ export const metadata: Metadata = {
},
};
export default async function Page() {
const Page = async () => {
// parse the year of each note and group them together
const notes = await getAllPosts();
const notesByYear: {
@ -58,5 +58,7 @@ export default async function Page() {
// grouped posts enter this component ordered chronologically -- we want reverse chronological
const reversed = sections.reverse();
return <>{reversed}</>;
}
return reversed;
};
export default Page;

View File

@ -34,7 +34,7 @@ const Link = ({
);
};
export default function Page() {
const Page = () => {
return (
<div className={styles.page}>
<h1>
@ -286,4 +286,6 @@ export default function Page() {
</p>
</div>
);
}
};
export default Page;

View File

@ -38,7 +38,7 @@ export const metadata: Metadata = {
},
};
export default async function Page() {
const Page = () => {
return (
<div
className={styles.wackyWrapper}
@ -86,7 +86,7 @@ export default async function Page() {
marginRight: "0.1em",
}}
>
<path d="M5.712 1.596l-.756.068-.238.55.734-.017zm1.39.927l-.978.137-.326.807.96-.12.345-.824zM4.89 3.535l-.72.05-.24.567.721-.017zm3.724.309l-1.287.068-.394.96 1.27-.052zm1.87.566l-1.579.069-.566 1.357 1.596-.088.548-1.338zm-4.188.037l-.977.153-.343.806.976-.12zm6.144.668l-1.87.135-.637 1.527 1.87-.154zm2.925.219c-.11 0-.222 0-.334.002l-.767 1.85c1.394-.03 2.52.089 3.373.38l-1.748 4.201c-.955-.304-2.082-.444-3.36-.394l-.54 1.305a8.762 8.762 0 0 1 3.365.396l-1.663 4.014c-1.257-.27-2.382-.395-3.387-.344l-.782 1.887c3.363-.446 6.348.822 9.009 3.773L24 9.23c-2.325-2.575-5.2-3.88-8.637-3.896zm-.644.002l-2.024.12-.687 1.68 2.025-.19zm-10.603.05l-.719.036-.224.566h.703l.24-.601zm3.69.397l-1.287.069-.395.959 1.27-.05zM5.54 6.3l-.994.154-.344.807.98-.121zm4.137.066l-1.58.069L7.53 7.77l1.596-.085.55-1.32zm1.955.688l-1.87.135-.636 1.527 1.887-.154zm2.282.19l-2.01.136-.7 1.682 2.04-.19.67-1.63zm-10.57.066l-.739.035-.238.564h.72l.257-.6zm3.705.293l-1.303.085-.394.96 1.287-.034zm11.839.255a6.718 6.718 0 0 1 2.777 1.717l-1.75 4.237c-.617-.584-1.15-.961-1.611-1.149l-1.201-.498zM4.733 8.22l-.976.154-.344.807.961-.12.36-.841zm4.186 0l-1.594.052-.549 1.354L8.37 9.54zm1.957.668L8.99 9.04l-.619 1.508 1.87-.135.636-1.527zm2.247.275l-2.007.12-.703 1.665 2.042-.156zM2.52 9.267l-.718.033-.24.549.718-.016zm3.725.273l-1.289.07-.41.96 1.287-.03.412-1zm1.87.6l-1.596.05-.55 1.356 1.598-.084.547-1.322zm-4.186.037l-.979.136-.324.805.96-.119zm6.14.633l-1.87.154-.653 1.527 1.906-.154zm2.267.275l-2.026.12-.686 1.663 2.025-.172zm-10.569.031l-.739.037-.238.565.72-.016zm3.673.362l-1.289.068-.41.978 1.305-.05zm-2.285.533l-.976.154-.326.805.96-.12.342-.84zm4.153.07l-1.596.066-.565 1.356 1.612-.084zm1.957.666l-1.889.154-.617 1.526 1.886-.15zm2.28.223l-2.025.12-.685 1.665 2.041-.172.67-1.613zm-10.584.05l-.738.053L0 13.64l.72-.02.24-.6zm3.705.31l-1.285.07-.395.976 1.287-.05.393-.997zm11.923.07c1.08.29 2.024.821 2.814 1.613l-1.715 4.183c-.892-.754-1.82-1.32-2.814-1.664l1.715-4.133zm-10.036.515L4.956 14l-.549 1.32 1.578-.066.567-1.338zm-4.184.014l-.996.156-.309.79.961-.106zm6.14.67l-1.904.154-.617 1.527 1.89-.154.632-1.527zm2.231.324l-2.025.123-.686 1.682 2.026-.174zm-6.863.328l-1.3.068-.397.98 1.285-.054zm1.871.584l-1.578.068-.566 1.334 1.595-.064zm1.953.701l-1.867.137-.635 1.51 1.87-.137zm2.23.31l-2.005.122-.703 1.68 2.04-.19.67-1.61z"></path>
<path d="M5.712 1.596l-.756.068-.238.55.734-.017zm1.39.927l-.978.137-.326.807.96-.12.345-.824zM4.89 3.535l-.72.05-.24.567.721-.017zm3.724.309l-1.287.068-.394.96 1.27-.052zm1.87.566l-1.579.069-.566 1.357 1.596-.088.548-1.338zm-4.188.037l-.977.153-.343.806.976-.12zm6.144.668l-1.87.135-.637 1.527 1.87-.154zm2.925.219c-.11 0-.222 0-.334.002l-.767 1.85c1.394-.03 2.52.089 3.373.38l-1.748 4.201c-.955-.304-2.082-.444-3.36-.394l-.54 1.305a8.762 8.762 0 0 1 3.365.396l-1.663 4.014c-1.257-.27-2.382-.395-3.387-.344l-.782 1.887c3.363-.446 6.348.822 9.009 3.773L24 9.23c-2.325-2.575-5.2-3.88-8.637-3.896zm-.644.002l-2.024.12-.687 1.68 2.025-.19zm-10.603.05l-.719.036-.224.566h.703l.24-.601zm3.69.397l-1.287.069-.395.959 1.27-.05zM5.54 6.3l-.994.154-.344.807.98-.121zm4.137.066l-1.58.069L7.53 7.77l1.596-.085.55-1.32zm1.955.688l-1.87.135-.636 1.527 1.887-.154zm2.282.19l-2.01.136-.7 1.682 2.04-.19.67-1.63zm-10.57.066l-.739.035-.238.564h.72l.257-.6zm3.705.293l-1.303.085-.394.96 1.287-.034zm11.839.255a6.718 6.718 0 0 1 2.777 1.717l-1.75 4.237c-.617-.584-1.15-.961-1.611-1.149l-1.201-.498zM4.733 8.22l-.976.154-.344.807.961-.12.36-.841zm4.186 0l-1.594.052-.549 1.354L8.37 9.54zm1.957.668L8.99 9.04l-.619 1.508 1.87-.135.636-1.527zm2.247.275l-2.007.12-.703 1.665 2.042-.156zM2.52 9.267l-.718.033-.24.549.718-.016zm3.725.273l-1.289.07-.41.96 1.287-.03.412-1zm1.87.6l-1.596.05-.55 1.356 1.598-.084.547-1.322zm-4.186.037l-.979.136-.324.805.96-.119zm6.14.633l-1.87.154-.653 1.527 1.906-.154zm2.267.275l-2.026.12-.686 1.663 2.025-.172zm-10.569.031l-.739.037-.238.565.72-.016zm3.673.362l-1.289.068-.41.978 1.305-.05zm-2.285.533l-.976.154-.326.805.96-.12.342-.84zm4.153.07l-1.596.066-.565 1.356 1.612-.084zm1.957.666l-1.889.154-.617 1.526 1.886-.15zm2.28.223l-2.025.12-.685 1.665 2.041-.172.67-1.613zm-10.584.05l-.738.053L0 13.64l.72-.02.24-.6zm3.705.31l-1.285.07-.395.976 1.287-.05.393-.997zm11.923.07c1.08.29 2.024.821 2.814 1.613l-1.715 4.183c-.892-.754-1.82-1.32-2.814-1.664l1.715-4.133zm-10.036.515L4.956 14l-.549 1.32 1.578-.066.567-1.338zm-4.184.014l-.996.156-.309.79.961-.106zm6.14.67l-1.904.154-.617 1.527 1.89-.154.632-1.527zm2.231.324l-2.025.123-.686 1.682 2.026-.174zm-6.863.328l-1.3.068-.397.98 1.285-.054zm1.871.584l-1.578.068-.566 1.334 1.595-.064zm1.953.701l-1.867.137-.635 1.51 1.87-.137zm2.23.31l-2.005.122-.703 1.68 2.04-.19.67-1.61z" />
</svg>{" "}
Click here for the <em>full</em> experience anyway.
</Link>
@ -96,7 +96,6 @@ export default async function Page() {
<iframe
src="https://jakejarvis.github.io/my-first-website/"
title="My Terrible, Horrible, No Good, Very Bad First Website"
sandbox="allow-same-origin allow-scripts allow-popups"
className={styles.iframe}
style={{ height: "500px" }}
/>
@ -188,4 +187,6 @@ export default async function Page() {
</Figure>
</div>
);
}
};
export default Page;

View File

@ -4,7 +4,7 @@ import PageTitle from "../../components/PageTitle";
import Link from "../../components/Link";
import RelativeTime from "../../components/RelativeTime";
import commaNumber from "comma-number";
import config from "../../lib/config/constants";
import config from "../../lib/config";
import { metadata as defaultMetadata } from "../layout";
import type { Metadata } from "next";
import type { User, Repository } from "@octokit/graphql-schema";
@ -39,7 +39,7 @@ type Project = {
updatedAt: string;
};
async function getRepos(): Promise<Project[] | null> {
const getRepos = async (): Promise<Project[] | null> => {
// don't fail the entire site build if the required API key for this page is missing
if (!process.env.GITHUB_TOKEN) {
console.warn(`ERROR: I can't fetch any GitHub projects without "GITHUB_TOKEN" set! Skipping for now...`);
@ -102,9 +102,9 @@ async function getRepos(): Promise<Project[] | null> {
}));
return repos;
}
};
export default async function Page() {
const Page = async () => {
const repos = await getRepos();
return (
@ -190,11 +190,13 @@ export default async function Page() {
fill: "var(--colors-text)",
}}
>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
</svg>{" "}
GitHub...
</Link>
</p>
</>
);
}
};
export default Page;

View File

@ -1,4 +1,4 @@
import config from "../lib/config/constants";
import config from "../lib/config";
import type { MetadataRoute } from "next";
export const dynamic = "force-static";

View File

@ -1,7 +1,7 @@
import path from "path";
import glob from "fast-glob";
import { getAllPosts } from "../lib/helpers/posts";
import config from "../lib/config/constants";
import config from "../lib/config";
import type { MetadataRoute } from "next";
export const dynamic = "force-static";

View File

@ -19,7 +19,7 @@ export const metadata: Metadata = {
},
};
export default async function Page() {
const Page = () => {
return (
<div
style={{
@ -73,4 +73,6 @@ export default async function Page() {
</CodeBlock>
</div>
);
}
};
export default Page;

View File

@ -3,7 +3,9 @@ import type { ComponentPropsWithoutRef } from "react";
import styles from "./Blockquote.module.css";
const Blockquote = ({ className, ...rest }: ComponentPropsWithoutRef<"blockquote">) => (
export type BlockquoteProps = ComponentPropsWithoutRef<"blockquote">;
const Blockquote = ({ className, ...rest }: BlockquoteProps) => (
<blockquote className={clsx(styles.blockquote, className)} {...rest} />
);

View File

@ -3,7 +3,9 @@ import type { ComponentPropsWithoutRef } from "react";
import styles from "./CodeInline.module.css";
const CodeInline = ({ className, ...rest }: ComponentPropsWithoutRef<"code">) => (
export type CodeInlineProps = ComponentPropsWithoutRef<"code">;
const CodeInline = ({ className, ...rest }: CodeInlineProps) => (
<code className={clsx(styles.codeInline, className)} {...rest} />
);

View File

@ -22,9 +22,7 @@ const CodePen = ({
preview: `${!!preview}`,
editable: `${!!editable}`,
})}`}
scrolling="no"
sandbox="allow-same-origin allow-scripts allow-popups allow-top-navigation-by-user-activation"
style={{ height: `${height}px`, width: "100%", border: "0" }}
style={{ height: `${height}px`, width: "100%", border: "0", overflow: "hidden" }}
/>
);
};

View File

@ -1,7 +1,7 @@
"use client";
import Giscus from "@giscus/react";
import config from "../../lib/config/constants";
import config from "../../lib/config";
import type { GiscusProps } from "@giscus/react";
export type CommentsProps = {

View File

@ -1,7 +1,7 @@
import clsx from "clsx";
import { HeartIcon } from "lucide-react";
import Link from "../Link";
import config from "../../lib/config/constants";
import config from "../../lib/config";
import type { ComponentPropsWithoutRef } from "react";
import styles from "./Footer.module.css";
@ -47,7 +47,7 @@ const Footer = ({ className, ...rest }: FooterProps) => {
width="1.25em"
className={styles.icon}
>
<path d="M18.665 21.978C16.758 23.255 14.465 24 12 24 5.377 24 0 18.623 0 12S5.377 0 12 0s12 5.377 12 12c0 3.583-1.574 6.801-4.067 9.001L9.219 7.2H7.2v9.596h1.615V9.251l9.85 12.727Zm-3.332-8.533 1.6 2.061V7.2h-1.6v6.245Z"></path>
<path d="M18.665 21.978C16.758 23.255 14.465 24 12 24 5.377 24 0 18.623 0 12S5.377 0 12 0s12 5.377 12 12c0 3.583-1.574 6.801-4.067 9.001L9.219 7.2H7.2v9.596h1.615V9.251l9.85 12.727Zm-3.332-8.533 1.6 2.061V7.2h-1.6v6.245Z" />
</svg>
</Link>
.{" "}

View File

@ -12,7 +12,7 @@ const Gist = async ({ id, file }: GistProps) => {
const scriptResponse = await fetch(scriptUrl);
if (!scriptResponse.ok) {
console.warn(`[gist] fetching js for https://gist.github.com/${id} failed:`, scriptResponse.statusText);
console.warn(`[gist] failed to fetch js:`, scriptResponse.statusText);
return (
<p style={{ textAlign: "center" }}>
@ -33,10 +33,9 @@ const Gist = async ({ id, file }: GistProps) => {
scrolling="no"
id={iframeId}
srcDoc={iframeHtml}
sandbox="allow-same-origin allow-scripts allow-popups allow-top-navigation-by-user-activation"
style={{ border: "0", overflow: "hidden" }}
suppressHydrationWarning
></iframe>
/>
);
};

View File

@ -2,7 +2,7 @@ import clsx from "clsx";
import Link from "../Link";
import Image from "../Image";
import Menu from "../Menu";
import config from "../../lib/config/constants";
import config from "../../lib/config";
import type { ComponentPropsWithoutRef } from "react";
import styles from "./Header.module.css";

View File

@ -3,7 +3,9 @@ import type { ComponentPropsWithoutRef } from "react";
import styles from "./HorizontalRule.module.css";
const HorizontalRule = ({ className, ...rest }: ComponentPropsWithoutRef<"hr">) => (
export type HorizontalRuleProps = ComponentPropsWithoutRef<"hr">;
const HorizontalRule = ({ className, ...rest }: HorizontalRuleProps) => (
<hr className={clsx(styles.hr, className)} {...rest} />
);

View File

@ -1,7 +1,7 @@
import NextLink from "next/link";
import clsx from "clsx";
import objStr from "obj-str";
import config from "../../lib/config/constants";
import config from "../../lib/config";
import type { ComponentPropsWithoutRef } from "react";
import styles from "./Link.module.css";

View File

@ -79,7 +79,8 @@ export const ThemeProvider = ({ children }: PropsWithChildren) => {
id="restore-theme"
// unminified: https://gist.github.com/jakejarvis/79b0ec8506bc843023546d0d29861bf0
dangerouslySetInnerHTML={{
__html: `(()=>{try{const e=document.documentElement,t="undefined"!=typeof Storage?window.localStorage.getItem("theme"):null,a=(t&&"dark"===t)??window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";e.dataset.theme=a,e.style.colorScheme=a}catch(e){}})()`,
__html:
"(()=>{try{const e=document.documentElement,t='undefined'!=typeof Storage?window.localStorage.getItem('theme'):null,a=(t&&'dark'===t)??window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light';e.dataset.theme=a,e.style.colorScheme=a}catch(e){}})()",
}}
/>

View File

@ -1,8 +1,9 @@
const constants = {
const config = {
// Site info
siteName: "Jake Jarvis",
siteLocale: "en-US",
baseUrl:
// same logic as metadataBase: https://nextjs.org/docs/app/api-reference/functions/generate-metadata#default-value
process.env.NEXT_PUBLIC_VERCEL_ENV === "production" && process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL
? `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`
: process.env.NEXT_PUBLIC_VERCEL_ENV === "preview" && process.env.NEXT_PUBLIC_VERCEL_URL
@ -35,4 +36,4 @@ const constants = {
},
};
export default constants;
export default config;

View File

@ -1,6 +1,6 @@
import { Feed } from "feed";
import { getAllPosts } from "./posts";
import config from "../config/constants";
import config from "../config";
import meJpg from "../../app/me.jpg";

View File

@ -5,7 +5,7 @@ import dayjsRelativeTime from "dayjs/plugin/relativeTime";
import dayjsLocalizedFormat from "dayjs/plugin/localizedFormat";
import dayjsAdvancedFormat from "dayjs/plugin/advancedFormat";
import "dayjs/locale/en";
import config from "../config/constants";
import config from "../config";
const IsomorphicDayJs = (date?: dayjs.ConfigType): dayjs.Dayjs => {
// plugins

View File

@ -3,7 +3,7 @@ import glob from "fast-glob";
import pMap from "p-map";
import pMemoize from "p-memoize";
import { formatDate } from "./format-date";
import config from "../config/constants";
import config from "../config";
// path to directory with .mdx files, relative to project root
const POSTS_DIR = "notes";

View File

@ -14,7 +14,7 @@ import YouTube from "./components/YouTube";
import Gist from "./components/Gist";
import CodePen from "./components/CodePen";
export function useMDXComponents(components: MDXComponents): MDXComponents {
export const useMDXComponents = (components: MDXComponents): MDXComponents => {
return {
...components,
@ -44,4 +44,4 @@ export function useMDXComponents(components: MDXComponents): MDXComponents {
Gist,
CodePen,
};
}
};

View File

@ -1,17 +1,17 @@
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import siteConfig from "./lib/config/constants";
import siteConfig from "./lib/config";
// assign "short codes" to approved reverse proxy destinations. for example:
// ["abc", "https://jakejarvis.github.io/blah"] => /_stream/abc/123.html -> https://jakejarvis.github.io/blah/123.html
// ["abc", "https://jakejarvis.github.io"] => /_stream/abc/123.html -> https://jakejarvis.github.io/123.html
const rewritePrefix = "/_stream/";
const rewrites = new Map([
// umami backend, see https://umami.is/docs/guides/running-on-vercel#proxy-umami-analytics-via-vercel
["u", process.env.NEXT_PUBLIC_UMAMI_HOST || "https://cloud.umami.is"],
["u", process.env.NEXT_PUBLIC_UMAMI_URL || "https://cloud.umami.is"],
]);
export function middleware(request: NextRequest) {
export const middleware = (request: NextRequest) => {
const headers = new Headers();
// https://gitweb.torproject.org/tor-browser-spec.git/tree/proposals/100-onion-location-header.txt
@ -31,9 +31,6 @@ export function middleware(request: NextRequest) {
// search the rewrite map for the short code
const proxiedOrigin = rewrites.get(key);
// TODO: remove debugging headers
headers.set("x-middleware-proxy-key", key);
// return a 400 error if a rewrite was requested but the short code isn't found
if (!proxiedOrigin) {
return NextResponse.json(
@ -50,7 +47,7 @@ export function middleware(request: NextRequest) {
const proxiedUrl = new URL(`${proxiedPath}${request.nextUrl.search}`, proxiedOrigin);
// TODO: remove debugging headers
headers.set("x-middleware-proxy-to", proxiedUrl.toString());
headers.set("x-middleware-rewrite", proxiedUrl.toString());
// finally do the rewriting
return NextResponse.rewrite(proxiedUrl, {
@ -64,7 +61,7 @@ export function middleware(request: NextRequest) {
request,
headers,
});
}
};
export const config = {
// save compute time by skipping middleware for static and metadata files

View File

@ -40,23 +40,13 @@ const nextConfig: NextConfig = {
],
},
],
rewrites: async () => ({
beforeFiles: [
rewrites: async () => [
{
// https://github.com/jakejarvis/tweets
source: "/tweets/:path*",
destination: "https://tweets-khaki.vercel.app/:path*",
},
],
afterFiles: [
{
// access security.txt, etc at both /security.txt and /.well-known/security.txt
source: "/.well-known/:slug.txt",
destination: "/:slug.txt",
},
],
fallback: [],
}),
redirects: async () => [
{ source: "/y2k", destination: "https://y2k.pages.dev", permanent: false },
{

View File

@ -28,7 +28,6 @@ I've written a simple implementation below, which...
title="Dark Mode Example"
loading="lazy"
style={{ height: "190px", width: "100%" }}
sandbox="allow-same-origin allow-scripts allow-popups allow-top-navigation-by-user-activation"
></iframe>
A _very_ barebones example is embedded above ([view the source here](https://github.com/jakejarvis/dark-mode-example), or [open in a new window](https://jakejarvis.github.io/dark-mode-example/) if your browser is blocking the frame) and you can try it out on this site by clicking the 💡 lightbulb in the upper right corner of this page. You'll notice that the dark theme sticks when refreshing this page, navigating between other pages, or if you were to return to this example weeks from now.

View File

@ -35,7 +35,7 @@
- Umami
- Giscus
- Resend
- ...and more: https://jarv.is/uses/
- ...and more: https://jarv.is/uses
# VIEW SOURCE
@ -43,7 +43,7 @@
# PRIVACY POLICY
https://jarv.is/privacy/
https://jarv.is/privacy
# TOR MIRROR
@ -54,4 +54,4 @@
All content is licensed under CC-BY-4.0, an
open & permissive Creative Commons license:
https://jarv.is/license/
https://jarv.is/license

View File

@ -1,24 +0,0 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Contact: https://jarv.is/contact/
Encryption: https://jarv.is/pubkey.asc
Encryption: openpgp4fpr:3bc6e5776bf379d36f6714802b0c9cf251e69a39
Preferred-Languages: en
Expires: 2025-01-01T06:00:00.000Z
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEEO8bld2vzedNvZxSAKwyc8lHmmjkFAmXTsxwACgkQKwyc8lHm
mjlwqA//ZyIYleG3sh5OeVpHS0mI4Tr5crR6SG08A5DEwe8ysbQqDhPx0LxodRMd
XulfZ+TIDM3TXmw7LffeiKpRRFm0ecQtQT3hKorQgzHtUuKoPdr6gPC7Lrs9H7fE
4QlAa/WM4M/yYJfW9HZnh1/2Lh5LulQ4dkGAhb5cBvSCAWYF3W0eLjUXI6xBWyzx
FEnfTxsFCBd2h1g+S/Sc99mOvwHkcMOZflsiWCvXJb8ELwcusAK4SWYUM/bTJMil
a3BzvYinjyGEGqX2u+SNp+6ZxFYpDUCq8Vl+LPUFvlYpfjqVjiK9knZBHo2YADH0
6HPP+FdMUnZTd3gGwLsUS4NOcXWqqRivL9bWOVgklsoawjOeQtelgrGXrzhtIaYo
bbUko3kpYBy9EkGKtefQ4BYAy3CTjFjfkeadm5EOXPFdEEPjQRqdfJdniHCYG+27
xmriwobd2Ht+e3f0oOOf7Ae/ZD9MvaAA5Qn5uIbebVQaOxjetKbKGwDiPSLRJ5On
zfOsJn2qY1NVjWG6IlqNHpI1vjzmNOsFFlknELg5NOFstpXvLYGX1TkqBnI2g3f4
KuGXx4gOoq2oyoZuCi2bGO0Yn6lZ1UlEnfAO2ixW2FAPe8gqzxCeyxHzgvb4vNbr
VpmZuRxsOcdCgvItZkYCaS164GYvRTPWCtC1Q3lzAZViCOgMUmk=
=XWDQ
-----END PGP SIGNATURE-----