Browse Source

Feature/improve subscription interstitial (#4612)

* Improve algorithm

* Set up skip button delay
pull/4613/head
Thomas Kaul 3 days ago
committed by GitHub
parent
commit
b2dcb1e7ac
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 10
      apps/api/src/app/user/user.service.ts
  2. 44
      apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts
  3. 23
      apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html
  4. 1
      apps/client/src/app/services/user/user.service.ts

10
apps/api/src/app/user/user.service.ts

@ -356,18 +356,20 @@ export class UserService {
new Date(), new Date(),
user.createdAt user.createdAt
); );
let frequency = 10; let frequency = 7;
if (daysSinceRegistration > 365) { if (daysSinceRegistration > 720) {
frequency = 1;
} else if (daysSinceRegistration > 360) {
frequency = 2; frequency = 2;
} else if (daysSinceRegistration > 180) { } else if (daysSinceRegistration > 180) {
frequency = 3; frequency = 3;
} else if (daysSinceRegistration > 60) { } else if (daysSinceRegistration > 60) {
frequency = 4; frequency = 4;
} else if (daysSinceRegistration > 30) { } else if (daysSinceRegistration > 30) {
frequency = 6; frequency = 5;
} else if (daysSinceRegistration > 15) { } else if (daysSinceRegistration > 15) {
frequency = 8; frequency = 6;
} }
if (Analytics?.activityCount % frequency === 1) { if (Analytics?.activityCount % frequency === 1) {

44
apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts

@ -1,5 +1,14 @@
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
Inject,
OnInit
} from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import ms from 'ms';
import { interval, Subject } from 'rxjs';
import { take, takeUntil, tap } from 'rxjs/operators';
import { SubscriptionInterstitialDialogParams } from './interfaces/interfaces'; import { SubscriptionInterstitialDialogParams } from './interfaces/interfaces';
@ -11,20 +20,47 @@ import { SubscriptionInterstitialDialogParams } from './interfaces/interfaces';
templateUrl: 'subscription-interstitial-dialog.html', templateUrl: 'subscription-interstitial-dialog.html',
standalone: false standalone: false
}) })
export class SubscriptionInterstitialDialog { export class SubscriptionInterstitialDialog implements OnInit {
private readonly VARIANTS_COUNT = 2; private static readonly SKIP_BUTTON_DELAY_IN_SECONDS = 5;
private static readonly VARIANTS_COUNT = 2;
public remainingSkipButtonDelay =
SubscriptionInterstitialDialog.SKIP_BUTTON_DELAY_IN_SECONDS;
public routerLinkPricing = ['/' + $localize`:snake-case:pricing`]; public routerLinkPricing = ['/' + $localize`:snake-case:pricing`];
public variantIndex: number; public variantIndex: number;
private unsubscribeSubject = new Subject<void>();
public constructor( public constructor(
private changeDetectorRef: ChangeDetectorRef,
@Inject(MAT_DIALOG_DATA) public data: SubscriptionInterstitialDialogParams, @Inject(MAT_DIALOG_DATA) public data: SubscriptionInterstitialDialogParams,
public dialogRef: MatDialogRef<SubscriptionInterstitialDialog> public dialogRef: MatDialogRef<SubscriptionInterstitialDialog>
) { ) {
this.variantIndex = Math.floor(Math.random() * this.VARIANTS_COUNT); this.variantIndex = Math.floor(
Math.random() * SubscriptionInterstitialDialog.VARIANTS_COUNT
);
}
public ngOnInit() {
interval(ms('1 second'))
.pipe(
take(SubscriptionInterstitialDialog.SKIP_BUTTON_DELAY_IN_SECONDS),
tap(() => {
this.remainingSkipButtonDelay--;
this.changeDetectorRef.markForCheck();
}),
takeUntil(this.unsubscribeSubject)
)
.subscribe();
} }
public closeDialog() { public closeDialog() {
this.dialogRef.close({}); this.dialogRef.close({});
} }
public ngOnDestroy() {
this.unsubscribeSubject.next();
this.unsubscribeSubject.complete();
}
} }

23
apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html

@ -51,7 +51,16 @@
</div> </div>
</div> </div>
<div class="justify-content-end" mat-dialog-actions> <div class="justify-content-end" mat-dialog-actions>
<button i18n mat-button (click)="closeDialog()">Skip</button> <button
mat-button
[disabled]="remainingSkipButtonDelay > 0"
(click)="closeDialog()"
>
<ng-container i18n>Skip</ng-container>
@if (remainingSkipButtonDelay > 0) {
({{ remainingSkipButtonDelay }})
}
</button>
<a <a
color="primary" color="primary"
mat-flat-button mat-flat-button
@ -80,8 +89,16 @@
</div> </div>
</div> </div>
<div class="flex-column" mat-dialog-actions> <div class="flex-column" mat-dialog-actions>
<button class="mb-2 py-4 w-100" i18n mat-button (click)="closeDialog()"> <button
Skip class="mb-2 py-4 w-100"
mat-button
[disabled]="remainingSkipButtonDelay > 0"
(click)="closeDialog()"
>
<ng-container i18n>Skip</ng-container>
@if (remainingSkipButtonDelay > 0) {
({{ remainingSkipButtonDelay }})
}
</button> </button>
<a <a
class="m-0 py-4 w-100" class="m-0 py-4 w-100"

1
apps/client/src/app/services/user/user.service.ts

@ -121,6 +121,7 @@ export class UserService extends ObservableStore<UserStoreState> {
data: { data: {
user user
} as SubscriptionInterstitialDialogParams, } as SubscriptionInterstitialDialogParams,
disableClose: true,
height: this.deviceType === 'mobile' ? '98vh' : '80vh', height: this.deviceType === 'mobile' ? '98vh' : '80vh',
width: this.deviceType === 'mobile' ? '100vw' : '50rem' width: this.deviceType === 'mobile' ? '100vw' : '50rem'
}); });

Loading…
Cancel
Save