import useSWR from "swr";
import { HydrationData } from "../../../libs/types/hydration";
import { HTTPError, RenderDocumentBody } from "../document";
import { PLACEMENT_ENABLED, WRITER_MODE } from "../env";
import "./index.scss";
import "./post.scss";
import {
BlogImage,
BlogPostData,
BlogPostMetadata,
BlogPostMetadataLinks,
BlogPostLimitedMetadata,
AuthorMetadata,
} from "../../../libs/types/blog";
import { useDecorateCodeExamples, useRunSample } from "../document/hooks";
import { DEFAULT_LOCALE } from "../../../libs/constants";
import { TOC } from "../document/organisms/toc";
import { SidePlacement } from "../ui/organisms/placement";
import { PlayQueue } from "../playground/queue";
function MaybeLink({ className = "", link, children }) {
return link ? (
link.startsWith("https://") ? (
{children}
) : (
{children}
)
) : (
{children}
);
}
export function TimeToRead({ readTime }: { readTime: number | undefined }) {
if (!readTime) {
return <>>;
}
return {readTime} minute read;
}
export function PublishDate({ date }: { date: string }) {
return (
);
}
export function Author({ metadata }: { metadata: AuthorMetadata | undefined }) {
return (
{metadata?.name || "The MDN Team"}
);
}
export function AuthorDateReadTime({
metadata,
}: {
metadata: BlogPostMetadata;
}) {
return (
);
}
function BlogImageFigure({
image,
width,
height,
}: {
image: BlogImage;
width?: number;
height?: number;
}) {
const src = `./${image.file}`;
return (
{(image.creator || image.source) && (
Image{" "}
{image.creator && (
<>
by{" "}
{image.creator.name}
>
)}
{image.source && (
<>
{" "}
via{" "}
{image.source.name}
>
)}
)}
);
}
function PreviousNext({
links: { previous, next },
}: {
links: BlogPostMetadataLinks;
}) {
return (
{previous && (
)}
{next && }
);
}
function PreviousNextLink({
direction,
metadata: { slug, title },
}: {
direction: "Previous" | "Next";
metadata: BlogPostLimitedMetadata;
}) {
return (
{direction} Post {title}
);
}
export function BlogPost(props: HydrationData) {
const dataURL = `./index.json`;
const { data } = useSWR(
dataURL,
async (url) => {
const response = await fetch(url);
if (!response.ok) {
switch (response.status) {
case 404:
throw new HTTPError(response.status, url, "Page not found");
}
const text = await response.text();
throw new HTTPError(response.status, url, text);
}
return await response.json();
},
{
fallbackData: props as BlogPostData,
revalidateOnFocus: WRITER_MODE,
revalidateOnMount: !props.blogMeta,
}
);
const { doc, blogMeta } = data || props || {};
useRunSample(doc);
useDecorateCodeExamples(doc);
return (
<>
{doc && blogMeta && (
{PLACEMENT_ENABLED && !blogMeta?.sponsored &&
}
{blogMeta?.sponsored && (
Sponsored
)}
{doc?.title}
{blogMeta.links && }
)}
>
);
}