1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-29 15:53:45 +00:00

improve performance of premium spotlight observable

This commit is contained in:
jaasen-livefront
2026-01-15 13:58:02 -08:00
parent 320fe1f1c9
commit 02560a86c2
2 changed files with 28 additions and 38 deletions

View File

@@ -5,19 +5,18 @@ import { AfterViewInit, Component, DestroyRef, OnDestroy, OnInit, ViewChild } fr
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { Router, RouterModule } from "@angular/router";
import {
BehaviorSubject,
combineLatest,
distinctUntilChanged,
filter,
firstValueFrom,
from,
map,
Observable,
shareReplay,
switchMap,
take,
withLatestFrom,
tap,
BehaviorSubject,
withLatestFrom,
} from "rxjs";
import { PremiumUpgradeDialogComponent } from "@bitwarden/angular/billing/components";
@@ -138,17 +137,8 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy {
activeUserId: UserId | null = null;
/**
* Subject that indicates whether the vault is ready to render
* and that all initialization tasks have been completed (ngOnInit).
* @private
*/
private readySubject = new BehaviorSubject(false);
/**
* Indicates whether the vault is loading and not yet ready to be displayed.
* @protected
*/
protected loading$ = combineLatest([
this.vaultPopupLoadingService.loading$,
this.readySubject.asObservable(),
@@ -169,10 +159,6 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy {
FeatureFlag.BrowserPremiumSpotlight,
);
private showPremiumNudgeSpotlight$ = this.activeUserId$.pipe(
switchMap((userId) => this.nudgesService.showNudgeSpotlight$(NudgeType.PremiumUpgrade, userId)),
);
protected favoriteCiphers$ = this.vaultPopupItemsService.favoriteCiphers$;
protected remainingCiphers$ = this.vaultPopupItemsService.remainingCiphers$;
protected allFilters$ = this.vaultPopupListFiltersService.allFilters$;
@@ -180,38 +166,39 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy {
protected hasPremium$ = this.activeUserId$.pipe(
switchMap((userId) => this.billingAccountService.hasPremiumFromAnySource$(userId)),
);
protected accountAgeInDays$ = this.activeUserId$.pipe(
switchMap((userId) => {
const creationDate$ = from(this.vaultProfileService.getProfileCreationDate(userId));
return creationDate$.pipe(
map((creationDate) => {
if (!creationDate) {
return 0;
}
const ageInMilliseconds = Date.now() - creationDate.getTime();
return Math.floor(ageInMilliseconds / (1000 * 60 * 60 * 24));
}),
);
protected accountAgeInDays$ = this.accountService.activeAccount$.pipe(
map((account) => {
if (!account || !account.creationDate) {
return 0;
}
const creationDate = account.creationDate;
const ageInMilliseconds = Date.now() - creationDate.getTime();
return Math.floor(ageInMilliseconds / (1000 * 60 * 60 * 24));
}),
);
protected showPremiumSpotlight$ = combineLatest([
this.premiumSpotlightFeatureFlag$,
this.showPremiumNudgeSpotlight$,
this.activeUserId$.pipe(
switchMap((userId) =>
this.nudgesService.showNudgeSpotlight$(NudgeType.PremiumUpgrade, userId),
),
),
this.showHasItemsVaultSpotlight$,
this.hasPremium$,
this.cipherCount$,
this.accountAgeInDays$,
]).pipe(
map(
([featureFlagEnabled, showPremiumNudge, showHasItemsNudge, hasPremium, count, age]) =>
map(([featureFlagEnabled, showPremiumNudge, showHasItemsNudge, hasPremium, count, age]) => {
return (
featureFlagEnabled &&
showPremiumNudge &&
!showHasItemsNudge &&
!hasPremium &&
count >= 5 &&
age >= 7,
),
age >= 7
);
}),
shareReplay({ bufferSize: 1, refCount: true }),
);

View File

@@ -1,8 +1,8 @@
import { inject, Injectable } from "@angular/core";
import { combineLatest, from, Observable, of, switchMap } from "rxjs";
import { catchError } from "rxjs/operators";
import { combineLatest, Observable, of, switchMap } from "rxjs";
import { catchError, map } from "rxjs/operators";
import { VaultProfileService } from "@bitwarden/angular/vault/services/vault-profile.service";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { UserId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
@@ -20,11 +20,14 @@ const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000;
})
export class HasItemsNudgeService extends DefaultSingleNudgeService {
cipherService = inject(CipherService);
vaultProfileService = inject(VaultProfileService);
accountService = inject(AccountService);
logService = inject(LogService);
nudgeStatus$(nudgeType: NudgeType, userId: UserId): Observable<NudgeStatus> {
const profileDate$ = from(this.vaultProfileService.getProfileCreationDate(userId)).pipe(
const profileDate$ = this.accountService.activeAccount$.pipe(
map((account) => {
return account?.creationDate ?? new Date();
}),
catchError(() => {
this.logService.error("Error getting profile creation date");
// Default to today to ensure we show the nudge