diff --git a/frontend/src/components/AppShell.tsx b/frontend/src/components/AppShell.tsx
index 8481f7a..d283508 100644
--- a/frontend/src/components/AppShell.tsx
+++ b/frontend/src/components/AppShell.tsx
@@ -178,7 +178,14 @@ export function AppShell({
{activeSidebarContent}
-
+ {
+ event.preventDefault();
+ }}
+ >
Navigation
Sidebar navigation
diff --git a/frontend/src/components/ChatHeader.tsx b/frontend/src/components/ChatHeader.tsx
index 0631b78..d9e429f 100644
--- a/frontend/src/components/ChatHeader.tsx
+++ b/frontend/src/components/ChatHeader.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useState } from 'react';
+import { useEffect, useRef, useState } from 'react';
import { Bell, Globe2, Info, Star, Trash2 } from 'lucide-react';
import { toast } from './ui/sonner';
import { DirectTraceIcon } from './DirectTraceIcon';
@@ -48,6 +48,8 @@ export function ChatHeader({
onOpenChannelInfo,
}: ChatHeaderProps) {
const [showKey, setShowKey] = useState(false);
+ const [contactStatusInline, setContactStatusInline] = useState(true);
+ const keyTextRef = useRef(null);
useEffect(() => {
setShowKey(false);
@@ -104,6 +106,43 @@ 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 (
@@ -126,8 +165,8 @@ export function ChatHeader({
)}
-
-
+
+
{titleClickable ? (
+ {conversation.type === 'contact' && activeContact && !contactStatusInline && (
+
+
+
+ )}
{conversation.type === 'channel' && activeFloodScopeDisplay && (