MCPcopy Create free account
hub / github.com/AmazingAng/PolyWorld / LiveChannelDropdown

Function LiveChannelDropdown

src/components/LivePanel.tsx:45–154  ·  view source on GitHub ↗
({
  activeStream,
  onSelect,
}: {
  activeStream: StreamSource | null;
  onSelect: (stream: StreamSource | null) => void;
})

Source from the content-addressed store, hash-verified

43
44/** Dropdown button for the Panel header — renders channel list inline */
45export function LiveChannelDropdown({
46 activeStream,
47 onSelect,
48}: {
49 activeStream: StreamSource | null;
50 onSelect: (stream: StreamSource | null) => void;
51}) {
52 const { t } = useI18n();
53 const [open, setOpen] = useState(false);
54 const [tab, setTab] = useState<CategoryTab>("news");
55 const ref = useRef<HTMLDivElement>(null);
56
57 const filteredStreams = useMemo(
58 () => STREAMS.filter((s) => s.category === tab),
59 [tab],
60 );
61
62 useEffect(() => {
63 if (!open) return;
64 const handler = (e: MouseEvent) => {
65 if (ref.current && !ref.current.contains(e.target as Node))
66 setOpen(false);
67 };
68 document.addEventListener("mousedown", handler);
69 return () => document.removeEventListener("mousedown", handler);
70 }, [open]);
71
72 return (
73 <div ref={ref} className="relative font-mono">
74 <button
75 onClick={() => setOpen((o) => !o)}
76 className={`flex items-center gap-1.5 text-[10px] px-1.5 py-0.5 border transition-colors ${
77 open || activeStream
78 ? "border-[var(--text-secondary)]/30 text-[var(--text-secondary)]"
79 : "border-[var(--border-subtle)] text-[var(--text-faint)] hover:text-[var(--text-secondary)]"
80 }`}
81 >
82 {activeStream ? (
83 <>
84 <span className="w-1 h-1 rounded-full bg-[#22c55e] animate-pulse shrink-0" />
85 <span className="max-w-[90px] truncate">{activeStream.name}</span>
86 </>
87 ) : (
88 <>{t("livePanel.channelMenu")}</>
89 )}
90 </button>
91
92 {open && (
93 <div className="absolute right-0 top-full mt-0.5 z-[9999] bg-[var(--bg)] border border-[var(--border)] shadow-[0_8px_32px_rgba(0,0,0,0.4)] min-w-[180px]">
94 {/* Category tabs */}
95 <div className="flex border-b border-[var(--border-subtle)]">
96 {(["news", "sports"] as const).map((tabKey) => (
97 <button
98 key={tabKey}
99 onClick={() => setTab(tabKey)}
100 className={`flex-1 text-[10px] uppercase tracking-wide px-2 py-1.5 font-mono transition-colors ${
101 tab === tabKey
102 ? "text-[var(--text-secondary)] bg-[var(--surface)]"

Callers

nothing calls this directly

Calls 1

useI18nFunction · 0.90

Tested by

no test coverage detected