Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 43 additions & 7 deletions app/(writing)/[slug]/opengraph-image/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,53 @@ export async function GET(request: NextRequest) {
const postViewsPostfix = postViews && postViews == 1 ? "view" : "views";

return new ImageResponse(
<div tw="flex items-center justify-center w-full h-full bg-white" style={{ fontFamily: "Geist Mono" }}>
<div tw="flex items-center justify-between w-full h-full px-20">
<img src={nathanThomasImage} alt="Nathan Thomas" width={340} height={340} tw="rounded-full" />
<div tw="flex h-[300px] flex-col justify-between flex-1 pl-10">
<h1 tw="text-5xl my-5 whitespace-normal break-words" style={{ fontFamily: "Geist Mono Medium" }}>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "center",
width: "100%",
height: "100%",
backgroundColor: "white",
fontFamily: "Geist Mono",
}}
>
<div
style={{
display: "flex",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
height: "100%",
paddingInline: 80,
}}
>
<img src={nathanThomasImage} alt="Nathan Thomas" width={340} height={340} style={{ borderRadius: 9999 }} />
<div
style={{
display: "flex",
height: 300,
flexDirection: "column",
justifyContent: "space-between",
flex: 1,
paddingLeft: 40,
}}
>
<h1
style={{
fontFamily: "Geist Mono Medium",
fontSize: 48,
marginBlock: 20,
whiteSpace: "normal",
overflowWrap: "break-word",
}}
>
{title}
</h1>
<p tw="flex text-3xl my-2 flex-2" style={{ fontFamily: "Geist Mono" }}>
<p style={{ display: "flex", fontSize: 30, marginBlock: 8, flex: 2, fontFamily: "Geist Mono" }}>
{description}
</p>
<p tw="text-2xl text-gray-500 flex-1" style={{ fontFamily: "Geist Mono" }}>
<p style={{ fontSize: 24, color: "#6b7280", flex: 1, fontFamily: "Geist Mono" }}>
{postViews != null && postViews != 0 ? `${date} • ${postViews} ${postViewsPostfix}` : date}
</p>
</div>
Expand Down
3 changes: 2 additions & 1 deletion app/(writing)/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { sx } from "@/app/styles/tw.stylex";
import * as Sentry from "@sentry/nextjs";

import { ImageOverlayContainer } from "@/app/components/ImageOverlay";
Expand Down Expand Up @@ -58,7 +59,7 @@ export default async function Page({ params }: Props) {
// with padding bottom. MDX gives no API for disovery of last index. This
// could move to mapping all items and passing an index on props, but
// that's overkill for this problem.
<article className="w-full -mb-5 flex flex-col items-center">
<article {...sx("wFull negMb5 flex flexCol itemsCenter")}>
<Post />
<ImageOverlayContainer />
{process.env.NODE_ENV === "production" ? <RedisIncrement slug={slug} /> : null}
Expand Down
7 changes: 4 additions & 3 deletions app/(writing)/components/blockquote.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { sx } from "@/app/styles/tw.stylex";
import { Children, type ReactNode } from "react";

export function Blockquote({ children }: { children: ReactNode }) {
Expand All @@ -13,7 +14,7 @@ export function Blockquote({ children }: { children: ReactNode }) {
const parts = child.split("\n");
parts.forEach((part, partIndex) => {
if (partIndex > 0) {
acc.push(<div className="mb-5" key={`br-${childIndex}-${partIndex}`}></div>);
acc.push(<div {...sx("mb5")} key={`br-${childIndex}-${partIndex}`}></div>);
}

if (part !== "") {
Expand All @@ -25,8 +26,8 @@ export function Blockquote({ children }: { children: ReactNode }) {
}, []);

return (
<div className="w-full flex justify-center mb-5">
<blockquote className="w-full max-w-2xl text-5 border-l-4 border-gray-500 mx-5 [&_p]:text-gray-500 italic whitespace-pre-line">
<div {...sx("wFull flex justifyCenter mb5")}>
<blockquote {...sx("wFull maxW2xl borderL4 borderGray500 mx5 italic whitespacePreLine blockquoteText")}>
{normalizedChildren}
</blockquote>
</div>
Expand Down
16 changes: 2 additions & 14 deletions app/(writing)/components/code.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
import { sx } from "@/app/styles/tw.stylex";
import type { ReactNode } from "react";

export const Code = ({ children }: { children: ReactNode }) => {
return (
<code
className={`
in-[p]:text-sm
in-[p]:px-1
in-[p]:py-0.5
in-[p]:rounded-sm
in-[p]:bg-neutral-200
dark:in-[p]:bg-[#222222]
`}
>
{children}
</code>
);
return <code {...sx("textSm px1 py05 roundedSm bgNeutral200")}>{children}</code>;
};
7 changes: 3 additions & 4 deletions app/(writing)/components/h1.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { sx } from "@/app/styles/tw.stylex";
import { HeadingLevel, getHeading } from "../utils/heading";

import type { ReactNode } from "react";

export function H1({ children }: { children: ReactNode }) {
return (
<div className="w-full flex justify-center mb-5">
<div className="w-full max-w-2xl mx-5">
{getHeading(children, HeadingLevel.H1)}
</div>
<div {...sx("wFull flex justifyCenter mb5")}>
<div {...sx("wFull maxW2xl mx5")}>{getHeading(children, HeadingLevel.H1)}</div>
</div>
);
}
9 changes: 4 additions & 5 deletions app/(writing)/components/h2.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { sx } from "@/app/styles/tw.stylex";
import { HeadingLevel, getHeading } from "../utils/heading";

import type { ReactNode } from "react";

export function H2({ children }: { children: ReactNode, id: string }) {
export function H2({ children }: { children: ReactNode; id: string }) {
return (
<div className="w-full flex justify-center mb-5">
<div className="w-full max-w-2xl mx-5">
{getHeading(children, HeadingLevel.H2)}
</div>
<div {...sx("wFull flex justifyCenter mb5")}>
<div {...sx("wFull maxW2xl mx5")}>{getHeading(children, HeadingLevel.H2)}</div>
</div>
);
}
7 changes: 3 additions & 4 deletions app/(writing)/components/h3.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { sx } from "@/app/styles/tw.stylex";
import { HeadingLevel, getHeading } from "../utils/heading";

import type { ReactNode } from "react";

export function H3({ children }: { children: ReactNode }) {
return (
<div className="w-full flex justify-center mb-5">
<div className="w-full max-w-2xl mx-5">
{getHeading(children, HeadingLevel.H3)}
</div>
<div {...sx("wFull flex justifyCenter mb5")}>
<div {...sx("wFull maxW2xl mx5")}>{getHeading(children, HeadingLevel.H3)}</div>
</div>
);
}
23 changes: 11 additions & 12 deletions app/(writing)/components/image.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client";

import NextImage from "next/image";
import clsx from "clsx";
import { showImageOverlay } from "@/app/store/reducers/writingSlice";
import { sx } from "@/app/styles/tw.stylex";
import { useDispatch } from "react-redux";
import { useState } from "react";

Expand Down Expand Up @@ -54,23 +54,22 @@ export function Image({
};

return (
<div className="w-full flex justify-center flex-col items-center mb-5">
<div {...sx("wFull flex justifyCenter flexCol itemsCenter mb5")}>
<button
aria-label="Enlarge image"
className={clsx(
"w-full mx-5 items-center flex overflow-hidden border border-background",
wide ? "max-w-4xl" : "max-w-2xl",
borderDark ? "border border-background dark:border-gray-800" : "",
borderLight ? "border border-gray-200 dark:border-background" : "",
disableOverlay ? "" : "hover:opacity-60 cursor-zoom-in transition-opacity duration-200",
{...sx(
"wFull mx5 itemsCenter flex overflowHidden border borderBackground",
wide ? "maxW4xl" : "maxW2xl",
(borderDark || borderLight) && "border borderMuted",
!disableOverlay && "opacityHover60 cursorZoomIn transitionOpacity",
)}
onClick={handleImageClick}
disabled={disableOverlay}
>
<div className={`aspect-ratio-[${width}/${height}] leading-none relative w-full flex justify-center`}>
<div {...sx("leadingNone relative wFull flex justifyCenter")} style={{ aspectRatio: `${width} / ${height}` }}>
{placeholderImage && isLoading ? (
<NextImage
className="absolute top-0 left-0 right-0 bottom-0 z-10 rounded-sm"
{...sx("absolute top0 left0 right0 bottom0 z10 roundedSm")}
src={placeholderImage}
alt={alt}
loading="eager"
Expand All @@ -82,7 +81,7 @@ export function Image({
) : null}
<NextImage
alt={alt}
className="rounded-sm"
{...sx("roundedSm")}
blurDataURL="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO5WZ5kAAAAASUVORK5CYII="
draggable={false}
height={height}
Expand All @@ -97,7 +96,7 @@ export function Image({
/>
</div>
</button>
<p className="text-xs mt-2 text-gray-500 font-mono">{title}</p>
<p {...sx("textXs mt2 textGray500 fontMono")}>{title}</p>
</div>
);
}
5 changes: 3 additions & 2 deletions app/(writing)/components/li.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { sx } from "@/app/styles/tw.stylex";
import type { ReactNode } from "react";

export function Li({ children }: { children: ReactNode }) {
return (
<div className="w-full flex justify-center">
<li className="w-full font-sans text-base relative">{children}</li>
<div {...sx("wFull flex justifyCenter")}>
<li {...sx("wFull fontSans textBase relative")}>{children}</li>
</div>
);
}
5 changes: 3 additions & 2 deletions app/(writing)/components/ol.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { sx } from "@/app/styles/tw.stylex";
import type { ReactNode } from "react";

export function Ol({ children }: { children: ReactNode }) {
return (
<div className="w-full flex justify-center mb-5">
<ol className="w-full max-w-2xl list-inside mx-5">{children}</ol>
<div {...sx("wFull flex justifyCenter mb5")}>
<ol {...sx("wFull maxW2xl listInside mx5")}>{children}</ol>
</div>
);
}
5 changes: 3 additions & 2 deletions app/(writing)/components/p.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { sx } from "@/app/styles/tw.stylex";
import type { ReactNode } from "react";

export function P({ children }: { children: ReactNode }) {
return (
<div className="w-full flex justify-center [&:not(blockquote_&)]:mb-5">
<p className="w-full max-w-2xl mx-5">{children}</p>
<div {...sx("wFull flex justifyCenter mb5")}>
<p {...sx("wFull maxW2xl mx5")}>{children}</p>
</div>
);
}
18 changes: 7 additions & 11 deletions app/(writing)/components/pre.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { sx } from "@/app/styles/tw.stylex";
import type { ReactNode } from "react";

export const Pre = ({
Expand All @@ -9,20 +10,15 @@ export const Pre = ({
scroll: boolean;
caption: ReactNode | null;
}) => (
<div className="w-full mb-5 flex justify-center mx-5 flex-col items-center">
<div {...sx("wFull mb5 flex justifyCenter mx5 flexCol itemsCenter")}>
<pre
className={`
p-4
text-sm
rounded-sm
bg-neutral-200 text-neutral-700
dark:bg-[#222222] dark:text-gray-300
w-full max-w-2xl
${scroll ? "overflow-auto" : "whitespace-pre-wrap break-all overflow-hidden"}
`}
{...sx(
"p4 textSm roundedSm bgNeutral200 textNeutral700 wFull maxW2xl",
scroll ? "overflowAuto" : "whitespacePreWrap breakAll overflowHidden",
)}
>
<code>{children}</code>
</pre>
<p className="text-sm mt-2 text-gray-500">{caption}</p>
<p {...sx("textSm mt2 textGray500")}>{caption}</p>
</div>
);
5 changes: 3 additions & 2 deletions app/(writing)/components/ul.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { sx } from "@/app/styles/tw.stylex";
import type { ReactNode } from "react";

export function Ul({ children }: { children: ReactNode }) {
return (
<div className="w-full flex justify-center mb-5">
<ul className="w-full max-w-2xl list-inside mx-5">{children}</ul>
<div {...sx("wFull flex justifyCenter mb5")}>
<ul {...sx("wFull maxW2xl listInside mx5")}>{children}</ul>
</div>
);
}
11 changes: 6 additions & 5 deletions app/(writing)/utils/heading.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { sx } from "@/app/styles/tw.stylex";
import Link from "next/link";
import { ReactNode } from "react";

Expand All @@ -24,7 +25,7 @@ function getHeadingAndHeadingId(heading: string) {
}

export function getHeading(children: ReactNode, level: HeadingLevel): ReactNode {
if (typeof children === 'string') {
if (typeof children === "string") {
const { heading, headingId } = getHeadingAndHeadingId(children);
let headingElement: ReactNode = children;
if (level === HeadingLevel.H1) {
Expand All @@ -38,17 +39,17 @@ export function getHeading(children: ReactNode, level: HeadingLevel): ReactNode
} else if (level === HeadingLevel.H5) {
headingElement = <h5 id={headingId}>{heading}</h5>;
}

if (!headingId) {
return headingElement;
}

return (
<Link className="inline-flex w-fit no-underline hover:opacity-100" href={`#${headingId}`}>
<Link {...sx("inlineFlex wFit noUnderline opacityHover100")} href={`#${headingId}`}>
{headingElement}
</Link>
);
}

return children;
}
}
Loading
Loading