feat(managers): clickable links in descriptions + real SVG country flags
- linkify: bare http(s) URLs inside channel descriptions become clickable links (new tab, rel=noopener noreferrer) — new lib/linkify.tsx, used in the shared ChannelAboutContent so both the About overlay and the channel detail page get it - Country flag: the flag EMOJI never renders on Windows/Chrome (showed the small-caps 'hu' fallback), so swap it for a real self-hosted SVG flag via the flag-icons package; applies to the About overlay + the channel detail page
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import { Fragment, type ReactNode } from "react";
|
||||
|
||||
// A bare http(s) URL: greedy up to whitespace/<, but don't swallow a trailing sentence
|
||||
// punctuation mark (so "…see https://x.com/y." links "https://x.com/y", not the dot).
|
||||
const URL_RE = /(https?:\/\/[^\s<]+[^\s<.,!?;:)\]}"'])/g;
|
||||
|
||||
/**
|
||||
* Turn bare http(s) URLs inside a plain-text string into clickable links that open in a new tab
|
||||
* (with a safe rel). Everything else is returned as text, so it composes with `whitespace-pre-wrap`
|
||||
* (line breaks preserved). Used for channel/video descriptions where links arrive as plain text.
|
||||
*/
|
||||
export function linkify(text: string): ReactNode[] {
|
||||
const out: ReactNode[] = [];
|
||||
let last = 0;
|
||||
let key = 0;
|
||||
URL_RE.lastIndex = 0;
|
||||
let m: RegExpExecArray | null;
|
||||
while ((m = URL_RE.exec(text)) !== null) {
|
||||
if (m.index > last) out.push(<Fragment key={key++}>{text.slice(last, m.index)}</Fragment>);
|
||||
const url = m[0];
|
||||
out.push(
|
||||
<a
|
||||
key={key++}
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-accent hover:underline break-all"
|
||||
>
|
||||
{url}
|
||||
</a>,
|
||||
);
|
||||
last = m.index + url.length;
|
||||
}
|
||||
if (last < text.length) out.push(<Fragment key={key++}>{text.slice(last)}</Fragment>);
|
||||
return out;
|
||||
}
|
||||
Reference in New Issue
Block a user