import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuthStore } from '@/stores/auth-store'; import { apiClient } from '@/api/client'; import { isParticleDeleted, type Particle } from '@/api/types'; import { particlePath, toFirestoreDocPath } from '@/lib/particle-path'; import { AvatarGroup } from '@/components/ui/avatar'; import { HumanAvatar } from '@/components/human-avatar'; import { Tooltip, TooltipContent, TooltipTrigger, } from '@/components/ui/tooltip'; import { useNetwork } from '@/hooks/use-networks'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { Settings, CircleCheckBig, CircleDot, EllipsisVertical, Pencil, Lock, Globe, Trash2, } from 'lucide-react'; import { updateStreamStatus } from '@/lib/firestore-particles'; import { RenameStreamOverlay } from '@/features/particles/rename-stream-overlay'; import { DeleteParticleOverlay } from '@/features/particles/delete-particle-overlay'; import { StreamMembersOverlay } from '@/features/particles/stream-members-overlay'; import { parseVisibleTo } from '@/lib/stream-visibility'; import { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, } from '@/components/ui/breadcrumb'; import { WindowControls } from '@/components/window-controls'; import { RelativeTimestamp } from '@/components/relative-timestamp'; import { useStreamPresence } from '@/features/particles/stream-presence-context'; import { resolveHumanDisplay } from '@/lib/humans'; import { platform } from '@/lib/platform'; import { requireDesktop } from '@/lib/platform/desktop-only'; function getParticleDisplayName(particle: Particle): string { switch (particle.type) { case 'stream': case 'folder': return particle.properties.name; case 'quest': return particle.properties.title; case 'paper': return particle.properties.title; case 'file': return particle.properties.filename; case 'text': return particle.properties.content.slice(0, 30); case 'media': return particle.type; } } interface TopBarProps { networkId: string; particle: Particle | null; streamParticle: Particle & { type: 'stream' }; } export function TopBar({ networkId, particle, streamParticle }: TopBarProps) { const navigate = useNavigate(); const network = useNetwork(networkId); const userId = useAuthStore((s) => s.user?.id); const isCreator = !!userId && userId === streamParticle.created_by_human_id; const [renameOpen, setRenameOpen] = useState(false); const [membersOpen, setMembersOpen] = useState(false); const [deleteOpen, setDeleteOpen] = useState(false); const canDeleteParticle = !!particle && !!userId && particle.created_by_human_id === userId && particle.type !== 'stream' && particle.type !== 'folder' && !isParticleDeleted(particle); const huddleParticipants = streamParticle.huddle_active_participants ?? []; const hasActiveHuddle = huddleParticipants.length > 0; const handleJoinHuddle = () => { if (!requireDesktop('Huddle')) return; apiClient .getLivekitToken(networkId, streamParticle.id) .then(({ token, server_url }) => { platform.huddle.open({ token, serverUrl: server_url }); }); }; return (