fix: Optimize panel management, support panel references for sidebar and tab types

This commit is contained in:
Felix NyxJae 2025-02-28 12:06:39 +08:00
parent 1ae4eaa80e
commit 156fe0d9fb
4 changed files with 51 additions and 59 deletions

View file

@ -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<RegisterComman
localResourceRoots: [context.extensionUri],
})
// Save panel references
setPanel(newPanel)
// Save as tab type panel
setPanel(newPanel, "tab")
// TODO: use better svg icon with light and dark variants (see
// https://stackoverflow.com/questions/58365687/vscode-extension-iconpath).
@ -114,7 +129,7 @@ const openClineInNewTab = async ({ context, outputChannel }: Omit<RegisterComman
// Handle panel closing events
newPanel.onDidDispose(() => {
setPanel(undefined)
setPanel(undefined, "tab")
})
// Lock the editor group so clicking on files doesn't open them over the panel

View file

@ -127,51 +127,10 @@ async function showHumanRelayDialog(promptText: string): Promise<string | undefi
},
)
// Check if the panel has been initialized
if (!getPanel()) {
// If the panel does not exist, first open a new panel
vscode.commands.executeCommand("roo-cline.openInNewTab").then(() => {
// 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,
})
})
}

View file

@ -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)

View file

@ -27,12 +27,20 @@ export const HumanRelayDialog: React.FC<HumanRelayDialogProps> = ({
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)