feat(desktop): render GitHub PR links as inline smart chips

GitHub pull request URLs are now displayed as compact inline chips
with a pull request icon and owner/repo#number label instead of
raw URLs, matching the style of @mention and #channel-link chips.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Taylor Ho
2026-04-08 14:06:57 -10:00
co-authored by Claude Opus 4.6
parent 68a3d16d9e
commit 9d029410e4
+33 -11
View File
@@ -1,3 +1,4 @@
import { GitPullRequest } from "lucide-react";
import * as React from "react";
import ReactMarkdown, { type Components } from "react-markdown";
import remarkBreaks from "remark-breaks";
@@ -11,6 +12,9 @@ import { rewriteRelayUrl } from "@/shared/lib/mediaUrl";
import remarkChannelLinks from "@/shared/lib/remarkChannelLinks";
import remarkMentions from "@/shared/lib/remarkMentions";
const GITHUB_PR_RE =
/^https?:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)\/?$/;
type MarkdownProps = {
channelNames?: string[];
className?: string;
@@ -41,17 +45,35 @@ function createMarkdownComponents(
: "space-y-1 pl-6 marker:text-muted-foreground";
return {
a: ({ children, href, ...props }) => (
<a
{...props}
className="font-medium text-primary underline underline-offset-4 transition-colors hover:text-primary/80"
href={href}
rel="noreferrer"
target="_blank"
>
{children}
</a>
),
a: ({ children, href, ...props }) => {
const prMatch = href ? GITHUB_PR_RE.exec(href) : null;
if (prMatch) {
const [, owner, repo, number] = prMatch;
return (
<a
{...props}
className="inline-flex items-center gap-1 rounded-md bg-primary/10 px-1.5 py-0.5 text-sm font-medium text-primary no-underline transition-colors hover:bg-primary/20"
href={href}
rel="noreferrer"
target="_blank"
>
<GitPullRequest className="size-3.5" />
{owner}/{repo}#{number}
</a>
);
}
return (
<a
{...props}
className="font-medium text-primary underline underline-offset-4 transition-colors hover:text-primary/80"
href={href}
rel="noreferrer"
target="_blank"
>
{children}
</a>
);
},
blockquote: ({ children }) => (
<blockquote className="border-l-2 border-border pl-4 italic text-muted-foreground">
{children}