Setup: allow a command link that opens setup view (fix microsoft/vscode-copilot#11301) (#237323)
parent
e8b620fc96
commit
dc1cfc044d
|
@ -60,6 +60,7 @@ import { IHostService } from '../../../services/host/browser/host.js';
|
|||
import Severity from '../../../../base/common/severity.js';
|
||||
import { IWorkbenchEnvironmentService } from '../../../services/environment/common/environmentService.js';
|
||||
import { isWeb } from '../../../../base/common/platform.js';
|
||||
import { ExtensionUrlHandlerOverrideRegistry } from '../../../services/extensions/browser/extensionUrlHandler.js';
|
||||
|
||||
const defaultChat = {
|
||||
extensionId: product.defaultChatAgent?.extensionId ?? '',
|
||||
|
@ -109,7 +110,9 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
|
|||
constructor(
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -122,6 +125,7 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
|
|||
|
||||
this.registerChatWelcome();
|
||||
this.registerActions();
|
||||
this.registerUrlLinkHandler();
|
||||
}
|
||||
|
||||
private registerChatWelcome(): void {
|
||||
|
@ -292,6 +296,18 @@ export class ChatSetupContribution extends Disposable implements IWorkbenchContr
|
|||
registerAction2(ChatSetupHideAction);
|
||||
registerAction2(UpgradePlanAction);
|
||||
}
|
||||
|
||||
private registerUrlLinkHandler(): void {
|
||||
this._register(ExtensionUrlHandlerOverrideRegistry.registerHandler(URI.parse(`${this.productService.urlProtocol}://${defaultChat.chatExtensionId}`), {
|
||||
handleURL: async () => {
|
||||
this.telemetryService.publicLog2<WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification>('workbenchActionExecuted', { id: TRIGGER_SETUP_COMMAND_ID, from: 'url' });
|
||||
|
||||
await this.commandService.executeCommand(TRIGGER_SETUP_COMMAND_ID);
|
||||
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { localize, localize2 } from '../../../../nls.js';
|
||||
import { IDisposable, combinedDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { IDisposable, combinedDisposable, toDisposable } from '../../../../base/common/lifecycle.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
|
||||
import { IDialogService } from '../../../../platform/dialogs/common/dialogs.js';
|
||||
|
@ -27,6 +27,7 @@ import { ICommandService } from '../../../../platform/commands/common/commands.j
|
|||
import { isCancellationError } from '../../../../base/common/errors.js';
|
||||
import { INotificationService } from '../../../../platform/notification/common/notification.js';
|
||||
import { IWorkbenchEnvironmentService } from '../../environment/common/environmentService.js';
|
||||
import { ResourceMap } from '../../../../base/common/map.js';
|
||||
|
||||
const FIVE_MINUTES = 5 * 60 * 1000;
|
||||
const THIRTY_SECONDS = 30 * 1000;
|
||||
|
@ -99,6 +100,25 @@ type ExtensionUrlReloadHandlerClassification = {
|
|||
comment: 'This is used to understand the drop funnel of extension URI handling by the OS & VS Code.';
|
||||
};
|
||||
|
||||
export interface IExtensionUrlHandlerOverride {
|
||||
handleURL(uri: URI): Promise<boolean>;
|
||||
}
|
||||
|
||||
export class ExtensionUrlHandlerOverrideRegistry {
|
||||
|
||||
private static readonly handlers = new ResourceMap<IExtensionUrlHandlerOverride>();
|
||||
|
||||
static registerHandler(uri: URI, handler: IExtensionUrlHandlerOverride): IDisposable {
|
||||
this.handlers.set(uri, handler);
|
||||
|
||||
return toDisposable(() => this.handlers.delete(uri));
|
||||
}
|
||||
|
||||
static getHandler(uri: URI): IExtensionUrlHandlerOverride | undefined {
|
||||
return this.handlers.get(uri);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class handles URLs which are directed towards extensions.
|
||||
* If a URL is directed towards an inactive extension, it buffers it,
|
||||
|
@ -153,6 +173,14 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
|
|||
return false;
|
||||
}
|
||||
|
||||
const overrideHandler = ExtensionUrlHandlerOverrideRegistry.getHandler(uri);
|
||||
if (overrideHandler) {
|
||||
const handled = await overrideHandler.handleURL(uri);
|
||||
if (handled) {
|
||||
return handled;
|
||||
}
|
||||
}
|
||||
|
||||
const extensionId = uri.authority;
|
||||
this.telemetryService.publicLog2<ExtensionUrlHandlerEvent, ExtensionUrlHandlerClassification>('uri_invoked/start', { extensionId });
|
||||
|
||||
|
|
Loading…
Reference in New Issue