fix: open external links in VS Code runtime
Route shared URL opening through VS Code host instead of webview window APIs Add a VS Code runtime URL-open API and bridge handler using vscode.env.openExternal Keep shared URL helper behavior unchanged for desktop and web
This commit is contained in:
@@ -619,6 +619,7 @@ export interface EditorAPI {
|
|||||||
export interface VSCodeAPI {
|
export interface VSCodeAPI {
|
||||||
executeCommand(command: string, ...args: unknown[]): Promise<unknown>;
|
executeCommand(command: string, ...args: unknown[]): Promise<unknown>;
|
||||||
openAgentManager(): Promise<void>;
|
openAgentManager(): Promise<void>;
|
||||||
|
openExternalUrl(url: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PushSubscribePayload {
|
export interface PushSubscribePayload {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { getRegisteredRuntimeAPIs } from '@/contexts/runtimeAPIRegistry';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility for opening external URLs with Tauri shell support.
|
* Utility for opening external URLs with Tauri shell support.
|
||||||
* In desktop runtime, uses tauri.shell.open() for proper system browser handling.
|
* In desktop runtime, uses tauri.shell.open() for proper system browser handling.
|
||||||
@@ -55,6 +57,16 @@ export const openExternalUrl = async (url: string): Promise<boolean> => {
|
|||||||
|
|
||||||
const normalizedTarget = parsed.toString();
|
const normalizedTarget = parsed.toString();
|
||||||
|
|
||||||
|
const runtimeApis = getRegisteredRuntimeAPIs();
|
||||||
|
if (runtimeApis?.runtime?.isVSCode && runtimeApis.vscode?.openExternalUrl) {
|
||||||
|
try {
|
||||||
|
await runtimeApis.vscode.openExternalUrl(normalizedTarget);
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const tauri = (window as unknown as { __TAURI__?: TauriShell }).__TAURI__;
|
const tauri = (window as unknown as { __TAURI__?: TauriShell }).__TAURI__;
|
||||||
if (tauri?.shell?.open) {
|
if (tauri?.shell?.open) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -3139,6 +3139,21 @@ export async function handleBridgeMessage(message: BridgeRequest, ctx?: BridgeCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'vscode:openExternalUrl': {
|
||||||
|
const { url } = (payload || {}) as { url?: string };
|
||||||
|
const target = typeof url === 'string' ? url.trim() : '';
|
||||||
|
if (!target) {
|
||||||
|
return { id, type, success: false, error: 'URL is required' };
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await vscode.env.openExternal(vscode.Uri.parse(target));
|
||||||
|
return { id, type, success: true, data: { opened: true } };
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||||
|
return { id, type, success: false, error: errorMessage };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case 'notifications:can-notify': {
|
case 'notifications:can-notify': {
|
||||||
return { id, type, success: true, data: true };
|
return { id, type, success: true, data: true };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -138,6 +138,10 @@ export async function executeVSCodeCommand(command: string, args?: unknown[]): P
|
|||||||
return sendBridgeMessage<{ result?: unknown }>('vscode:command', { command, args });
|
return sendBridgeMessage<{ result?: unknown }>('vscode:command', { command, args });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function openVSCodeExternalUrl(url: string): Promise<void> {
|
||||||
|
await sendBridgeMessage('vscode:openExternalUrl', { url });
|
||||||
|
}
|
||||||
|
|
||||||
type CommandHandler = (payload: unknown) => void;
|
type CommandHandler = (payload: unknown) => void;
|
||||||
const commandHandlers = new Map<string, CommandHandler>();
|
const commandHandlers = new Map<string, CommandHandler>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { VSCodeAPI } from '@openchamber/ui/lib/api/types';
|
import type { VSCodeAPI } from '@openchamber/ui/lib/api/types';
|
||||||
import { executeVSCodeCommand } from './bridge';
|
import { executeVSCodeCommand, openVSCodeExternalUrl } from './bridge';
|
||||||
|
|
||||||
export const createVSCodeActionsAPI = (): VSCodeAPI => ({
|
export const createVSCodeActionsAPI = (): VSCodeAPI => ({
|
||||||
async executeCommand(command: string, ...args: unknown[]): Promise<unknown> {
|
async executeCommand(command: string, ...args: unknown[]): Promise<unknown> {
|
||||||
@@ -10,4 +10,8 @@ export const createVSCodeActionsAPI = (): VSCodeAPI => ({
|
|||||||
async openAgentManager(): Promise<void> {
|
async openAgentManager(): Promise<void> {
|
||||||
await executeVSCodeCommand('openchamber.openAgentManager');
|
await executeVSCodeCommand('openchamber.openAgentManager');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async openExternalUrl(url: string): Promise<void> {
|
||||||
|
await openVSCodeExternalUrl(url);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user