feat: Introduce Linkify component to automatically convert URLs in comment and reply content into clickable links.

This commit is contained in:
Yusuf İpek
2026-02-21 10:50:45 +03:00
parent 5065fca38d
commit cd9b89c971
2 changed files with 36 additions and 2 deletions
+33
View File
@@ -0,0 +1,33 @@
import React from 'react';
const URL_REGEX = /(https?:\/\/[^\s]+)/g;
export function Linkify({ children }: { children: React.ReactNode }) {
if (typeof children !== 'string') {
return <>{children}</>;
}
const parts = children.split(URL_REGEX);
return (
<>
{parts.map((part, i) => {
if (part.match(URL_REGEX)) {
return (
<a
key={i}
href={part}
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline break-all"
onClick={(e) => e.stopPropagation()}
>
{part}
</a>
);
}
return <React.Fragment key={i}>{part}</React.Fragment>;
})}
</>
);
}
+3 -2
View File
@@ -74,6 +74,7 @@ import {
} from '@/components/ui/dropdown-menu';
import { cn } from '@/lib/utils';
import { parseVideoUrl, getThumbnailUrl, fetchVideoMetadata, type VideoSource } from '@/lib/video-providers';
import { Linkify } from '@/components/linkify';
interface Version {
id: string;
@@ -2380,7 +2381,7 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi
</div>
</div>
) : (
comment.content && <p className="text-sm mb-2">{comment.content}</p>
comment.content && <p className="text-sm mb-2"><Linkify>{comment.content}</Linkify></p>
)}
{comment.voiceUrl && (
@@ -2523,7 +2524,7 @@ export function VideoPageContent({ mode, videoId, projectId: propProjectId }: Vi
</div>
</div>
) : (
reply.content && <p className="text-sm">{reply.content}</p>
reply.content && <p className="text-sm"><Linkify>{reply.content}</Linkify></p>
)}
{reply.voiceUrl && (
<div className="flex items-center gap-2 p-1.5 bg-muted rounded mt-1">