import { useTranslation } from "react-i18next"; import { ExternalLink } from "lucide-react"; import type { ChannelDetail } from "../lib/api"; import { linkify } from "../lib/linkify"; import { Badge } from "./ui/Badge"; // --- About-tab metadata helpers (shared by the channel page and the manager's About overlay) --- function displayName(code: string, lang: string, type: "region" | "language"): string { try { return ( new Intl.DisplayNames([lang], { type }).of(type === "region" ? code.toUpperCase() : code) ?? code ); } catch { return code; } } // YouTube keywords are ONE space-separated string with multi-word tags quoted: gaming "let's play". function parseKeywords(s: string): string[] { return (s.match(/"[^"]+"|\S+/g) ?? []).map((k) => k.replace(/^"|"$/g, "")).filter(Boolean); } // topicCategories are Wikipedia URLs (…/wiki/Music) → a readable label, de-duplicated. function topicLabels(urls: string[]): string[] { const seen = new Set(); for (const url of urls) { const seg = url.split("/wiki/")[1] ?? url.split("/").pop() ?? url; let label = seg; try { label = decodeURIComponent(seg); } catch { /* keep raw */ } label = label.replace(/_/g, " ").trim(); if (label) seen.add(label); } return [...seen]; } /** * The channel "About" content — description, external links, and the enriched metadata * (country, language, topics, keywords). Shared by the channel detail page's About tab and the * Channel manager's About-column hover overlay, so both show exactly the same thing. */ export default function ChannelAboutContent({ ch }: { ch: ChannelDetail }) { const { t, i18n } = useTranslation(); const topics = ch.topic_categories?.length ? topicLabels(ch.topic_categories) : []; const keywords = ch.keywords ? parseKeywords(ch.keywords) : []; const hasAboutDetails = !!ch.country || !!ch.default_language || topics.length > 0 || keywords.length > 0; return ( <> {ch.description ? (

{linkify(ch.description)}

) : (

{t("channel.noDescription")}

)} {ch.external_links && ch.external_links.length > 0 && (
{ch.external_links.map((l, i) => ( {l.title || l.url} ))}
)} {hasAboutDetails && (
{ch.country && (
{t("channel.country")} {/^[A-Za-z]{2}$/.test(ch.country) && ( // Real SVG flag (flag-icons) — Windows/Chrome don't render flag emoji. )} {displayName(ch.country, i18n.language, "region")}
)} {ch.default_language && (
{t("channel.language")} {displayName(ch.default_language, i18n.language, "language")}
)} {topics.length > 0 && (
{t("channel.topics")}
{/* Future search epic: these topic chips become clickable filters. */} {topics.map((tp) => ( {tp} ))}
)} {keywords.length > 0 && (
{t("channel.keywords")}
{keywords.map((kw, i) => ( {kw} ))}
)}
)} ); }