import { ExternalLinkIcon, PaperclipIcon, PlayIcon } from "lucide-react"; import type { EnvironmentId, ScopedThreadRef } from "@t3tools/contracts"; import { createContext, useContext, useMemo } from "react"; import type { Options as ReactMarkdownOptions } from "react-markdown"; import { cn } from "~/lib/utils"; import ChatMarkdown from "../ChatMarkdown"; import { remarkPullRequestAutolinks, splitPullRequestBody } from "./pullRequestMarkdown.logic"; export const PullRequestMarkdownContext = createContext(null); /** * A pull request body, rendered with the app's markdown renderer plus a card for each upload * embedded in it, which that renderer drops on the floor. * * These upload URLs do not identify the media format. The card links to GitHub, where the * original upload can be opened or downloaded even when its codec cannot play in the client. */ export function PullRequestMarkdown({ text, cwd, environmentId, threadRef, className, }: { text: string; cwd: string; environmentId: EnvironmentId; /** Thread the body is shown beside, so its links can open in that thread's in-app browser. */ threadRef?: ScopedThreadRef | null; className?: string; }) { const segments = splitPullRequestBody(text); const repositoryUrl = useContext(PullRequestMarkdownContext); const extraRemarkPlugins = useMemo>( () => (repositoryUrl ? [[remarkPullRequestAutolinks, { repositoryUrl }]] : []), [repositoryUrl], ); return (
{segments.map((segment) => { if (segment.kind === "markdown") { return ( ); } const isVideo = segment.media === "video"; const Icon = isVideo ? PlayIcon : PaperclipIcon; return ( // A plain anchor rather than the page's openExternal button: the desktop window // turns a blocked _blank into openExternal itself, and in a browser tab — where // there is no shell to call — this is the only one of the two that goes anywhere. {isVideo ? "Play video on GitHub" : "Open attachment on GitHub"} ); })}
); }