Skip to content

Commit

Permalink
Updates verbiage for GL+ and GL Pro
Browse files Browse the repository at this point in the history
- updates plan names
- consolidates ensurePaidPlan functionality
- updates account quickpicks
- updates account notification messages

Co-authored-by: Eric Amodio <eamodio@gmail.com>
  • Loading branch information
d13 and eamodio committed Oct 14, 2022
1 parent 1d69690 commit c90b1c3
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 187 deletions.
2 changes: 1 addition & 1 deletion src/commands/gitCommands.ts
Expand Up @@ -712,7 +712,7 @@ export class GitCommandsCommand extends Command {
resolve(undefined);
return;

case Directive.RequiresFreeSubscription:
case Directive.ExtendTrial:
void Container.instance.subscription.loginOrSignUp();
resolve(undefined);
return;
Expand Down
22 changes: 8 additions & 14 deletions src/commands/quickCommand.steps.ts
Expand Up @@ -2167,26 +2167,20 @@ export async function* ensureAccessStep<
let placeholder: string;
if (access.subscription.current.account?.verified === false) {
directives.push(DirectiveQuickPickItem.create(Directive.RequiresVerification, true));
placeholder = 'You must verify your GitLens+ account email address before you can continue';
placeholder = 'You must verify your email address before you can continue';
} else {
if (access.subscription.required == null) return undefined;

placeholder = 'You need GitLens Pro to access GitLens+ features on this repo';
if (isSubscriptionPaidPlan(access.subscription.required) && access.subscription.current.account != null) {
directives.push(DirectiveQuickPickItem.create(Directive.RequiresPaidSubscription, true));
placeholder = 'GitLens+ features require an upgraded account';
} else if (
access.subscription.current.account == null &&
!isSubscriptionPreviewTrialExpired(access.subscription.current)
) {
directives.push(DirectiveQuickPickItem.create(Directive.StartPreviewTrial, true));
} else {
if (
access.subscription.current.account == null &&
!isSubscriptionPreviewTrialExpired(access.subscription.current)
) {
directives.push(
DirectiveQuickPickItem.create(Directive.StartPreviewTrial, true),
DirectiveQuickPickItem.create(Directive.RequiresFreeSubscription),
);
} else {
directives.push(DirectiveQuickPickItem.create(Directive.RequiresFreeSubscription));
}
placeholder = 'GitLens+ features require a free account';
directives.push(DirectiveQuickPickItem.create(Directive.ExtendTrial));
}
}

Expand Down
75 changes: 2 additions & 73 deletions src/git/remotes/github.ts
Expand Up @@ -7,7 +7,6 @@ import type {
IntegrationAuthenticationProvider,
IntegrationAuthenticationSessionDescriptor,
} from '../../plus/integrationAuthentication';
import { isSubscriptionPaidPlan, isSubscriptionPreviewTrialExpired } from '../../subscription';
import { log } from '../../system/decorators/log';
import { memoize } from '../../system/decorators/memoize';
import { encodeUrl } from '../../system/encoding';
Expand All @@ -18,7 +17,7 @@ import type { IssueOrPullRequest } from '../models/issue';
import type { PullRequest, PullRequestState } from '../models/pullRequest';
import { GitRevision } from '../models/reference';
import type { Repository } from '../models/repository';
import { RichRemoteProvider } from './richRemoteProvider';
import { ensurePaidPlan, RichRemoteProvider } from './richRemoteProvider';

const autolinkFullIssuesRegex = /\b(?<repo>[^/\s]+\/[^/\s]+)#(?<num>[0-9]+)\b(?!]\()/g;
const fileRegex = /^\/([^/]+)\/([^/]+?)\/blob(.+)$/i;
Expand Down Expand Up @@ -141,77 +140,7 @@ export class GitHubRemote extends RichRemoteProvider {
@log()
override async connect(): Promise<boolean> {
if (!isGitHubDotCom(this.domain)) {
const title =
'Connecting to a GitHub Enterprise instance for rich integration features requires a paid GitLens+ account.';

while (true) {
const subscription = await this.container.subscription.getSubscription();
if (subscription.account?.verified === false) {
const resend = { title: 'Resend Verification' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nYou must verify your GitLens+ account email address before you can continue.`,
{ modal: true },
resend,
cancel,
);

if (result === resend) {
if (await this.container.subscription.resendVerification()) {
continue;
}
}

return false;
}

const plan = subscription.plan.effective.id;
if (isSubscriptionPaidPlan(plan)) break;

if (subscription.account == null && !isSubscriptionPreviewTrialExpired(subscription)) {
const startTrial = { title: 'Try GitLens+' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nDo you want to try GitLens+ for free for 3 days?`,
{ modal: true },
startTrial,
cancel,
);

if (result !== startTrial) return false;

void this.container.subscription.startPreviewTrial();
break;
} else if (subscription.account == null) {
const signIn = { title: 'Sign In to GitLens+' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nDo you want to sign in to GitLens+?`,
{ modal: true },
signIn,
cancel,
);

if (result === signIn) {
if (await this.container.subscription.loginOrSignUp()) {
continue;
}
}
} else {
const upgrade = { title: 'Upgrade Account' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nDo you want to upgrade your account?`,
{ modal: true },
upgrade,
cancel,
);

if (result === upgrade) {
void this.container.subscription.purchase();
}
}

if (!(await ensurePaidPlan('GitHub Enterprise instance', this.container))) {
return false;
}
}
Expand Down
75 changes: 2 additions & 73 deletions src/git/remotes/gitlab.ts
Expand Up @@ -8,7 +8,6 @@ import type {
IntegrationAuthenticationProvider,
IntegrationAuthenticationSessionDescriptor,
} from '../../plus/integrationAuthentication';
import { isSubscriptionPaidPlan, isSubscriptionPreviewTrialExpired } from '../../subscription';
import { log } from '../../system/decorators/log';
import { encodeUrl } from '../../system/encoding';
import { equalsIgnoreCase } from '../../system/string';
Expand All @@ -18,7 +17,7 @@ import type { IssueOrPullRequest } from '../models/issue';
import type { PullRequest, PullRequestState } from '../models/pullRequest';
import { GitRevision } from '../models/reference';
import type { Repository } from '../models/repository';
import { RichRemoteProvider } from './richRemoteProvider';
import { ensurePaidPlan, RichRemoteProvider } from './richRemoteProvider';

const autolinkFullIssuesRegex = /\b(?<repo>[^/\s]+\/[^/\s]+)#(?<num>[0-9]+)\b(?!]\()/g;
const autolinkFullMergeRequestsRegex = /\b(?<repo>[^/\s]+\/[^/\s]+)!(?<num>[0-9]+)\b(?!]\()/g;
Expand Down Expand Up @@ -184,77 +183,7 @@ export class GitLabRemote extends RichRemoteProvider {
@log()
override async connect(): Promise<boolean> {
if (!equalsIgnoreCase(this.domain, 'gitlab.com')) {
const title =
'Connecting to a GitLab self-managed instance for rich integration features requires a paid GitLens+ account.';

while (true) {
const subscription = await this.container.subscription.getSubscription();
if (subscription.account?.verified === false) {
const resend = { title: 'Resend Verification' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nYou must verify your GitLens+ account email address before you can continue.`,
{ modal: true },
resend,
cancel,
);

if (result === resend) {
if (await this.container.subscription.resendVerification()) {
continue;
}
}

return false;
}

const plan = subscription.plan.effective.id;
if (isSubscriptionPaidPlan(plan)) break;

if (subscription.account == null && !isSubscriptionPreviewTrialExpired(subscription)) {
const startTrial = { title: 'Try GitLens+' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nDo you want to try GitLens+ for free for 3 days?`,
{ modal: true },
startTrial,
cancel,
);

if (result !== startTrial) return false;

void this.container.subscription.startPreviewTrial();
break;
} else if (subscription.account == null) {
const signIn = { title: 'Sign In to GitLens+' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nDo you want to sign in to GitLens+?`,
{ modal: true },
signIn,
cancel,
);

if (result === signIn) {
if (await this.container.subscription.loginOrSignUp()) {
continue;
}
}
} else {
const upgrade = { title: 'Upgrade Account' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nDo you want to upgrade your account?`,
{ modal: true },
upgrade,
cancel,
);

if (result === upgrade) {
void this.container.subscription.purchase();
}
}

if (!(await ensurePaidPlan('GitLab self-managed instance', this.container))) {
return false;
}
}
Expand Down
78 changes: 78 additions & 0 deletions src/git/remotes/richRemoteProvider.ts
Expand Up @@ -8,6 +8,7 @@ import { AuthenticationError, ProviderRequestClientError } from '../../errors';
import { Logger } from '../../logger';
import { showIntegrationDisconnectedTooManyFailedRequestsWarningMessage } from '../../messages';
import type { IntegrationAuthenticationSessionDescriptor } from '../../plus/integrationAuthentication';
import { isSubscriptionPaidPlan, isSubscriptionPreviewTrialExpired } from '../../subscription';
import { gate } from '../../system/decorators/gate';
import { debug, getLogScope, log } from '../../system/decorators/log';
import { isPromise } from '../../system/promise';
Expand Down Expand Up @@ -466,3 +467,80 @@ export abstract class RichRemoteProvider extends RemoteProvider {
return session ?? undefined;
}
}

export async function ensurePaidPlan(providerName: string, container: Container): Promise<boolean> {
const title = `Connecting to a ${providerName} instance for rich integration features requires GitLens Pro.`;

while (true) {
const subscription = await container.subscription.getSubscription();
if (subscription.account?.verified === false) {
const resend = { title: 'Resend Verification' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nYou must verify your email address before you can continue.`,
{ modal: true },
resend,
cancel,
);

if (result === resend) {
if (await container.subscription.resendVerification()) {
continue;
}
}

return false;
}

const plan = subscription.plan.effective.id;
if (isSubscriptionPaidPlan(plan)) break;

if (subscription.account == null && !isSubscriptionPreviewTrialExpired(subscription)) {
const startTrial = { title: 'Start a GitLens Pro Trial' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nDo you want to also try GitLens+ features on private repos, free for 3 days?`,
{ modal: true },
startTrial,
cancel,
);

if (result !== startTrial) return false;

void container.subscription.startPreviewTrial();
break;
} else if (subscription.account == null) {
const signIn = { title: 'Extend Your GitLens Pro Trial' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nDo you want to continue to use GitLens+ features on private repos, free for an additional 7-days?`,
{ modal: true },
signIn,
cancel,
);

if (result === signIn) {
if (await container.subscription.loginOrSignUp()) {
continue;
}
}
} else {
const upgrade = { title: 'Upgrade to Pro' };
const cancel = { title: 'Cancel', isCloseAffordance: true };
const result = await window.showWarningMessage(
`${title}\n\nDo you want to continue to use GitLens+ features on private repos?`,
{ modal: true },
upgrade,
cancel,
);

if (result === upgrade) {
void container.subscription.purchase();
}
}

return false;
}

return true;
}
26 changes: 15 additions & 11 deletions src/plus/subscription/subscriptionService.ts
Expand Up @@ -242,7 +242,7 @@ export class SubscriptionService implements Disposable {
const confirm: MessageItem = { title: 'Resend Verification', isCloseAffordance: true };
const cancel: MessageItem = { title: 'Cancel' };
const result = await window.showInformationMessage(
`Before you can access your ${actual.name} account, you must verify your email address.`,
`Before you can access ${effective.name}, you must verify your email address.`,
confirm,
cancel,
);
Expand All @@ -256,11 +256,12 @@ export class SubscriptionService implements Disposable {
const confirm: MessageItem = { title: 'OK', isCloseAffordance: true };
const learn: MessageItem = { title: 'Learn More' };
const result = await window.showInformationMessage(
`You are now signed in to your ${
actual.name
} account which gives you access to GitLens+ features on public repos.\n\nYou were also granted a trial of ${
`Welcome to ${
effective.name
} for both public and private repos for ${pluralize('more day', remaining ?? 0)}.`,
} (Trial). You now have additional access to GitLens+ features on private repos for ${pluralize(
'more day',
remaining ?? 0,
)}.`,
{ modal: true },
confirm,
learn,
Expand All @@ -270,7 +271,10 @@ export class SubscriptionService implements Disposable {
this.learn();
}
} else {
void window.showInformationMessage(`You are now signed in to your ${actual.name} account.`, 'OK');
void window.showInformationMessage(
`Welcome to ${actual.name}. You now have additional access to GitLens+ features on private repos.`,
'OK',
);
}
}
return loggedIn;
Expand Down Expand Up @@ -427,10 +431,10 @@ export class SubscriptionService implements Disposable {
void this.showHomeView();

if (!silent && plan.effective.id === SubscriptionPlanId.Free) {
const confirm: MessageItem = { title: 'Sign in to GitLens+', isCloseAffordance: true };
const confirm: MessageItem = { title: 'Extend Your Trial', isCloseAffordance: true };
const cancel: MessageItem = { title: 'Cancel' };
const result = await window.showInformationMessage(
'Your GitLens+ features trial has ended.\nPlease sign in to use GitLens+ features on public repos and get a free 7-day trial for both public and private repos.',
'Your 3-day trial has ended.\nExtend your GitLens Pro trial to continue to use GitLens+ features on private repos, free for an additional 7-days.',
{ modal: true },
confirm,
cancel,
Expand Down Expand Up @@ -476,7 +480,7 @@ export class SubscriptionService implements Disposable {
const confirm: MessageItem = { title: 'OK', isCloseAffordance: true };
const learn: MessageItem = { title: 'Learn More' };
const result = await window.showInformationMessage(
`You have started a ${days} day trial of GitLens+ features for both public and private repos.`,
`You have started a ${days}-day GitLens Pro trial of GitLens+ features on private repos.`,
{ modal: true },
confirm,
learn,
Expand Down Expand Up @@ -920,8 +924,8 @@ export class SubscriptionService implements Disposable {
this._statusBarSubscription.backgroundColor = new ThemeColor('statusBarItem.warningBackground');
this._statusBarSubscription.tooltip = new MarkdownString(
trial
? `**Please verify your email**\n\nBefore you can start your **${effective.name}** trial, please verify the email for the account you created.\n\nClick for details`
: `**Please verify your email**\n\nBefore you can use GitLens+ features, please verify the email for the account you created.\n\nClick for details`,
? `**Please verify your email**\n\nBefore you can start your **${effective.name}** trial, please verify your email address.\n\nClick for details`
: `**Please verify your email**\n\nBefore you can also use GitLens+ features on private repos, please verify your email address.\n\nClick for details`,
true,
);
} else {
Expand Down

0 comments on commit c90b1c3

Please sign in to comment.