Skip to content

Commit 97e34a6

Browse files
committed
feat(ChatScreen):Empty input box contents when the Unified Processing Panel opens
1 parent b2d9e4f commit 97e34a6

2 files changed

Lines changed: 90 additions & 82 deletions

File tree

source/ui/components/chat/ChatFooter.tsx

Lines changed: 81 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,10 @@ const ChatFooter = React.memo(function ChatFooter(props: ChatFooterProps) {
247247
};
248248
}, [copyStatusMessage]);
249249

250-
// When a panel hides the input area, clear the draft so the old command text
251-
// doesn't get restored when the panel closes and ChatInput remounts.
250+
// 统一处理:ChatFooter 内部会把 ChatInput 替换为 ReviewCommitPanel / IdeSelectPanel
251+
// 这两类面板(见下方条件渲染)。这些面板打开时 footer 整体仍在渲染,
252+
// ChatScreen 的 shouldShowFooter 侧通用逻辑覆盖不到,需要在此清空 draft,
253+
// 避免面板关闭后 ChatInput 重新挂载时把旧文本恢复进输入框。
252254
useEffect(() => {
253255
if (props.showReviewCommitPanel || props.showIdeSelectPanel) {
254256
props.onDraftChange(null);
@@ -257,88 +259,85 @@ const ChatFooter = React.memo(function ChatFooter(props: ChatFooterProps) {
257259

258260
return (
259261
<>
260-
{!props.showReviewCommitPanel && !props.showIdeSelectPanel && (
261-
<>
262-
<LoadingIndicator
263-
isStreaming={props.isStreaming}
264-
isStopping={props.isStopping}
265-
isSaving={props.isSaving}
266-
hasPendingToolConfirmation={props.hasPendingToolConfirmation}
267-
hasPendingUserQuestion={props.hasPendingUserQuestion}
268-
hasBlockingOverlay={props.hasBlockingOverlay}
269-
terminalWidth={props.terminalWidth}
270-
animationFrame={props.animationFrame}
271-
retryStatus={props.retryStatus}
272-
codebaseSearchStatus={props.codebaseSearchStatus}
273-
isReasoning={props.isReasoning}
274-
streamTokenCount={props.streamTokenCount}
275-
elapsedSeconds={props.elapsedSeconds}
276-
currentModel={props.currentModel}
277-
teamMode={props.teamMode}
278-
/>
279-
280-
{props.btwPrompt ? (
281-
<Suspense
282-
fallback={
283-
<Box>
284-
<Text>
285-
<Spinner type="dots" /> Loading...
286-
</Text>
287-
</Box>
288-
}
289-
>
290-
<BtwPanel
291-
prompt={props.btwPrompt}
292-
onClose={props.onBtwClose}
293-
/>
294-
</Suspense>
295-
) : (
296-
<ChatInput
297-
onSubmit={props.onSubmit}
298-
onCommand={props.onCommand}
299-
placeholder={t.chatScreen.inputPlaceholder}
300-
disabled={props.disabled}
301-
disableKeyboardNavigation={props.showBackgroundPanel}
302-
isProcessing={props.isProcessing}
303-
chatHistory={props.chatHistory}
304-
onHistorySelect={props.handleHistorySelect}
305-
yoloMode={props.yoloMode}
306-
setYoloMode={props.setYoloMode}
307-
planMode={props.planMode}
308-
setPlanMode={props.setPlanMode}
309-
vulnerabilityHuntingMode={props.vulnerabilityHuntingMode}
310-
setVulnerabilityHuntingMode={props.setVulnerabilityHuntingMode}
262+
{!props.showReviewCommitPanel && !props.showIdeSelectPanel && (
263+
<>
264+
<LoadingIndicator
265+
isStreaming={props.isStreaming}
266+
isStopping={props.isStopping}
267+
isSaving={props.isSaving}
268+
hasPendingToolConfirmation={props.hasPendingToolConfirmation}
269+
hasPendingUserQuestion={props.hasPendingUserQuestion}
270+
hasBlockingOverlay={props.hasBlockingOverlay}
271+
terminalWidth={props.terminalWidth}
272+
animationFrame={props.animationFrame}
273+
retryStatus={props.retryStatus}
274+
codebaseSearchStatus={props.codebaseSearchStatus}
275+
isReasoning={props.isReasoning}
276+
streamTokenCount={props.streamTokenCount}
277+
elapsedSeconds={props.elapsedSeconds}
278+
currentModel={props.currentModel}
311279
teamMode={props.teamMode}
312-
setTeamMode={props.setTeamMode}
313-
contextUsage={props.contextUsage}
314-
initialContent={props.initialContent}
315-
draftContent={props.draftContent}
316-
onDraftChange={props.onDraftChange}
317-
onContextPercentageChange={props.onContextPercentageChange}
318-
showProfilePicker={props.showProfilePicker}
319-
setShowProfilePicker={props.setShowProfilePicker}
320-
profileSelectedIndex={props.profileSelectedIndex}
321-
setProfileSelectedIndex={props.setProfileSelectedIndex}
322-
getFilteredProfiles={props.getFilteredProfiles}
323-
handleProfileSelect={props.handleProfileSelect}
324-
profileSearchQuery={props.profileSearchQuery}
325-
setProfileSearchQuery={props.setProfileSearchQuery}
326-
onSwitchProfile={props.onSwitchProfile}
327-
onCopyInputSuccess={() => {
328-
setCopyStatusMessage({
329-
text: `✔ ${t.chatScreen.inputCopySuccess}`,
330-
timestamp: Date.now(),
331-
});
332-
}}
333-
onCopyInputError={errorMessage => {
334-
setCopyStatusMessage({
335-
text: `✖ ${t.chatScreen.inputCopyFailedPrefix}: ${errorMessage}`,
336-
isError: true,
337-
timestamp: Date.now(),
338-
});
339-
}}
340280
/>
341-
)}
281+
282+
{props.btwPrompt ? (
283+
<Suspense
284+
fallback={
285+
<Box>
286+
<Text>
287+
<Spinner type="dots" /> Loading...
288+
</Text>
289+
</Box>
290+
}
291+
>
292+
<BtwPanel prompt={props.btwPrompt} onClose={props.onBtwClose} />
293+
</Suspense>
294+
) : (
295+
<ChatInput
296+
onSubmit={props.onSubmit}
297+
onCommand={props.onCommand}
298+
placeholder={t.chatScreen.inputPlaceholder}
299+
disabled={props.disabled}
300+
disableKeyboardNavigation={props.showBackgroundPanel}
301+
isProcessing={props.isProcessing}
302+
chatHistory={props.chatHistory}
303+
onHistorySelect={props.handleHistorySelect}
304+
yoloMode={props.yoloMode}
305+
setYoloMode={props.setYoloMode}
306+
planMode={props.planMode}
307+
setPlanMode={props.setPlanMode}
308+
vulnerabilityHuntingMode={props.vulnerabilityHuntingMode}
309+
setVulnerabilityHuntingMode={props.setVulnerabilityHuntingMode}
310+
teamMode={props.teamMode}
311+
setTeamMode={props.setTeamMode}
312+
contextUsage={props.contextUsage}
313+
initialContent={props.initialContent}
314+
draftContent={props.draftContent}
315+
onDraftChange={props.onDraftChange}
316+
onContextPercentageChange={props.onContextPercentageChange}
317+
showProfilePicker={props.showProfilePicker}
318+
setShowProfilePicker={props.setShowProfilePicker}
319+
profileSelectedIndex={props.profileSelectedIndex}
320+
setProfileSelectedIndex={props.setProfileSelectedIndex}
321+
getFilteredProfiles={props.getFilteredProfiles}
322+
handleProfileSelect={props.handleProfileSelect}
323+
profileSearchQuery={props.profileSearchQuery}
324+
setProfileSearchQuery={props.setProfileSearchQuery}
325+
onSwitchProfile={props.onSwitchProfile}
326+
onCopyInputSuccess={() => {
327+
setCopyStatusMessage({
328+
text: `✔ ${t.chatScreen.inputCopySuccess}`,
329+
timestamp: Date.now(),
330+
});
331+
}}
332+
onCopyInputError={errorMessage => {
333+
setCopyStatusMessage({
334+
text: `✖ ${t.chatScreen.inputCopyFailedPrefix}: ${errorMessage}`,
335+
isError: true,
336+
timestamp: Date.now(),
337+
});
338+
}}
339+
/>
340+
)}
342341

343342
{showTodos && todos.length > 0 && (
344343
<Box marginTop={1}>

source/ui/pages/ChatScreen.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,15 @@ export default function ChatScreen({
404404
!schedulerExecutionState.state.isRunning &&
405405
!hasBlockingPanel &&
406406
!snapshotState.pendingRollback;
407+
408+
// 统一处理:任何会隐藏输入框的场景(面板打开、footer 隐藏等),
409+
// 都需要清空 draftContent,避免面板关闭后 ChatInput 重新挂载时
410+
// 通过 draftContent 把旧文本恢复回输入框。
411+
useEffect(() => {
412+
if (!shouldShowFooter) {
413+
setInputDraftContent(null);
414+
}
415+
}, [shouldShowFooter, setInputDraftContent]);
407416
const footerContextUsage = streamingState.contextUsage
408417
? {
409418
inputTokens: streamingState.contextUsage.prompt_tokens,

0 commit comments

Comments
 (0)