qwen-code/packages/cli/src/ui/layouts/DefaultAppLayout.tsx
Shaojin Wen e855229453
Merge pull request #2776 from QwenLM/feat/enhance-btw-command
feat(cli): enhance /btw side question with improved prompt and Ctrl+C/D cancel
2026-04-03 19:17:12 +08:00

92 lines
3.3 KiB
TypeScript

/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import type React from 'react';
import { useEffect, useRef } from 'react';
import { Box } from 'ink';
import { MainContent } from '../components/MainContent.js';
import { DialogManager } from '../components/DialogManager.js';
import { Composer } from '../components/Composer.js';
import { ExitWarning } from '../components/ExitWarning.js';
import { BtwMessage } from '../components/messages/BtwMessage.js';
import { AgentTabBar } from '../components/agent-view/AgentTabBar.js';
import { AgentChatView } from '../components/agent-view/AgentChatView.js';
import { AgentComposer } from '../components/agent-view/AgentComposer.js';
import { useUIState } from '../contexts/UIStateContext.js';
import { useUIActions } from '../contexts/UIActionsContext.js';
import { useAgentViewState } from '../contexts/AgentViewContext.js';
import { useTerminalSize } from '../hooks/useTerminalSize.js';
export const DefaultAppLayout: React.FC = () => {
const uiState = useUIState();
const { refreshStatic } = useUIActions();
const { activeView, agents } = useAgentViewState();
const { columns: terminalWidth } = useTerminalSize();
const hasAgents = agents.size > 0;
const isAgentTab = activeView !== 'main' && agents.has(activeView);
// Clear terminal on view switch so previous view's <Static> output
// is removed. refreshStatic clears the terminal and bumps the
// historyRemountKey so MainContent's <Static> re-renders all items
// when switching back.
const prevViewRef = useRef(activeView);
useEffect(() => {
if (prevViewRef.current !== activeView) {
prevViewRef.current = activeView;
refreshStatic();
}
}, [activeView, refreshStatic]);
return (
<Box flexDirection="column" width={terminalWidth}>
{isAgentTab ? (
<>
{/* Agent view: chat history + agent-specific composer */}
<AgentChatView agentId={activeView} />
<Box flexDirection="column" ref={uiState.mainControlsRef}>
<AgentComposer key={activeView} agentId={activeView} />
<ExitWarning />
</Box>
</>
) : (
<>
{/* Main view: conversation history + main composer / dialogs */}
<MainContent />
<Box flexDirection="column" ref={uiState.mainControlsRef}>
{uiState.dialogsVisible ? (
<Box
marginX={2}
flexDirection="column"
width={uiState.mainAreaWidth}
>
<DialogManager
terminalWidth={uiState.terminalWidth}
addItem={uiState.historyManager.addItem}
/>
</Box>
) : (
<>
{uiState.btwItem && (
<Box marginX={2} width={uiState.mainAreaWidth}>
<BtwMessage
btw={uiState.btwItem.btw}
containerWidth={uiState.mainAreaWidth}
/>
</Box>
)}
<Composer />
</>
)}
<ExitWarning />
</Box>
</>
)}
{/* Tab bar: visible whenever in-process agents exist and input is active */}
{hasAgents && !uiState.dialogsVisible && <AgentTabBar />}
</Box>
);
};