Browse Source

Adopts new webview model for the Home view

main
Eric Amodio 1 year ago
parent
commit
871458c29e
4 changed files with 350 additions and 324 deletions
  1. +3
    -7
      src/container.ts
  2. +47
    -33
      src/webviews/home/homeWebview.ts
  3. +16
    -0
      src/webviews/home/registration.ts

+ 3
- 7
src/container.ts View File

@ -56,7 +56,7 @@ import { ViewFileDecorationProvider } from './views/viewDecorationProvider';
import { WorktreesView } from './views/worktreesView'; import { WorktreesView } from './views/worktreesView';
import { VslsController } from './vsls/vsls'; import { VslsController } from './vsls/vsls';
import { CommitDetailsWebviewView } from './webviews/commitDetails/commitDetailsWebviewView'; 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 { RebaseEditorProvider } from './webviews/rebase/rebaseEditor';
import { SettingsWebview } from './webviews/settings/settingsWebview'; import { SettingsWebview } from './webviews/settings/settingsWebview';
import type { WebviewViewProxy } from './webviews/webviewsController'; 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._contributorsView = new ContributorsView(this)));
context.subscriptions.splice(0, 0, (this._searchAndCompareView = new SearchAndCompareView(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')) { if (configuration.get('terminalLinks.enabled')) {
context.subscriptions.splice(0, 0, (this._terminalLinks = new GitTerminalLinkProvider(this))); context.subscriptions.splice(0, 0, (this._terminalLinks = new GitTerminalLinkProvider(this)));
@ -462,12 +462,8 @@ export class Container {
// return this._graphView; // return this._graphView;
// } // }
private _homeView: HomeWebviewView | undefined; private _homeView: WebviewViewProxy;
get homeView() { get homeView() {
if (this._homeView == null) {
this._context.subscriptions.splice(0, 0, (this._homeView = new HomeWebviewView(this)));
}
return this._homeView; return this._homeView;
} }

src/webviews/home/homeWebviewView.ts → src/webviews/home/homeWebview.ts View File

@ -1,5 +1,5 @@
import type { ConfigurationChangeEvent, Disposable } from 'vscode'; import type { ConfigurationChangeEvent, ViewColumn } from 'vscode';
import { window } from 'vscode'; import { Disposable, window } from 'vscode';
import { getAvatarUriFromGravatarEmail } from '../../avatars'; import { getAvatarUriFromGravatarEmail } from '../../avatars';
import { ViewsLayout } from '../../commands/setViewsLayout'; import { ViewsLayout } from '../../commands/setViewsLayout';
import { ContextKeys, CoreCommands } from '../../constants'; import { ContextKeys, CoreCommands } from '../../constants';
@ -16,7 +16,8 @@ import type { Deferrable } from '../../system/function';
import { debounce } from '../../system/function'; import { debounce } from '../../system/function';
import type { IpcMessage } from '../protocol'; import type { IpcMessage } from '../protocol';
import { onIpc } 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 type { CompleteStepParams, DismissBannerParams, DismissSectionParams, State } from './protocol';
import { import {
CompletedActions, CompletedActions,
@ -30,11 +31,15 @@ import {
DismissStatusCommandType, DismissStatusCommandType,
} from './protocol'; } from './protocol';
export class HomeWebviewView extends WebviewViewBase<State> { export class HomeWebviewProvider implements WebviewProvider<State> {
constructor(container: Container) { private readonly _disposable: Disposable;
super(container, 'gitlens.views.home', 'home.html', 'Home', `${ContextKeys.WebviewViewPrefix}home`, 'homeView');
this.disposables.push( constructor(
readonly container: Container,
readonly id: `gitlens.${WebviewIds}` | `gitlens.views.${WebviewViewIds}`,
readonly host: WebviewController<State>,
) {
this._disposable = Disposable.from(
this.container.subscription.onDidChange(this.onSubscriptionChanged, this), this.container.subscription.onDidChange(this.onSubscriptionChanged, this),
onDidChangeContext(key => { onDidChangeContext(key => {
if (key !== ContextKeys.Disabled) return; if (key !== ContextKeys.Disabled) return;
@ -49,14 +54,17 @@ export class HomeWebviewView extends WebviewViewBase {
); );
} }
override async show(options?: { preserveFocus?: boolean | undefined }): Promise<void> { dispose() {
if (!(await ensurePlusFeaturesEnabled())) return; this._disposable.dispose();
return super.show(options);
} }
private async onSubscriptionChanged(e: SubscriptionChangeEvent) { async canShowWebviewPanel(
await this.container.storage.store('home:status:pinned', true); _firstTime: boolean,
void this.notifyDidChangeData(e.current); _options?: { column?: ViewColumn; preserveFocus?: boolean },
..._args: unknown[]
): Promise<boolean> {
if (!(await ensurePlusFeaturesEnabled())) return false;
return true;
} }
private onConfigurationChanged(e: ConfigurationChangeEvent) { private onConfigurationChanged(e: ConfigurationChangeEvent) {
@ -73,7 +81,12 @@ export class HomeWebviewView extends WebviewViewBase {
this.notifyDidChangeLayout(); 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) { if (!visible) {
this._validateSubscriptionDebounced?.cancel(); this._validateSubscriptionDebounced?.cancel();
return; return;
@ -82,8 +95,8 @@ export class HomeWebviewView extends WebviewViewBase {
queueMicrotask(() => void this.validateSubscription()); queueMicrotask(() => void this.validateSubscription());
} }
protected override onWindowFocusChanged(focused: boolean): void { onWindowFocusChanged(focused: boolean): void {
if (!focused || !this.visible) { if (!focused || !this.host.visible) {
this._validateSubscriptionDebounced?.cancel(); this._validateSubscriptionDebounced?.cancel();
return; return;
} }
@ -91,9 +104,9 @@ export class HomeWebviewView extends WebviewViewBase {
queueMicrotask(() => void this.validateSubscription()); queueMicrotask(() => void this.validateSubscription());
} }
protected override registerCommands(): Disposable[] { registerCommands(): Disposable[] {
return [ return [
registerCommand(`${this.id}.refresh`, () => this.refresh(), this), registerCommand(`${this.id}.refresh`, () => this.host.refresh(), this),
registerCommand('gitlens.home.toggleWelcome', async () => { registerCommand('gitlens.home.toggleWelcome', async () => {
const welcomeVisible = !this.welcomeVisible; const welcomeVisible = !this.welcomeVisible;
await this.container.storage.store('views:welcome:visible', 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', []); await this.container.storage.store('home:sections:dismissed', []);
} }
void this.refresh(); void this.host.refresh();
}), }),
registerCommand('gitlens.home.restoreWelcome', async () => { registerCommand('gitlens.home.restoreWelcome', async () => {
await this.container.storage.store('home:steps:completed', []); await this.container.storage.store('home:steps:completed', []);
await this.container.storage.store('home:sections:dismissed', []); await this.container.storage.store('home:sections:dismissed', []);
void this.refresh(); void this.host.refresh();
}), }),
registerCommand('gitlens.home.showSCM', async () => { 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) { switch (e.method) {
case CompleteStepCommandType.method: case CompleteStepCommandType.method:
onIpc(CompleteStepCommandType, e, params => this.completeStep(params)); 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); void this.container.storage.store('home:status:pinned', false);
} }
protected override async includeBootstrap(): Promise<State> { includeBootstrap(): Promise<State> {
return this.getState(); return this.getState();
} }
@ -205,7 +218,7 @@ export class HomeWebviewView extends WebviewViewBase {
if (subscriptionState.account?.email) { if (subscriptionState.account?.email) {
avatar = getAvatarUriFromGravatarEmail(subscriptionState.account.email, 34).toString(); avatar = getAvatarUriFromGravatarEmail(subscriptionState.account.email, 34).toString();
} else { } else {
avatar = `${this.getWebRoot() ?? ''}/media/gitlens-logo.webp`; avatar = `${this.host.getWebRoot() ?? ''}/media/gitlens-logo.webp`;
} }
return { return {
@ -227,7 +240,7 @@ export class HomeWebviewView extends WebviewViewBase {
return { return {
extensionEnabled: this.getExtensionEnabled(), extensionEnabled: this.getExtensionEnabled(),
webroot: this.getWebRoot(), webroot: this.host.getWebRoot(),
subscription: subscriptionState.subscription, subscription: subscriptionState.subscription,
completedActions: subscriptionState.completedActions, completedActions: subscriptionState.completedActions,
plusEnabled: this.getPlusEnabled(), plusEnabled: this.getPlusEnabled(),
@ -242,7 +255,7 @@ export class HomeWebviewView extends WebviewViewBase {
} }
private notifyDidChangeData(subscription?: Subscription) { private notifyDidChangeData(subscription?: Subscription) {
if (!this.isReady) return false; if (!this.host.isReady) return false;
const getSub = async () => { const getSub = async () => {
const sub = await this.getSubscription(subscription); const sub = await this.getSubscription(subscription);
@ -254,7 +267,7 @@ export class HomeWebviewView extends WebviewViewBase {
}; };
return window.withProgress({ location: { viewId: this.id } }, async () => 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() { private notifyExtensionEnabled() {
if (!this.isReady) return; if (!this.host.isReady) return;
void this.notify(DidChangeExtensionEnabledType, { void this.host.notify(DidChangeExtensionEnabledType, {
extensionEnabled: this.getExtensionEnabled(), extensionEnabled: this.getExtensionEnabled(),
}); });
} }
@ -275,9 +288,9 @@ export class HomeWebviewView extends WebviewViewBase {
} }
private notifyDidChangeConfiguration() { private notifyDidChangeConfiguration() {
if (!this.isReady) return; if (!this.host.isReady) return;
void this.notify(DidChangeConfigurationType, { void this.host.notify(DidChangeConfigurationType, {
plusEnabled: this.getPlusEnabled(), plusEnabled: this.getPlusEnabled(),
}); });
} }
@ -288,12 +301,13 @@ export class HomeWebviewView extends WebviewViewBase {
} }
private notifyDidChangeLayout() { 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<HomeWebviewView['validateSubscription']> | undefined = undefined; private _validateSubscriptionDebounced: Deferrable<HomeWebviewProvider['validateSubscription']> | undefined =
undefined;
private async validateSubscription(): Promise<void> { private async validateSubscription(): Promise<void> {
if (this._validateSubscriptionDebounced == null) { if (this._validateSubscriptionDebounced == null) {

+ 16
- 0
src/webviews/home/registration.ts View File

@ -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<State>('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);
},
});
}

||||||
x
 
000:0
Loading…
Cancel
Save