import { useState, useEffect, useRef, useCallback } from "react"; import { useNetworks } from "@/hooks/use-networks"; import { cn } from "@/lib/utils"; import { generateRandomName } from "@/lib/random-name"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Checkbox } from "@/components/ui/checkbox"; import { ScrollArea } from "@/components/ui/scroll-area"; interface ConfigureStreamStepProps { networkId: string | null; onCancel: () => void; onSubmit: (streamName: string, visibleTo: string[]) => void; } export function ConfigureStreamStep({ networkId, onCancel, onSubmit, }: ConfigureStreamStepProps) { const { data: networks } = useNetworks(); const network = networks?.find((n) => n.id === networkId); const members = network?.humans ?? []; const [name, setName] = useState(() => generateRandomName()); const [everyone, setEveryone] = useState(true); const [selectedEmails, setSelectedEmails] = useState>(new Set()); const toggleMember = useCallback((email: string) => { setSelectedEmails((prev) => { const next = new Set(prev); if (next.has(email)) next.delete(email); else next.add(email); return next; }); }, []); const buildVisibleTo = useCallback((): string[] => { if (everyone && networkId) return [`network:${networkId}`]; return Array.from(selectedEmails).map((e) => `human:${e}`); }, [everyone, networkId, selectedEmails]); const handleSubmit = useCallback(() => { if (!name.trim() || !networkId) return; onSubmit(name.trim(), buildVisibleTo()); }, [name, networkId, onSubmit, buildVisibleTo]); const handleKeyDown = useCallback( (e: React.KeyboardEvent) => { switch (e.key) { case "Escape": e.preventDefault(); onCancel(); return; case "Enter": if (e.metaKey || e.ctrlKey) { e.preventDefault(); handleSubmit(); } return; } }, [onCancel, handleSubmit, members, name, toggleMember], ); return (
{/* Stream name */}
{ setName(e.target.value); }} placeholder="Give it a name..." className="border-white/10 bg-white/5 text-white placeholder-white/30 focus-visible:border-white/30 focus-visible:ring-0" />
{/* Visibility */}
{/* Everyone in network */}
setEveryone((prev) => !prev)} className={cn( "flex w-full cursor-pointer items-center gap-2.5 px-3 py-2 text-left text-sm transition-colors", "text-white/70 hover:bg-white/5", )} > setEveryone(checked === true)} tabIndex={-1} className="pointer-events-none" /> Everyone in network
{/* Per-member selection */} {!everyone && members.length > 0 && (
{members.map((member, index) => { const isSelected = selectedEmails.has(member.email); const initials = member.email_prefix .slice(0, 2) .toUpperCase(); return (
toggleMember(member.email)} className={cn( "flex w-full cursor-pointer items-center gap-2.5 rounded px-3 py-1.5 text-left text-sm transition-colors", "text-white/70 hover:bg-white/5", )} > {initials} {member.email_prefix}
); })}
)}
{/* Keyboard hints */}
Esc {" "} cancel ⌘+Enter {" "} create
); }