Fix AI streaming, learn images, and full city regions.
Remove use server from stream helper to fix RSC errors; support OPENAI_API_BASE alias; render HTML tables via rehype-raw with gua-image API; expand regions to 356 prefecture-level cities. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import Link from "next/link";
|
||||
import Markdown from "react-markdown";
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import type { LearnVariant } from "@/lib/content/gua-utils";
|
||||
import { guaNumFromMark } from "@/lib/content/gua-utils";
|
||||
|
||||
function resolveLearnHref(
|
||||
href: string | undefined,
|
||||
@@ -31,19 +33,48 @@ function resolveLearnHref(
|
||||
const num = mark.split(".")[0];
|
||||
return `${base}/${num}`;
|
||||
}
|
||||
if (/^\.\.\/\d{2}\./.test(href)) {
|
||||
const num = href.replace(/^\.\.\//, "").split(".")[0];
|
||||
return `${base}/${num}`;
|
||||
}
|
||||
if (/^\d{2}\./.test(href)) {
|
||||
const num = href.split(".")[0];
|
||||
return `${base}/${num}`;
|
||||
}
|
||||
return href;
|
||||
}
|
||||
|
||||
function resolveImageSrc(
|
||||
src: string | undefined,
|
||||
variant: LearnVariant,
|
||||
guaNum: string,
|
||||
): string | undefined {
|
||||
if (!src) {
|
||||
return src;
|
||||
}
|
||||
if (src.startsWith("http://") || src.startsWith("https://")) {
|
||||
return src;
|
||||
}
|
||||
const file = src.replace(/^\.\//, "").split("/").pop() ?? src;
|
||||
const apiVariant = variant === "traditional" ? "traditional" : "simplified";
|
||||
return `/api/gua-image/${apiVariant}/${guaNum}/${encodeURIComponent(file)}`;
|
||||
}
|
||||
|
||||
export default function MarkdownContent({
|
||||
content,
|
||||
variant = "traditional",
|
||||
guaMark,
|
||||
}: {
|
||||
content: string;
|
||||
variant?: LearnVariant;
|
||||
guaMark: string;
|
||||
}) {
|
||||
const guaNum = guaNumFromMark(guaMark);
|
||||
|
||||
return (
|
||||
<Markdown
|
||||
className="prose max-w-none dark:prose-invert prose-headings:scroll-mt-20 prose-a:text-primary"
|
||||
className="prose max-w-none dark:prose-invert prose-headings:scroll-mt-20 prose-a:text-primary prose-table:text-sm"
|
||||
rehypePlugins={[rehypeRaw]}
|
||||
components={{
|
||||
a: ({ href, children, ...props }) => {
|
||||
const resolved = resolveLearnHref(href, variant);
|
||||
@@ -60,15 +91,24 @@ export default function MarkdownContent({
|
||||
</a>
|
||||
);
|
||||
},
|
||||
img: ({ src, alt, ...props }) => {
|
||||
if (typeof src === "string" && !src.startsWith("http")) {
|
||||
return (
|
||||
<span className="my-2 block rounded border border-dashed p-4 text-center text-sm text-muted-foreground">
|
||||
[{alt || "卦象图片"}]
|
||||
</span>
|
||||
);
|
||||
img: ({ src, alt }) => {
|
||||
const resolved = resolveImageSrc(
|
||||
typeof src === "string" ? src : undefined,
|
||||
variant,
|
||||
guaNum,
|
||||
);
|
||||
if (!resolved) {
|
||||
return null;
|
||||
}
|
||||
return <img src={src} alt={alt} {...props} />;
|
||||
return (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={resolved}
|
||||
alt={alt ?? "卦象图片"}
|
||||
className="mx-auto h-auto max-w-[120px]"
|
||||
loading="lazy"
|
||||
/>
|
||||
);
|
||||
},
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user