import { useEffect, useState } from 'react'; import { toast } from './ui/sonner'; import { isFavorite } from '../utils/favorites'; import { handleKeyboardActivate } from '../utils/a11y'; import { ContactAvatar } from './ContactAvatar'; import { ContactStatusInfo } from './ContactStatusInfo'; import type { Channel, Contact, Conversation, Favorite, RadioConfig } from '../types'; interface ChatHeaderProps { conversation: Conversation; contacts: Contact[]; channels: Channel[]; config: RadioConfig | null; favorites: Favorite[]; onTrace: () => void; onToggleFavorite: (type: 'channel' | 'contact', id: string) => void; onSetChannelFloodScopeOverride?: (key: string, floodScopeOverride: string) => void; onDeleteChannel: (key: string) => void; onDeleteContact: (publicKey: string) => void; onOpenContactInfo?: (publicKey: string) => void; onOpenChannelInfo?: (channelKey: string) => void; } export function ChatHeader({ conversation, contacts, channels, config, favorites, onTrace, onToggleFavorite, onSetChannelFloodScopeOverride, onDeleteChannel, onDeleteContact, onOpenContactInfo, onOpenChannelInfo, }: ChatHeaderProps) { const [showKey, setShowKey] = useState(false); useEffect(() => { setShowKey(false); }, [conversation.id]); const activeChannel = conversation.type === 'channel' ? channels.find((channel) => channel.key === conversation.id) : undefined; const isPrivateChannel = conversation.type === 'channel' && !activeChannel?.is_hashtag; const titleClickable = (conversation.type === 'contact' && onOpenContactInfo) || (conversation.type === 'channel' && onOpenChannelInfo); const handleEditFloodScopeOverride = () => { if (conversation.type !== 'channel' || !onSetChannelFloodScopeOverride) return; const nextValue = window.prompt( 'Enter regional override flood scope for this room. This temporarily changes the radio flood scope before send and restores it after, which significantly slows room sends. Leave blank to clear.', activeChannel?.flood_scope_override ?? '' ); if (nextValue === null) return; onSetChannelFloodScopeOverride(conversation.id, nextValue); }; return (
{conversation.type === 'contact' && onOpenContactInfo && ( onOpenContactInfo(conversation.id)} title="View contact info" aria-label={`View info for ${conversation.name}`} > c.public_key === conversation.id)?.type} clickable /> )}

{ if (conversation.type === 'contact' && onOpenContactInfo) { onOpenContactInfo(conversation.id); } else if (conversation.type === 'channel' && onOpenChannelInfo) { onOpenChannelInfo(conversation.id); } } : undefined } > {conversation.type === 'channel' && !conversation.name.startsWith('#') && activeChannel?.is_hashtag ? '#' : ''} {conversation.name}

{isPrivateChannel && !showKey ? ( ) : ( { e.stopPropagation(); navigator.clipboard.writeText(conversation.id); toast.success( conversation.type === 'channel' ? 'Room key copied!' : 'Contact key copied!' ); }} title="Click to copy" aria-label={conversation.type === 'channel' ? 'Copy channel key' : 'Copy contact key'} > {conversation.type === 'channel' ? conversation.id.toLowerCase() : conversation.id} )} {conversation.type === 'channel' && activeChannel?.flood_scope_override && ( Regional override active: {activeChannel.flood_scope_override} )} {conversation.type === 'contact' && (() => { const contact = contacts.find((c) => c.public_key === conversation.id); if (!contact) return null; return ( ); })()}
{conversation.type === 'contact' && ( )} {conversation.type === 'channel' && onSetChannelFloodScopeOverride && ( )} {(conversation.type === 'channel' || conversation.type === 'contact') && ( )} {!(conversation.type === 'channel' && conversation.name === 'Public') && ( )}
); }