Parcourir la source

Trial reactivation UX (#2962)

* Updates account messaging to support trial reactivation

* Polishes and improved messaging
main
Ramin Tadayon il y a 1 an
committed by GitHub
Parent
révision
e03275f0b8
Aucune clé connue n'a été trouvée dans la base pour cette signature ID de la clé GPG: 4AEE18F83AFDEB23
6 fichiers modifiés avec 58 ajouts et 12 suppressions
  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 Voir le fichier

@ -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 Voir le fichier

@ -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 Voir le fichier

@ -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 Voir le fichier

@ -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 Voir le fichier

@ -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 Voir le fichier

@ -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>
`;
}

Chargement…
Annuler
Enregistrer