Skip to content

Commit 156fe0d

Browse files
committed
fix: Optimize panel management, support panel references for sidebar and tab types
1 parent 1ae4eaa commit 156fe0d

File tree

4 files changed

+52
-60
lines changed

4 files changed

+52
-60
lines changed

src/activate/registerCommands.ts

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,32 @@ import delay from "delay"
33

44
import { ClineProvider } from "../core/webview/ClineProvider"
55

6-
// Add a global variable to store panel references
7-
let panel: vscode.WebviewPanel | undefined = undefined
8-
9-
// Get the panel function for command access
10-
export function getPanel(): vscode.WebviewPanel | undefined {
11-
return panel
6+
// Store panel references in both modes
7+
let sidebarPanel: vscode.WebviewView | undefined = undefined
8+
let tabPanel: vscode.WebviewPanel | undefined = undefined
9+
10+
/**
11+
* Get the currently active panel
12+
* @returns WebviewPanel或WebviewView
13+
*/
14+
export function getPanel(): vscode.WebviewPanel | vscode.WebviewView | undefined {
15+
return tabPanel || sidebarPanel
1216
}
1317

14-
// Setting the function of the panel
15-
export function setPanel(newPanel: vscode.WebviewPanel | undefined): void {
16-
panel = newPanel
18+
/**
19+
* Set panel references
20+
*/
21+
export function setPanel(
22+
newPanel: vscode.WebviewPanel | vscode.WebviewView | undefined,
23+
type: "sidebar" | "tab",
24+
): void {
25+
if (type === "sidebar") {
26+
sidebarPanel = newPanel as vscode.WebviewView
27+
tabPanel = undefined
28+
} else {
29+
tabPanel = newPanel as vscode.WebviewPanel
30+
sidebarPanel = undefined
31+
}
1732
}
1833

1934
export type RegisterCommandOptions = {
@@ -100,8 +115,8 @@ const openClineInNewTab = async ({ context, outputChannel }: Omit<RegisterComman
100115
localResourceRoots: [context.extensionUri],
101116
})
102117

103-
// Save panel references
104-
setPanel(newPanel)
118+
// Save as tab type panel
119+
setPanel(newPanel, "tab")
105120

106121
// TODO: use better svg icon with light and dark variants (see
107122
// https://stackoverflow.com/questions/58365687/vscode-extension-iconpath).
@@ -114,7 +129,7 @@ const openClineInNewTab = async ({ context, outputChannel }: Omit<RegisterComman
114129

115130
// Handle panel closing events
116131
newPanel.onDidDispose(() => {
117-
setPanel(undefined)
132+
setPanel(undefined, "tab")
118133
})
119134

120135
// Lock the editor group so clicking on files doesn't open them over the panel

src/api/providers/human-relay.ts

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -127,51 +127,10 @@ async function showHumanRelayDialog(promptText: string): Promise<string | undefi
127127
},
128128
)
129129

130-
// Check if the panel has been initialized
131-
if (!getPanel()) {
132-
// If the panel does not exist, first open a new panel
133-
vscode.commands.executeCommand("roo-cline.openInNewTab").then(() => {
134-
// Wait for the panel to be created before showing the human relay dialog
135-
setTimeout(() => {
136-
vscode.commands.executeCommand("roo-code.showHumanRelayDialog", {
137-
requestId,
138-
promptText,
139-
})
140-
}, 500) // Allow some time for the panel to be created
141-
})
142-
} else {
143-
// If the panel already exists, directly show the dialog
144-
vscode.commands.executeCommand("roo-code.showHumanRelayDialog", {
145-
requestId,
146-
promptText,
147-
})
148-
}
149-
150-
// Provide a temporary UI in case the WebView fails to load
151-
vscode.window
152-
.showInformationMessage(
153-
"Please paste the copied message to the AI, then copy the response back into the dialog",
154-
{
155-
modal: true,
156-
detail: "The message has been copied to the clipboard. If the dialog does not open, please try using the input box.",
157-
},
158-
"Use Input Box",
159-
)
160-
.then((selection) => {
161-
if (selection === "Use Input Box") {
162-
// Unregister the callback
163-
vscode.commands.executeCommand("roo-code.unregisterHumanRelayCallback", requestId)
164-
165-
vscode.window
166-
.showInputBox({
167-
prompt: "Please paste the AI's response here",
168-
placeHolder: "Paste the AI's response here...",
169-
ignoreFocusOut: true,
170-
})
171-
.then((input) => {
172-
resolve(input || undefined)
173-
})
174-
}
175-
})
130+
// Open the dialog box directly using the current panel
131+
vscode.commands.executeCommand("roo-code.showHumanRelayDialog", {
132+
requestId,
133+
promptText,
134+
})
176135
})
177136
}

src/core/webview/ClineProvider.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import pWaitFor from "p-wait-for"
77
import * as path from "path"
88
import * as vscode from "vscode"
99
import simpleGit from "simple-git"
10+
import { setPanel } from "../../activate/registerCommands"
1011

1112
import { ApiConfiguration, ApiProvider, ModelInfo } from "../../shared/api"
1213
import { findLast } from "../../shared/array"
@@ -233,6 +234,15 @@ export class ClineProvider implements vscode.WebviewViewProvider {
233234
this.outputChannel.appendLine("Resolving webview view")
234235
this.view = webviewView
235236

237+
// Set panel reference according to webview type
238+
if ("onDidChangeViewState" in webviewView) {
239+
// Tag page type
240+
setPanel(webviewView, "tab")
241+
} else if ("onDidChangeVisibility" in webviewView) {
242+
// Sidebar Type
243+
setPanel(webviewView, "sidebar")
244+
}
245+
236246
// Initialize sound enabled state
237247
this.getState().then(({ soundEnabled }) => {
238248
setSoundEnabled(soundEnabled ?? false)

webview-ui/src/components/human-relay/HumanRelayDialog.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,20 @@ export const HumanRelayDialog: React.FC<HumanRelayDialogProps> = ({
2727
onCancel,
2828
}) => {
2929
const [response, setResponse] = React.useState("")
30-
const { onCopy } = useClipboard(promptText)
30+
const { copy } = useClipboard()
3131
const [isCopyClicked, setIsCopyClicked] = React.useState(false)
3232

33+
// Listen to isOpen changes, clear the input box when the dialog box is opened
34+
React.useEffect(() => {
35+
if (isOpen) {
36+
setResponse("")
37+
setIsCopyClicked(false)
38+
}
39+
}, [isOpen])
40+
3341
// Copy to clipboard and show a success message
3442
const handleCopy = () => {
35-
onCopy()
43+
copy(promptText)
3644
setIsCopyClicked(true)
3745
setTimeout(() => {
3846
setIsCopyClicked(false)

0 commit comments

Comments
 (0)