|
|
@ -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<State> { |
|
|
|
constructor(container: Container) { |
|
|
|
super(container, 'gitlens.views.home', 'home.html', 'Home', `${ContextKeys.WebviewViewPrefix}home`, 'homeView'); |
|
|
|
export class HomeWebviewProvider implements WebviewProvider<State> { |
|
|
|
private readonly _disposable: Disposable; |
|
|
|
|
|
|
|
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), |
|
|
|
onDidChangeContext(key => { |
|
|
|
if (key !== ContextKeys.Disabled) return; |
|
|
@ -49,14 +54,17 @@ export class HomeWebviewView extends WebviewViewBase { |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
override async show(options?: { preserveFocus?: boolean | undefined }): Promise<void> { |
|
|
|
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<boolean> { |
|
|
|
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<State> { |
|
|
|
includeBootstrap(): Promise<State> { |
|
|
|
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<HomeWebviewView['validateSubscription']> | undefined = undefined; |
|
|
|
private _validateSubscriptionDebounced: Deferrable<HomeWebviewProvider['validateSubscription']> | undefined = |
|
|
|
undefined; |
|
|
|
|
|
|
|
private async validateSubscription(): Promise<void> { |
|
|
|
if (this._validateSubscriptionDebounced == null) { |