'use client';
import React from 'react';
import { Image as ImageIcon, Video, Volume2 } from 'lucide-react';
import type { VideoAsset } from '@/components/video-page/types';
const URL_REGEX = /(https?:\/\/[^\s]+)/g;
const ASSET_MENTION_REGEX = /@\[(.+?)\]\(asset:([a-z0-9]+)\)/gi;
interface CommentRichTextProps {
text: string;
onAssetMentionClick?: (assetId: string) => void;
assets?: VideoAsset[];
}
// `keyPrefix` scopes the indices to this slice. The function runs once per gap between
// mentions, so keying on the index alone emitted `txt-0` for several siblings and React
// warned about duplicate keys.
function renderUrls(text: string, keyPrefix: string): React.ReactNode[] {
const parts = text.split(URL_REGEX);
return parts.map((part, index) => {
if (/^https?:\/\/[^\s]+$/.test(part)) {
return (
event.stopPropagation()}
>
{part}
);
}
return {part};
});
}
export function CommentRichText({ text, onAssetMentionClick, assets = [] }: CommentRichTextProps) {
const nodes: React.ReactNode[] = [];
let lastIndex = 0;
for (const match of text.matchAll(ASSET_MENTION_REGEX)) {
const mentionIndex = match.index ?? -1;
if (mentionIndex < 0) continue;
if (mentionIndex > lastIndex) {
nodes.push(...renderUrls(text.slice(lastIndex, mentionIndex), `s${lastIndex}`));
}
const fallbackLabel = match[1] || 'asset';
const assetId = match[2] || '';
const matchedAsset = assets.find((asset) => asset.id === assetId);
const label = matchedAsset?.displayName || fallbackLabel;
const assetKind = matchedAsset?.kind;
nodes.push(
);
lastIndex = mentionIndex + match[0].length;
}
if (lastIndex < text.length) {
nodes.push(...renderUrls(text.slice(lastIndex), `s${lastIndex}`));
}
return <>{nodes}>;
}