XRenderer.tsx•1.34 kB
import { MessageSquare } from "lucide-react";
import { Tweet } from "react-tweet";
import { BookmarkTypes, ZBookmark } from "@karakeep/shared/types/bookmarks";
import { ContentRenderer } from "./types";
function extractTweetId(url: string): string | null {
const patterns = [
/(?:twitter\.com|x\.com)\/\w+\/status\/(\d+)/,
/(?:twitter\.com|x\.com)\/i\/web\/status\/(\d+)/,
];
for (const pattern of patterns) {
const match = url.match(pattern);
if (match) {
return match[1];
}
}
return null;
}
function canRenderX(bookmark: ZBookmark): boolean {
if (bookmark.content.type !== BookmarkTypes.LINK) {
return false;
}
const url = bookmark.content.url;
return extractTweetId(url) !== null;
}
function XRendererComponent({ bookmark }: { bookmark: ZBookmark }) {
if (bookmark.content.type !== BookmarkTypes.LINK) {
return null;
}
const tweetId = extractTweetId(bookmark.content.url);
if (!tweetId) {
return null;
}
return (
<div className="relative h-full w-full overflow-auto">
<div className="flex justify-center p-4">
<Tweet id={tweetId} />
</div>
</div>
);
}
export const xRenderer: ContentRenderer = {
id: "x",
name: "X (Twitter)",
icon: MessageSquare,
canRender: canRenderX,
component: XRendererComponent,
priority: 10,
};