From d5b8f7d462969da8483d09d41dfc484af2d7d852 Mon Sep 17 00:00:00 2001 From: Jack Kingsman Date: Tue, 17 Mar 2026 16:28:05 -0700 Subject: [PATCH] Prevent contact status bar jitter. Closes #68. --- frontend/src/components/ChatHeader.tsx | 163 +++++++++---------------- 1 file changed, 55 insertions(+), 108 deletions(-) diff --git a/frontend/src/components/ChatHeader.tsx b/frontend/src/components/ChatHeader.tsx index 42be98d..378785e 100644 --- a/frontend/src/components/ChatHeader.tsx +++ b/frontend/src/components/ChatHeader.tsx @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useState } from 'react'; import { Bell, Globe2, Info, Route, Star, Trash2 } from 'lucide-react'; import { toast } from './ui/sonner'; import { DirectTraceIcon } from './DirectTraceIcon'; @@ -60,10 +60,8 @@ export function ChatHeader({ onOpenChannelInfo, }: ChatHeaderProps) { const [showKey, setShowKey] = useState(false); - const [contactStatusInline, setContactStatusInline] = useState(true); const [pathDiscoveryOpen, setPathDiscoveryOpen] = useState(false); const [channelOverrideOpen, setChannelOverrideOpen] = useState(false); - const keyTextRef = useRef(null); useEffect(() => { setShowKey(false); @@ -117,43 +115,6 @@ export function ChatHeader({ } }; - useEffect(() => { - if (conversation.type !== 'contact') { - setContactStatusInline(true); - return; - } - - const measure = () => { - const keyElement = keyTextRef.current; - if (!keyElement) return; - const isTruncated = keyElement.scrollWidth > keyElement.clientWidth + 1; - setContactStatusInline(!isTruncated); - }; - - measure(); - - const onResize = () => { - window.requestAnimationFrame(measure); - }; - - window.addEventListener('resize', onResize); - - let observer: ResizeObserver | null = null; - if (typeof ResizeObserver !== 'undefined') { - observer = new ResizeObserver(() => { - window.requestAnimationFrame(measure); - }); - if (keyTextRef.current?.parentElement) { - observer.observe(keyTextRef.current.parentElement); - } - } - - return () => { - window.removeEventListener('resize', onResize); - observer?.disconnect(); - }; - }, [conversation.id, conversation.type, showKey]); - return (
@@ -174,31 +135,16 @@ export function ChatHeader({ /> )} - - - -

- {titleClickable ? ( - - ) : ( + + +

+ {titleClickable ? ( +

- {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' && + !conversation.name.startsWith('#') && + activeChannel?.is_hashtag + ? '#' + : ''} + {conversation.name} )} - - {conversation.type === 'contact' && activeContact && contactStatusInline && ( - - +

+ {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 === 'contact' && activeContact && !contactStatusInline && ( - + {conversation.type === 'contact' && activeContact && ( +