import { useState, useCallback } from "react"; import { useNetworks } from "@/hooks/use-networks"; import { cn, removeDuplicates } from "@/lib/utils"; import { useAuthStore } from "@/stores/auth-store"; 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 [name, setName] = useState(() => generateRandomName()); const [everyone, setEveryone] = useState(true); const userId = useAuthStore((s) => s.user?.id); const [selectedIds, setSelectedIds] = useState>(new Set()); const members = (network?.humans ?? []).filter((h) => h.id !== userId); const toggleMember = useCallback((id: string) => { setSelectedIds((prev) => { const next = new Set(prev); if (next.has(id)) next.delete(id); else next.add(id); return next; }); }, []); const buildVisibleTo = useCallback((): string[] => { if (everyone && networkId) return [`network:${networkId}`]; return Array.from(removeDuplicates([...selectedIds, userId].filter(Boolean) as string[])).map((id) => `human:${id}`); }, [everyone, networkId, selectedIds, userId]); 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], ); 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 = selectedIds.has(member.id); const initials = member.email_prefix .slice(0, 2) .toUpperCase(); return (
toggleMember(member.id)} 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
); }