diff --git a/package.json b/package.json index 65fa5b623212c..4035b31634cf0 100644 --- a/package.json +++ b/package.json @@ -1658,16 +1658,9 @@ }, { "id": "launchpad-view", - "title": "Launchpad View (ᴇxᴘᴇʀɪᴍᴇɴᴛᴀʟ)", + "title": "Launchpad View (ᴘʀᴏ)", "order": 101, "properties": { - "gitlens.views.launchpad.enabled": { - "type": "boolean", - "default": false, - "markdownDescription": "(Experimental) Specifies whether to enable an experimental _Launchpad_ view", - "scope": "window", - "order": 10 - }, "gitlens.views.launchpad.files.layout": { "type": "string", "default": "auto", @@ -19077,13 +19070,57 @@ }, { "view": "gitlens.views.launchpad", - "contents": "[Launchpad](command:gitlens.views.launchpad.info \"Learn about Launchpad\") — organizes your pull requests into actionable groups to help you focus and keep your team unblocked.", - "when": "config.gitlens.views.launchpad.enabled" + "contents": "[Launchpad](command:gitlens.views.launchpad.info \"Learn about Launchpad\") — organizes your pull requests into actionable groups to help you focus and keep your team unblocked." }, { "view": "gitlens.views.launchpad", "contents": "[Connect an Integration...](command:gitlens.showLaunchpad?%7B%22source%22%3A%22launchpad-view%22%7D)\n\nAllows Launchpad to organize your pull requests into actionable groups and keep your team unblocked.", - "when": "config.gitlens.views.launchpad.enabled && gitlens:launchpad:connect" + "when": "gitlens:launchpad:connect" + }, + { + "view": "gitlens.views.launchpad", + "contents": "[Resend Verification Email](command:gitlens.plus.resendVerification?%7B%22source%22%3A%22launchpad-view%22%7D)\n\nYou must verify your email before you can continue or [recheck Status](command:gitlens.plus.validate?%7B%22source%22%3A%22launchpad-view%22%7D).", + "when": "!gitlens:launchpad:connect && gitlens:plus:state == -1" + }, + { + "view": "gitlens.views.launchpad", + "contents": "[Continue](command:gitlens.plus.startPreviewTrial?%7B%22source%22%3A%22launchpad-view%22%7D)\n\nContinuing gives you 3 days to preview Launchpad and other local Pro features for 3 days. [Start 7-day Pro trial](command:gitlens.plus.signUp?%7B%22source%22%3A%22launchpad-view%22%7D) or [sign in](command:gitlens.plus.login?%7B%22source%22%3A%22launchpad-view%22%7D) for full access to Pro features.", + "when": "!gitlens:launchpad:connect && gitlens:plus:required && gitlens:plus:state == 0" + }, + { + "view": "gitlens.views.launchpad", + "contents": "[Start Pro Trial](command:gitlens.plus.signUp?%7B%22source%22%3A%22launchpad-view%22%7D)\n\nStart your free 7-day Pro trial to try Launchpad and other Pro features, or [sign in](command:gitlens.plus.login?%7B%22source%22%3A%22launchpad-view%22%7D).", + "when": "!gitlens:launchpad:connect && gitlens:plus:required && gitlens:plus:state == 2" + }, + { + "view": "gitlens.views.launchpad", + "contents": "[Upgrade to Pro](command:gitlens.plus.upgrade?%7B%22source%22%3A%22launchpad-view%22%7D)", + "when": "!gitlens:launchpad:connect && gitlens:plus:required && gitlens:plus:state == 4" + }, + { + "view": "gitlens.views.launchpad", + "contents": "Limited-time sale: Save 33% or more on your 1st seat of Pro.", + "when": "!gitlens:launchpad:connect && gitlens:plus:required && gitlens:plus:state == 4 && (gitlens:promo == pro50 || !gitlens:promo)" + }, + { + "view": "gitlens.views.launchpad", + "contents": "Limited-time sale: Save up to 80% on GitLens Pro", + "when": "!gitlens:launchpad:connect && gitlens:plus:required && gitlens:plus:state == 4 && gitlens:promo == devexdays" + }, + { + "view": "gitlens.views.launchpad", + "contents": "Your Pro trial has ended. Please upgrade for full access to Launchpad and other Pro features.", + "when": "!gitlens:launchpad:connect && gitlens:plus:required && gitlens:plus:state == 4" + }, + { + "view": "gitlens.views.launchpad", + "contents": "[Continue](command:gitlens.plus.reactivateProTrial?%7B%22source%22%3A%22launchpad-view%22%7D)\n\nReactivate your Pro trial and experience Launchpad and all the new Pro features — free for another 7 days!", + "when": "!gitlens:launchpad:connect && gitlens:plus:required && gitlens:plus:state == 5" + }, + { + "view": "gitlens.views.launchpad", + "contents": "Pro feature — requires a paid plan for use on privately-hosted repos.", + "when": "!gitlens:launchpad:connect" }, { "view": "gitlens.views.workspaces", @@ -19226,7 +19263,6 @@ { "id": "gitlens.views.launchpad", "name": "Launchpad", - "when": "config.gitlens.views.launchpad.enabled", "contextualTitle": "GitLens", "icon": "$(rocket)", "initialSize": 2, diff --git a/src/views/launchpadView.ts b/src/views/launchpadView.ts index fef14afaf9caa..8c3125bc03841 100644 --- a/src/views/launchpadView.ts +++ b/src/views/launchpadView.ts @@ -1,12 +1,14 @@ -import type { ConfigurationChangeEvent, MessageItem, TreeViewVisibilityChangeEvent } from 'vscode'; +import type { ConfigurationChangeEvent, TreeViewVisibilityChangeEvent } from 'vscode'; import { Disposable, ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri, window } from 'vscode'; import type { OpenWalkthroughCommandArgs } from '../commands/walkthroughs'; import type { LaunchpadViewConfig, ViewFilesLayout } from '../config'; -import { experimentalBadge } from '../constants'; import { Commands } from '../constants.commands'; import type { Container } from '../container'; import { AuthenticationRequiredError } from '../errors'; +import { PlusFeatures } from '../features'; import { GitUri, unknownGitUri } from '../git/gitUri'; +import type { SubscriptionChangeEvent } from '../plus/gk/account/subscriptionService'; +import { ensurePlusFeaturesEnabled } from '../plus/gk/utils'; import type { LaunchpadCommandArgs } from '../plus/launchpad/launchpad'; import type { LaunchpadGroup, LaunchpadItem } from '../plus/launchpad/launchpadProvider'; import { @@ -125,7 +127,10 @@ export class LaunchpadViewNode extends CacheableChildrenViewNode< constructor(view: LaunchpadView) { super('launchpad', unknownGitUri, view); - this.disposable = Disposable.from(this.view.container.launchpad.onDidChange(this.refresh, this)); + this.disposable = Disposable.from( + this.view.container.launchpad.onDidChange(this.refresh, this), + this.view.container.subscription.onDidChange(this.onSubscriptionChanged, this), + ); } override dispose() { @@ -133,6 +138,12 @@ export class LaunchpadViewNode extends CacheableChildrenViewNode< super.dispose(); } + private onSubscriptionChanged(e: SubscriptionChangeEvent) { + if (e.current.plan !== e.previous.plan) { + void this.triggerChange(true); + } + } + override refresh() { if (this.children == null) return; @@ -142,6 +153,9 @@ export class LaunchpadViewNode extends CacheableChildrenViewNode< async getChildren(): Promise<(GroupingNode | LaunchpadItemNode)[]> { if (this.children == null) { + const access = await this.view.container.git.access(PlusFeatures.Launchpad); + if (!access.allowed) return []; + const children: (GroupingNode | LaunchpadItemNode)[] = []; this.view.message = undefined; @@ -208,8 +222,6 @@ export class LaunchpadView extends ViewBase<'launchpad', LaunchpadViewNode, Laun constructor(container: Container) { super(container, 'launchpad', 'Launchpad', 'launchpadView'); - - this.description = experimentalBadge; } override dispose() { @@ -233,24 +245,7 @@ export class LaunchpadView extends ViewBase<'launchpad', LaunchpadViewNode, Laun } override async show(options?: { preserveFocus?: boolean | undefined }): Promise { - if (!configuration.get('views.launchpad.enabled')) { - const confirm: MessageItem = { title: 'Enable' }; - const cancel: MessageItem = { title: 'Cancel', isCloseAffordance: true }; - const result = await window.showInformationMessage( - 'Would you like to try the new experimental Launchpad view?', - { - modal: true, - detail: 'Launchpad organizes your pull requests into actionable groups to help you focus and keep your team unblocked.', - }, - confirm, - cancel, - ); - - if (result !== confirm) return; - - await configuration.updateEffective('views.launchpad.enabled', true); - } - + if (!(await ensurePlusFeaturesEnabled())) return; return super.show(options); }