import { useState, useCallback } from 'react'; import { useNetworks } from '@/hooks/use-networks'; import { cn, removeDuplicates } from '@/lib/utils'; import { metaKey } from '@/lib/platform'; import { useAuthStore } from '@/stores/auth-store'; import { generateRandomName } from '@/lib/random-name'; import { Input } from '@/components/ui/input'; import { KeyHint } from '@/components/key-hint'; 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) => { 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 */}
cancel create
); }