"use client"; // The row of scope chips above the query builder: one per archive on the hub, // official and added. Pressing a chip takes that archive in or out of the // search (useHubScope remembers it per browser). Each chip says what its // archive is doing — loading, its record count once ready (its summaries // manifest's totalCount, the number the results header counts), or failed with // a Retry beside it — so a slow or dead member is visible, not a silent gap. // A ready archive whose live chat could not be read says that too // (LIVE_CHAT_MISSING), with a Retry for its live chat alone: its videos stay // in the search meanwhile. import { cn } from "yt-dlp-transcript-common/lib/utils"; import { useSearchData, type FederatedSiteState, } from "yt-dlp-transcript-common/components/SearchDataContext"; import { LIVE_CHAT_MISSING } from "../../ask/hubScopeCopy"; function detail(s: FederatedSiteState): string { switch (s.status) { case "off": return "off"; case "loading": return "loading…"; case "failed": return "failed"; case "ready": return s.count === undefined ? "ready" : s.count.toLocaleString(); } } export default function HubScope({ onToggle, }: { onToggle: (origin: string) => void; }) { const { federation } = useSearchData(); if (!federation || federation.sites.length === 0) return null; const { sites, retry, retryLiveChat } = federation; return (
{sites.map((s) => { const on = s.status !== "off"; return ( {s.status === "failed" && ( )} {s.status === "ready" && s.liveChatMissing && ( <> {LIVE_CHAT_MISSING} )} ); })}
); }