Skip to content

Commit ffeee7e

Browse files
authored
[PROTOBUS] Move openInBrowser to protobus (RooCodeInc#3691)
* openInBrowser_protobus_migration
1 parent 10239f0 commit ffeee7e

File tree

7 files changed

+60
-28
lines changed

7 files changed

+60
-28
lines changed

.changeset/five-sheep-count.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": patch
3+
---
4+
5+
openInBrowser protobus migration

proto/web.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import "common.proto";
99
service WebService {
1010
rpc checkIsImageUrl(StringRequest) returns (IsImageUrl);
1111
rpc fetchOpenGraphData(StringRequest) returns (OpenGraphData);
12+
rpc openInBrowser(StringRequest) returns (Empty);
1213
}
1314

1415
message IsImageUrl {

src/core/controller/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,6 @@ export class Controller {
303303
text: message.text,
304304
})
305305
break
306-
case "openInBrowser":
307-
if (message.url) {
308-
vscode.env.openExternal(vscode.Uri.parse(message.url))
309-
}
310-
break
311306
case "fetchUserCreditsData": {
312307
await this.fetchUserCreditsData()
313308
break
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import * as vscode from "vscode"
2+
import { Controller } from ".."
3+
import { Empty, StringRequest } from "../../../shared/proto/common"
4+
5+
/**
6+
* Opens a URL in the user's default browser
7+
* @param controller The controller instance
8+
* @param request The URL to open
9+
* @returns Empty response since the client doesn't need a return value
10+
*/
11+
export async function openInBrowser(controller: Controller, request: StringRequest): Promise<Empty> {
12+
try {
13+
if (request.value) {
14+
await vscode.env.openExternal(vscode.Uri.parse(request.value))
15+
}
16+
return Empty.create()
17+
} catch (error) {
18+
console.error("Error opening URL in browser:", error)
19+
return Empty.create()
20+
}
21+
}

src/shared/WebviewMessage.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export interface WebviewMessage {
1313
| "newTask"
1414
| "condense"
1515
| "reportBug"
16-
| "openInBrowser"
1716
| "showChatView"
1817
| "requestVsCodeLmModels"
1918
| "authStateChanged"
@@ -54,8 +53,6 @@ export interface WebviewMessage {
5453
// For auth
5554
user?: UserInfo | null
5655
customToken?: string
57-
// For openInBrowser
58-
url?: string
5956
planActSeparateModelsSetting?: boolean
6057
enableCheckpointsSetting?: boolean
6158
mcpMarketplaceEnabled?: boolean

webview-ui/src/components/mcp/chat-display/ImagePreview.tsx

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from "react"
22
import { vscode } from "@/utils/vscode"
3+
import { WebServiceClient } from "@/services/grpc-client"
34
import DOMPurify from "dompurify"
45
import { getSafeHostname, formatUrlForOpening, checkIfImageUrl } from "./utils/mcpRichUtil"
56
import ChatErrorBoundary from "@/components/chat/ChatErrorBoundary"
@@ -232,11 +233,14 @@ class ImagePreview extends React.Component<
232233
borderRadius: "4px",
233234
color: "var(--vscode-errorForeground)",
234235
}}
235-
onClick={() => {
236-
vscode.postMessage({
237-
type: "openInBrowser",
238-
url: DOMPurify.sanitize(url),
239-
})
236+
onClick={async () => {
237+
try {
238+
await WebServiceClient.openInBrowser({
239+
value: DOMPurify.sanitize(url),
240+
})
241+
} catch (err) {
242+
console.error("Error opening URL in browser:", err)
243+
}
240244
}}>
241245
<div style={{ fontWeight: "bold" }}>Failed to load image</div>
242246
<div style={{ fontSize: "12px", marginTop: "4px" }}>{getSafeHostname(url)}</div>
@@ -256,11 +260,14 @@ class ImagePreview extends React.Component<
256260
maxWidth: "100%",
257261
cursor: "pointer",
258262
}}
259-
onClick={() => {
260-
vscode.postMessage({
261-
type: "openInBrowser",
262-
url: DOMPurify.sanitize(formatUrlForOpening(url)),
263-
})
263+
onClick={async () => {
264+
try {
265+
await WebServiceClient.openInBrowser({
266+
value: DOMPurify.sanitize(formatUrlForOpening(url)),
267+
})
268+
} catch (err) {
269+
console.error("Error opening URL in browser:", err)
270+
}
264271
}}>
265272
{/\.svg(\?.*)?$/i.test(url) ? (
266273
// Special handling for SVG images

webview-ui/src/components/mcp/chat-display/LinkPreview.tsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,14 @@ class LinkPreview extends React.Component<LinkPreviewProps, LinkPreviewState> {
238238
maxWidth: "512px",
239239
overflow: "auto",
240240
}}
241-
onClick={() => {
242-
vscode.postMessage({
243-
type: "openInBrowser",
244-
url: DOMPurify.sanitize(url),
245-
})
241+
onClick={async () => {
242+
try {
243+
await WebServiceClient.openInBrowser({
244+
value: DOMPurify.sanitize(url),
245+
})
246+
} catch (err) {
247+
console.error("Error opening URL in browser:", err)
248+
}
246249
}}>
247250
<div style={{ fontWeight: "bold" }}>{errorDisplay}</div>
248251
<div style={{ fontSize: "12px", marginTop: "4px" }}>{getSafeHostname(url)}</div>
@@ -275,11 +278,14 @@ class LinkPreview extends React.Component<LinkPreviewProps, LinkPreviewState> {
275278
height: "128px",
276279
maxWidth: "512px",
277280
}}
278-
onClick={() => {
279-
vscode.postMessage({
280-
type: "openInBrowser",
281-
url: DOMPurify.sanitize(url),
282-
})
281+
onClick={async () => {
282+
try {
283+
await WebServiceClient.openInBrowser({
284+
value: DOMPurify.sanitize(url),
285+
})
286+
} catch (err) {
287+
console.error("Error opening URL in browser:", err)
288+
}
283289
}}>
284290
{data.image && (
285291
<div className="link-preview-image" style={{ width: "128px", height: "128px", flexShrink: 0 }}>

0 commit comments

Comments
 (0)