From 156fe0d9fb74169e2bc9a4367708f4f963917cbf Mon Sep 17 00:00:00 2001 From: Felix NyxJae <18661811993@163.com> Date: Fri, 28 Feb 2025 12:06:39 +0800 Subject: [PATCH] fix: Optimize panel management, support panel references for sidebar and tab types --- src/activate/registerCommands.ts | 37 ++++++++++---- src/api/providers/human-relay.ts | 51 ++----------------- src/core/webview/ClineProvider.ts | 10 ++++ .../human-relay/HumanRelayDialog.tsx | 12 ++++- 4 files changed, 51 insertions(+), 59 deletions(-) diff --git a/src/activate/registerCommands.ts b/src/activate/registerCommands.ts index 8cc895f291..b520e0cb8e 100644 --- a/src/activate/registerCommands.ts +++ b/src/activate/registerCommands.ts @@ -3,17 +3,32 @@ import delay from "delay" import { ClineProvider } from "../core/webview/ClineProvider" -// Add a global variable to store panel references -let panel: vscode.WebviewPanel | undefined = undefined +// Store panel references in both modes +let sidebarPanel: vscode.WebviewView | undefined = undefined +let tabPanel: vscode.WebviewPanel | undefined = undefined -// Get the panel function for command access -export function getPanel(): vscode.WebviewPanel | undefined { - return panel +/** + * Get the currently active panel + * @returns WebviewPanelꈖWebviewView + */ +export function getPanel(): vscode.WebviewPanel | vscode.WebviewView | undefined { + return tabPanel || sidebarPanel } -// Setting the function of the panel -export function setPanel(newPanel: vscode.WebviewPanel | undefined): void { - panel = newPanel +/** + * Set panel references + */ +export function setPanel( + newPanel: vscode.WebviewPanel | vscode.WebviewView | undefined, + type: "sidebar" | "tab", +): void { + if (type === "sidebar") { + sidebarPanel = newPanel as vscode.WebviewView + tabPanel = undefined + } else { + tabPanel = newPanel as vscode.WebviewPanel + sidebarPanel = undefined + } } export type RegisterCommandOptions = { @@ -100,8 +115,8 @@ const openClineInNewTab = async ({ context, outputChannel }: Omit { - setPanel(undefined) + setPanel(undefined, "tab") }) // Lock the editor group so clicking on files doesn't open them over the panel diff --git a/src/api/providers/human-relay.ts b/src/api/providers/human-relay.ts index 2911e24eaf..618ae847de 100644 --- a/src/api/providers/human-relay.ts +++ b/src/api/providers/human-relay.ts @@ -127,51 +127,10 @@ async function showHumanRelayDialog(promptText: string): Promise { - // Wait for the panel to be created before showing the human relay dialog - setTimeout(() => { - vscode.commands.executeCommand("roo-code.showHumanRelayDialog", { - requestId, - promptText, - }) - }, 500) // Allow some time for the panel to be created - }) - } else { - // If the panel already exists, directly show the dialog - vscode.commands.executeCommand("roo-code.showHumanRelayDialog", { - requestId, - promptText, - }) - } - - // Provide a temporary UI in case the WebView fails to load - vscode.window - .showInformationMessage( - "Please paste the copied message to the AI, then copy the response back into the dialog", - { - modal: true, - detail: "The message has been copied to the clipboard. If the dialog does not open, please try using the input box.", - }, - "Use Input Box", - ) - .then((selection) => { - if (selection === "Use Input Box") { - // Unregister the callback - vscode.commands.executeCommand("roo-code.unregisterHumanRelayCallback", requestId) - - vscode.window - .showInputBox({ - prompt: "Please paste the AI's response here", - placeHolder: "Paste the AI's response here...", - ignoreFocusOut: true, - }) - .then((input) => { - resolve(input || undefined) - }) - } - }) + // Open the dialog box directly using the current panel + vscode.commands.executeCommand("roo-code.showHumanRelayDialog", { + requestId, + promptText, + }) }) } diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index e781a36dbe..c87406d3d4 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -7,6 +7,7 @@ import pWaitFor from "p-wait-for" import * as path from "path" import * as vscode from "vscode" import simpleGit from "simple-git" +import { setPanel } from "../../activate/registerCommands" import { ApiConfiguration, ApiProvider, ModelInfo } from "../../shared/api" import { findLast } from "../../shared/array" @@ -233,6 +234,15 @@ export class ClineProvider implements vscode.WebviewViewProvider { this.outputChannel.appendLine("Resolving webview view") this.view = webviewView + // Set panel reference according to webview type + if ("onDidChangeViewState" in webviewView) { + // Tag page type + setPanel(webviewView, "tab") + } else if ("onDidChangeVisibility" in webviewView) { + // Sidebar Type + setPanel(webviewView, "sidebar") + } + // Initialize sound enabled state this.getState().then(({ soundEnabled }) => { setSoundEnabled(soundEnabled ?? false) diff --git a/webview-ui/src/components/human-relay/HumanRelayDialog.tsx b/webview-ui/src/components/human-relay/HumanRelayDialog.tsx index ea306d11d7..61d4cbe213 100644 --- a/webview-ui/src/components/human-relay/HumanRelayDialog.tsx +++ b/webview-ui/src/components/human-relay/HumanRelayDialog.tsx @@ -27,12 +27,20 @@ export const HumanRelayDialog: React.FC = ({ onCancel, }) => { const [response, setResponse] = React.useState("") - const { onCopy } = useClipboard(promptText) + const { copy } = useClipboard() const [isCopyClicked, setIsCopyClicked] = React.useState(false) + // Listen to isOpen changes, clear the input box when the dialog box is opened + React.useEffect(() => { + if (isOpen) { + setResponse("") + setIsCopyClicked(false) + } + }, [isOpen]) + // Copy to clipboard and show a success message const handleCopy = () => { - onCopy() + copy(promptText) setIsCopyClicked(true) setTimeout(() => { setIsCopyClicked(false)