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:
@@ -1,13 +1,9 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
import type { ChannelDetail } from "../lib/api";
|
||||
import { linkify } from "../lib/linkify";
|
||||
|
||||
// --- About-tab metadata helpers (shared by the channel page and the manager's About overlay) ---
|
||||
// ISO 3166-1 alpha-2 code → 🇺🇸 regional-indicator flag emoji.
|
||||
function countryFlag(code: string): string {
|
||||
if (!/^[A-Za-z]{2}$/.test(code)) return "";
|
||||
return String.fromCodePoint(...[...code.toUpperCase()].map((c) => 0x1f1e6 + c.charCodeAt(0) - 65));
|
||||
}
|
||||
function displayName(code: string, lang: string, type: "region" | "language"): string {
|
||||
try {
|
||||
return new Intl.DisplayNames([lang], { type }).of(type === "region" ? code.toUpperCase() : code) ?? code;
|
||||
@@ -51,7 +47,7 @@ export default function ChannelAboutContent({ ch }: { ch: ChannelDetail }) {
|
||||
return (
|
||||
<>
|
||||
{ch.description ? (
|
||||
<p className="text-sm whitespace-pre-wrap break-words leading-relaxed">{ch.description}</p>
|
||||
<p className="text-sm whitespace-pre-wrap break-words leading-relaxed">{linkify(ch.description)}</p>
|
||||
) : (
|
||||
<p className="text-sm text-muted">{t("channel.noDescription")}</p>
|
||||
)}
|
||||
@@ -76,8 +72,12 @@ export default function ChannelAboutContent({ ch }: { ch: ChannelDetail }) {
|
||||
{ch.country && (
|
||||
<div className="flex gap-2">
|
||||
<span className="text-muted w-24 shrink-0">{t("channel.country")}</span>
|
||||
<span>
|
||||
{countryFlag(ch.country)} {displayName(ch.country, i18n.language, "region")}
|
||||
<span className="inline-flex items-center gap-2">
|
||||
{/^[A-Za-z]{2}$/.test(ch.country) && (
|
||||
// Real SVG flag (flag-icons) — Windows/Chrome don't render flag emoji.
|
||||
<span className={`fi fi-${ch.country.toLowerCase()} rounded-sm shrink-0`} aria-hidden />
|
||||
)}
|
||||
{displayName(ch.country, i18n.language, "region")}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user