Browse Source

Trial reactivation UX (#2962)

* Updates account messaging to support trial reactivation

* Polishes and improved messaging
main
Ramin Tadayon 1 year ago
committed by GitHub
parent
commit
e03275f0b8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 12 deletions
  1. +1
    -0
      src/commands/showView.ts
  2. +24
    -7
      src/plus/subscription/subscriptionService.ts
  3. +3
    -0
      src/subscription.ts
  4. +1
    -1
      src/webviews/apps/plus/account/account.scss
  5. +1
    -0
      src/webviews/apps/plus/account/account.ts
  6. +28
    -4
      src/webviews/apps/plus/account/components/account-content.ts

+ 1
- 0
src/commands/showView.ts View File

@ -15,6 +15,7 @@ export class ShowViewCommand extends Command {
Commands.ShowFileHistoryView,
Commands.ShowGraphView,
Commands.ShowHomeView,
Commands.ShowAccountView,
Commands.ShowLineHistoryView,
Commands.ShowRemotesView,
Commands.ShowRepositoriesView,

+ 24
- 7
src/plus/subscription/subscriptionService.ts View File

@ -304,6 +304,7 @@ export class SubscriptionService implements Disposable {
actual: getSubscriptionPlan(
SubscriptionPlanId.Free,
false,
0,
undefined,
this._subscription.plan?.actual?.startedOn != null
? new Date(this._subscription.plan.actual.startedOn)
@ -312,6 +313,7 @@ export class SubscriptionService implements Disposable {
effective: getSubscriptionPlan(
SubscriptionPlanId.Free,
false,
0,
undefined,
this._subscription.plan?.effective?.startedOn != null
? new Date(this._subscription.plan.actual.startedOn)
@ -462,7 +464,7 @@ export class SubscriptionService implements Disposable {
...this._subscription,
plan: {
...this._subscription.plan,
effective: getSubscriptionPlan(SubscriptionPlanId.Pro, false, undefined, startedOn, expiresOn),
effective: getSubscriptionPlan(SubscriptionPlanId.Pro, false, 0, undefined, startedOn, expiresOn),
},
previewTrial: previewTrial,
});
@ -632,6 +634,7 @@ export class SubscriptionService implements Disposable {
actual = getSubscriptionPlan(
convertLicenseTypeToPlanId(licenseType),
isBundleLicenseType(licenseType),
license.reactivationCount ?? 0,
license.organizationId,
new Date(license.latestStartDate),
new Date(license.latestEndDate),
@ -643,6 +646,7 @@ export class SubscriptionService implements Disposable {
actual = getSubscriptionPlan(
SubscriptionPlanId.FreePlus,
false,
0,
undefined,
data.user.firstGitLensCheckIn != null
? new Date(data.user.firstGitLensCheckIn)
@ -668,6 +672,7 @@ export class SubscriptionService implements Disposable {
effective = getSubscriptionPlan(
convertLicenseTypeToPlanId(licenseType),
isBundleLicenseType(licenseType),
license.reactivationCount ?? 0,
license.organizationId,
new Date(license.latestStartDate),
new Date(license.latestEndDate),
@ -825,8 +830,8 @@ export class SubscriptionService implements Disposable {
if (subscription == null) {
subscription = {
plan: {
actual: getSubscriptionPlan(SubscriptionPlanId.Free, false, undefined),
effective: getSubscriptionPlan(SubscriptionPlanId.Free, false, undefined),
actual: getSubscriptionPlan(SubscriptionPlanId.Free, false, 0, undefined),
effective: getSubscriptionPlan(SubscriptionPlanId.Free, false, 0, undefined),
},
account: undefined,
state: SubscriptionState.Free,
@ -857,6 +862,7 @@ export class SubscriptionService implements Disposable {
effective: getSubscriptionPlan(
SubscriptionPlanId.Pro,
false,
0,
undefined,
new Date(subscription.previewTrial.startedOn),
new Date(subscription.previewTrial.expiresOn),
@ -999,6 +1005,7 @@ export class SubscriptionService implements Disposable {
const {
account,
plan: { effective },
state,
} = this._subscription;
if (effective.id === SubscriptionPlanId.Free) {
@ -1023,7 +1030,7 @@ export class SubscriptionService implements Disposable {
}
this._statusBarSubscription.name = 'GitKraken Subscription';
this._statusBarSubscription.command = Commands.ShowHomeView;
this._statusBarSubscription.command = Commands.ShowAccountView;
if (account?.verified === false) {
this._statusBarSubscription.text = `$(warning) ${effective.name} (Unverified)`;
@ -1038,12 +1045,21 @@ export class SubscriptionService implements Disposable {
);
} else {
const remaining = getSubscriptionTimeRemaining(this._subscription, 'days');
const isReactivatedTrial =
state === SubscriptionState.FreePlusInTrial && effective.trialReactivationCount > 0;
this._statusBarSubscription.text = `${effective.name} (Trial)`;
this._statusBarSubscription.tooltip = new MarkdownString(
`You have ${pluralize('day', remaining ?? 0)} left in your free **${
effective.name
}** trial, which gives you additional access to Pro features on privately hosted repos.\n\nClick for details`,
`${
isReactivatedTrial
? `[See what's new](https://help.gitkraken.com/gitlens/gitlens-release-notes-current/) with
${pluralize('day', remaining ?? 0, {
infix: ' more ',
})}
in your **${effective.name}** trial.`
: `You have ${pluralize('day', remaining ?? 0)} remaining in your **${effective.name}** trial.`
} Once your trial ends, you'll need a paid plan to continue using features.\n\nTry our
[other developer tools](https://www.gitkraken.com/suite) also included in your trial.`,
true,
);
}
@ -1095,6 +1111,7 @@ interface GKLicense {
readonly latestStartDate: string;
readonly latestEndDate: string;
readonly organizationId: string | undefined;
readonly reactivationCount?: number;
}
type GKLicenseType =

+ 3
- 0
src/subscription.ts View File

@ -30,6 +30,7 @@ export interface SubscriptionPlan {
readonly id: SubscriptionPlanId;
readonly name: string;
readonly bundle: boolean;
readonly trialReactivationCount: number;
readonly cancelled: boolean;
readonly startedOn: string;
readonly expiresOn?: string | undefined;
@ -112,6 +113,7 @@ export function computeSubscriptionState(subscription: Optional
export function getSubscriptionPlan(
id: SubscriptionPlanId,
bundle: boolean,
trialReactivationCount: number,
organizationId: string | undefined,
startedOn?: Date,
expiresOn?: Date,
@ -123,6 +125,7 @@ export function getSubscriptionPlan(
bundle: bundle,
cancelled: cancelled,
organizationId: organizationId,
trialReactivationCount: trialReactivationCount,
startedOn: (startedOn ?? new Date()).toISOString(),
expiresOn: expiresOn != null ? expiresOn.toISOString() : undefined,
};

+ 1
- 1
src/webviews/apps/plus/account/account.scss View File

@ -103,7 +103,7 @@ body {
}
account-content {
margin-top: 1.3rem;
margin-top: 0.3rem;
margin-bottom: 1.3rem;
}

+ 1
- 0
src/webviews/apps/plus/account/account.ts View File

@ -83,6 +83,7 @@ export class AccountApp extends App {
$content.state = subscription.state;
$content.plan = subscription.plan.effective.name;
$content.days = days;
$content.trialReactivationCount = subscription.plan.effective.trialReactivationCount;
}
}

+ 28
- 4
src/webviews/apps/plus/account/components/account-content.ts View File

@ -85,6 +85,9 @@ export class AccountContent extends LitElement {
@property()
plan = '';
@property({ type: Number })
trialReactivationCount = 0;
get daysRemaining() {
if (this.days < 1) {
return '<1 day';
@ -122,6 +125,10 @@ export class AccountContent extends LitElement {
return hasAccountFromSubscriptionState(this.state);
}
get isReactivatedTrial() {
return this.state === SubscriptionState.FreePlusInTrial && this.trialReactivationCount > 0;
}
private renderAccountInfo() {
if (!this.hasAccount) {
return nothing;
@ -192,15 +199,28 @@ export class AccountContent extends LitElement {
case SubscriptionState.FreePlusInTrial:
return html`
<p>
Your have ${this.daysRemaining} remaining in your GitKraken trial. Once your trial ends, you'll
need a paid plan to continue using features.
${this.isReactivatedTrial
? html`<a href="https://help.gitkraken.com/gitlens/gitlens-release-notes-current/"
>See what's new</a
>
with
${pluralize('day', this.days, {
infix: ' more ',
})}
in your GitKraken trial.`
: `You have
${this.daysRemaining} remaining in your GitKraken trial.`}
Once your trial ends, you'll need a paid plan to continue using features.
</p>
<button-container>
<gl-button full href="command:gitlens.plus.purchase">Upgrade to Pro</gl-button>
</button-container>
<p>
You have access to features on privately hosted repos and features based on the Pro plan
during your trial.
You have access to features on privately hosted repos and features based on the Pro plan.
</p>
<p>
Try our
<a href="https://www.gitkraken.com/suite">other developer tools</a> also included in your trial.
</p>
`;
@ -212,6 +232,10 @@ export class AccountContent extends LitElement {
>
</button-container>
<p>You have access to features on privately hosted repos and features based on your plan.</p>
<p>
Try our
<a href="https://www.gitkraken.com/suite">other developer tools</a> also included in your plan.
</p>
`;
}

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