Skip to content

Commit 5144273

Browse files
committed
🤖 Fix circular dependency - observe ChatArea width directly
Previous approach had circular dependency: - Measured ViewContainer (includes ChatArea + Sidebar) - Sidebar width affected container width being measured - Could never collapse properly New architecture: - Observe ChatArea width directly (independent of sidebar) - ChatArea has flex:1 and min-width:750px - When ChatArea compressed (≤800px) → collapse sidebar - When sidebar collapses → ChatArea expands → positive feedback Logic: - chatAreaWidth ≤ 800px → showCollapsed = true - No circular dependency - ChatArea width independent of sidebar - 800px threshold = min(750px) + 50px comfort buffer Debug logging included to verify behavior in live testing. _Generated with `cmux`_
1 parent 909fb71 commit 5144273

File tree

2 files changed

+21
-23
lines changed

2 files changed

+21
-23
lines changed

src/components/AIView.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ const AIViewInner: React.FC<AIViewProps> = ({
203203
workspacePath,
204204
className,
205205
}) => {
206-
const viewContainerRef = useRef<HTMLDivElement>(null);
206+
const chatAreaRef = useRef<HTMLDivElement>(null);
207207

208208
// NEW: Get workspace state from store (only re-renders when THIS workspace changes)
209209
const workspaceState = useWorkspaceState(workspaceId);
@@ -534,7 +534,7 @@ const AIViewInner: React.FC<AIViewProps> = ({
534534
/>
535535
</ChatArea>
536536

537-
<ChatMetaSidebar workspaceId={workspaceId} containerRef={viewContainerRef} />
537+
<ChatMetaSidebar workspaceId={workspaceId} chatAreaRef={chatAreaRef} />
538538
</ViewContainer>
539539
</ChatProvider>
540540
);

src/components/ChatMetaSidebar.tsx

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,18 @@ type TabType = "costs" | "tools";
7474

7575
interface ChatMetaSidebarProps {
7676
workspaceId: string;
77-
containerRef: React.RefObject<HTMLDivElement>;
77+
chatAreaRef: React.RefObject<HTMLDivElement>;
7878
}
7979

80-
export const ChatMetaSidebar: React.FC<ChatMetaSidebarProps> = ({ workspaceId, containerRef }) => {
80+
export const ChatMetaSidebar: React.FC<ChatMetaSidebarProps> = ({ workspaceId, chatAreaRef }) => {
8181
const [selectedTab, setSelectedTab] = usePersistedState<TabType>(
8282
`chat-meta-sidebar-tab:${workspaceId}`,
8383
"costs"
8484
);
8585

8686
const { stats } = useChatContext();
8787
const [use1M] = use1MContext();
88-
const containerSize = useResizeObserver(containerRef);
88+
const chatAreaSize = useResizeObserver(chatAreaRef);
8989

9090
const baseId = `chat-meta-${workspaceId}`;
9191
const costsTabId = `${baseId}-tab-costs`;
@@ -99,24 +99,22 @@ export const ChatMetaSidebar: React.FC<ChatMetaSidebarProps> = ({ workspaceId, c
9999
: { segments: [], totalTokens: 0, totalPercentage: 0 };
100100

101101
// Calculate if we should show collapsed view
102-
// Problem: Container includes both ChatArea + Sidebar, creating circular dependency
103-
// Solution: Check if container has enough width for ChatArea + full sidebar + buffer
104-
// When collapsed: container = ChatArea(750+) + CollapsedSidebar(20) = 770+
105-
// When expanded: container = ChatArea(750+) + FullSidebar(300) = 1050+
106-
// Threshold: If container < 1050px, there's not enough room for full sidebar
107-
const containerWidth = containerSize?.width ?? 2000; // Default to large to avoid flash
108-
const FULL_SIDEBAR_THRESHOLD = 1050; // ChatArea(750) + FullSidebar(300)
109-
const showCollapsed = containerWidth < FULL_SIDEBAR_THRESHOLD;
110-
111-
// Debug logging (temporary)
112-
if (containerSize) {
113-
console.log(
114-
"[ChatMetaSidebar] containerWidth:",
115-
containerWidth,
116-
"showCollapsed:",
117-
showCollapsed
118-
);
119-
}
102+
// Strategy: Observe ChatArea width directly (independent of sidebar width)
103+
// - ChatArea has min-width: 750px and flex: 1
104+
// - When ChatArea is compressed near its minimum, space is tight → collapse sidebar
105+
// - When sidebar collapses (300→20), ChatArea gains 280px → positive feedback loop
106+
// - No circular dependency: ChatArea width doesn't include sidebar
107+
const CHAT_AREA_COMFORTABLE_WIDTH = 800; // Buffer above min-width (750px)
108+
const chatAreaWidth = chatAreaSize?.width ?? 1000; // Default to large to avoid flash
109+
const showCollapsed = chatAreaWidth <= CHAT_AREA_COMFORTABLE_WIDTH;
110+
111+
// Debug logging
112+
console.log(
113+
"[ChatMetaSidebar] chatAreaWidth:",
114+
chatAreaWidth,
115+
"showCollapsed:",
116+
showCollapsed
117+
);
120118

121119
return (
122120
<SidebarContainer

0 commit comments

Comments
 (0)