diff --git a/src/container.ts b/src/container.ts index e0a4194..9ca7975 100644 --- a/src/container.ts +++ b/src/container.ts @@ -56,7 +56,7 @@ import { ViewFileDecorationProvider } from './views/viewDecorationProvider'; import { WorktreesView } from './views/worktreesView'; import { VslsController } from './vsls/vsls'; import { CommitDetailsWebviewView } from './webviews/commitDetails/commitDetailsWebviewView'; -import { HomeWebviewView } from './webviews/home/homeWebviewView'; +import { registerHomeWebviewView } from './webviews/home/registration'; import { RebaseEditorProvider } from './webviews/rebase/rebaseEditor'; import { SettingsWebview } from './webviews/settings/settingsWebview'; import type { WebviewViewProxy } from './webviews/webviewsController'; @@ -238,7 +238,7 @@ export class Container { context.subscriptions.splice(0, 0, (this._contributorsView = new ContributorsView(this))); context.subscriptions.splice(0, 0, (this._searchAndCompareView = new SearchAndCompareView(this))); - context.subscriptions.splice(0, 0, (this._homeView = new HomeWebviewView(this))); + context.subscriptions.splice(0, 0, (this._homeView = registerHomeWebviewView(this._webviews))); if (configuration.get('terminalLinks.enabled')) { context.subscriptions.splice(0, 0, (this._terminalLinks = new GitTerminalLinkProvider(this))); @@ -462,12 +462,8 @@ export class Container { // return this._graphView; // } - private _homeView: HomeWebviewView | undefined; + private _homeView: WebviewViewProxy; get homeView() { - if (this._homeView == null) { - this._context.subscriptions.splice(0, 0, (this._homeView = new HomeWebviewView(this))); - } - return this._homeView; } diff --git a/src/webviews/home/homeWebviewView.ts b/src/webviews/home/homeWebview.ts similarity index 82% rename from src/webviews/home/homeWebviewView.ts rename to src/webviews/home/homeWebview.ts index b51cbc1..da750b1 100644 --- a/src/webviews/home/homeWebviewView.ts +++ b/src/webviews/home/homeWebview.ts @@ -1,5 +1,5 @@ -import type { ConfigurationChangeEvent, Disposable } from 'vscode'; -import { window } from 'vscode'; +import type { ConfigurationChangeEvent, ViewColumn } from 'vscode'; +import { Disposable, window } from 'vscode'; import { getAvatarUriFromGravatarEmail } from '../../avatars'; import { ViewsLayout } from '../../commands/setViewsLayout'; import { ContextKeys, CoreCommands } from '../../constants'; @@ -16,7 +16,8 @@ import type { Deferrable } from '../../system/function'; import { debounce } from '../../system/function'; import type { IpcMessage } from '../protocol'; import { onIpc } from '../protocol'; -import { WebviewViewBase } from '../webviewViewBase'; +import type { WebviewController, WebviewProvider } from '../webviewController'; +import type { WebviewIds, WebviewViewIds } from '../webviewsController'; import type { CompleteStepParams, DismissBannerParams, DismissSectionParams, State } from './protocol'; import { CompletedActions, @@ -30,11 +31,15 @@ import { DismissStatusCommandType, } from './protocol'; -export class HomeWebviewView extends WebviewViewBase { - constructor(container: Container) { - super(container, 'gitlens.views.home', 'home.html', 'Home', `${ContextKeys.WebviewViewPrefix}home`, 'homeView'); +export class HomeWebviewProvider implements WebviewProvider { + private readonly _disposable: Disposable; - this.disposables.push( + constructor( + readonly container: Container, + readonly id: `gitlens.${WebviewIds}` | `gitlens.views.${WebviewViewIds}`, + readonly host: WebviewController, + ) { + this._disposable = Disposable.from( this.container.subscription.onDidChange(this.onSubscriptionChanged, this), onDidChangeContext(key => { if (key !== ContextKeys.Disabled) return; @@ -49,14 +54,17 @@ export class HomeWebviewView extends WebviewViewBase { ); } - override async show(options?: { preserveFocus?: boolean | undefined }): Promise { - if (!(await ensurePlusFeaturesEnabled())) return; - return super.show(options); + dispose() { + this._disposable.dispose(); } - private async onSubscriptionChanged(e: SubscriptionChangeEvent) { - await this.container.storage.store('home:status:pinned', true); - void this.notifyDidChangeData(e.current); + async canShowWebviewPanel( + _firstTime: boolean, + _options?: { column?: ViewColumn; preserveFocus?: boolean }, + ..._args: unknown[] + ): Promise { + if (!(await ensurePlusFeaturesEnabled())) return false; + return true; } private onConfigurationChanged(e: ConfigurationChangeEvent) { @@ -73,7 +81,12 @@ export class HomeWebviewView extends WebviewViewBase { this.notifyDidChangeLayout(); } - protected override onVisibilityChanged(visible: boolean): void { + private async onSubscriptionChanged(e: SubscriptionChangeEvent) { + await this.container.storage.store('home:status:pinned', true); + void this.notifyDidChangeData(e.current); + } + + onVisibilityChanged(visible: boolean): void { if (!visible) { this._validateSubscriptionDebounced?.cancel(); return; @@ -82,8 +95,8 @@ export class HomeWebviewView extends WebviewViewBase { queueMicrotask(() => void this.validateSubscription()); } - protected override onWindowFocusChanged(focused: boolean): void { - if (!focused || !this.visible) { + onWindowFocusChanged(focused: boolean): void { + if (!focused || !this.host.visible) { this._validateSubscriptionDebounced?.cancel(); return; } @@ -91,9 +104,9 @@ export class HomeWebviewView extends WebviewViewBase { queueMicrotask(() => void this.validateSubscription()); } - protected override registerCommands(): Disposable[] { + registerCommands(): Disposable[] { return [ - registerCommand(`${this.id}.refresh`, () => this.refresh(), this), + registerCommand(`${this.id}.refresh`, () => this.host.refresh(), this), registerCommand('gitlens.home.toggleWelcome', async () => { const welcomeVisible = !this.welcomeVisible; await this.container.storage.store('views:welcome:visible', welcomeVisible); @@ -103,13 +116,13 @@ export class HomeWebviewView extends WebviewViewBase { await this.container.storage.store('home:sections:dismissed', []); } - void this.refresh(); + void this.host.refresh(); }), registerCommand('gitlens.home.restoreWelcome', async () => { await this.container.storage.store('home:steps:completed', []); await this.container.storage.store('home:sections:dismissed', []); - void this.refresh(); + void this.host.refresh(); }), registerCommand('gitlens.home.showSCM', async () => { @@ -126,7 +139,7 @@ export class HomeWebviewView extends WebviewViewBase { ]; } - protected override onMessageReceived(e: IpcMessage) { + onMessageReceived(e: IpcMessage) { switch (e.method) { case CompleteStepCommandType.method: onIpc(CompleteStepCommandType, e, params => this.completeStep(params)); @@ -179,7 +192,7 @@ export class HomeWebviewView extends WebviewViewBase { void this.container.storage.store('home:status:pinned', false); } - protected override async includeBootstrap(): Promise { + includeBootstrap(): Promise { return this.getState(); } @@ -205,7 +218,7 @@ export class HomeWebviewView extends WebviewViewBase { if (subscriptionState.account?.email) { avatar = getAvatarUriFromGravatarEmail(subscriptionState.account.email, 34).toString(); } else { - avatar = `${this.getWebRoot() ?? ''}/media/gitlens-logo.webp`; + avatar = `${this.host.getWebRoot() ?? ''}/media/gitlens-logo.webp`; } return { @@ -227,7 +240,7 @@ export class HomeWebviewView extends WebviewViewBase { return { extensionEnabled: this.getExtensionEnabled(), - webroot: this.getWebRoot(), + webroot: this.host.getWebRoot(), subscription: subscriptionState.subscription, completedActions: subscriptionState.completedActions, plusEnabled: this.getPlusEnabled(), @@ -242,7 +255,7 @@ export class HomeWebviewView extends WebviewViewBase { } private notifyDidChangeData(subscription?: Subscription) { - if (!this.isReady) return false; + if (!this.host.isReady) return false; const getSub = async () => { const sub = await this.getSubscription(subscription); @@ -254,7 +267,7 @@ export class HomeWebviewView extends WebviewViewBase { }; return window.withProgress({ location: { viewId: this.id } }, async () => - this.notify(DidChangeSubscriptionNotificationType, await getSub()), + this.host.notify(DidChangeSubscriptionNotificationType, await getSub()), ); } @@ -263,9 +276,9 @@ export class HomeWebviewView extends WebviewViewBase { } private notifyExtensionEnabled() { - if (!this.isReady) return; + if (!this.host.isReady) return; - void this.notify(DidChangeExtensionEnabledType, { + void this.host.notify(DidChangeExtensionEnabledType, { extensionEnabled: this.getExtensionEnabled(), }); } @@ -275,9 +288,9 @@ export class HomeWebviewView extends WebviewViewBase { } private notifyDidChangeConfiguration() { - if (!this.isReady) return; + if (!this.host.isReady) return; - void this.notify(DidChangeConfigurationType, { + void this.host.notify(DidChangeConfigurationType, { plusEnabled: this.getPlusEnabled(), }); } @@ -288,12 +301,13 @@ export class HomeWebviewView extends WebviewViewBase { } private notifyDidChangeLayout() { - if (!this.isReady) return; + if (!this.host.isReady) return; - void this.notify(DidChangeLayoutType, { layout: this.getLayout() }); + void this.host.notify(DidChangeLayoutType, { layout: this.getLayout() }); } - private _validateSubscriptionDebounced: Deferrable | undefined = undefined; + private _validateSubscriptionDebounced: Deferrable | undefined = + undefined; private async validateSubscription(): Promise { if (this._validateSubscriptionDebounced == null) { diff --git a/src/webviews/home/registration.ts b/src/webviews/home/registration.ts new file mode 100644 index 0000000..ce5c73a --- /dev/null +++ b/src/webviews/home/registration.ts @@ -0,0 +1,16 @@ +import { ContextKeys } from '../../constants'; +import type { WebviewsController } from '../webviewsController'; +import type { State } from './protocol'; + +export function registerHomeWebviewView(controller: WebviewsController) { + return controller.registerWebviewView('gitlens.views.home', { + fileName: 'home.html', + title: 'Home', + contextKeyPrefix: `${ContextKeys.WebviewViewPrefix}home`, + trackingFeature: 'homeView', + resolveWebviewProvider: async function (container, id, host) { + const { HomeWebviewProvider } = await import(/* webpackChunkName: "home" */ './homeWebview'); + return new HomeWebviewProvider(container, id, host); + }, + }); +}