diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts index 7f401461b1..504abbe158 100644 --- a/apps/browser/src/popup/app.component.ts +++ b/apps/browser/src/popup/app.component.ts @@ -1,7 +1,15 @@ -import { ChangeDetectorRef, Component, NgZone, OnInit, SecurityContext } from "@angular/core"; +import { + ChangeDetectorRef, + Component, + NgZone, + OnDestroy, + OnInit, + SecurityContext, +} from "@angular/core"; import { DomSanitizer } from "@angular/platform-browser"; import { NavigationEnd, Router, RouterOutlet } from "@angular/router"; import { IndividualConfig, ToastrService } from "ngx-toastr"; +import { Subject, takeUntil } from "rxjs"; import Swal, { SweetAlertIcon } from "sweetalert2"; import { AuthService } from "@bitwarden/common/abstractions/auth.service"; @@ -23,10 +31,12 @@ import { routerTransition } from "./app-routing.animations"; `, }) -export class AppComponent implements OnInit { +export class AppComponent implements OnInit, OnDestroy { private lastActivity: number = null; private activeUserId: string; + private destroy$: Subject = new Subject(); + constructor( private toastrService: ToastrService, private broadcasterService: BroadcasterService, @@ -46,7 +56,7 @@ export class AppComponent implements OnInit { // Clear them aggressively to make sure this doesn't occur await this.clearComponentStates(); - this.stateService.activeAccount.subscribe((userId) => { + this.stateService.activeAccount.pipe(takeUntil(this.destroy$)).subscribe((userId) => { this.activeUserId = userId; }); @@ -121,7 +131,7 @@ export class AppComponent implements OnInit { BrowserApi.messageListener("app.component", (window as any).bitwardenPopupMainMessageListener); - this.router.events.subscribe(async (event) => { + this.router.events.pipe(takeUntil(this.destroy$)).subscribe(async (event) => { if (event instanceof NavigationEnd) { const url = event.urlAfterRedirects || event.url || ""; if ( @@ -146,6 +156,11 @@ export class AppComponent implements OnInit { }); } + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } + getState(outlet: RouterOutlet) { if (outlet.activatedRouteData.state === "ciphers") { const routeDirection = diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts index 300104ee72..9732173b56 100644 --- a/apps/desktop/src/app/app.component.ts +++ b/apps/desktop/src/app/app.component.ts @@ -10,6 +10,7 @@ import { import { DomSanitizer } from "@angular/platform-browser"; import { Router } from "@angular/router"; import { IndividualConfig, ToastrService } from "ngx-toastr"; +import { Subject, takeUntil } from "rxjs"; import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref"; import { ModalService } from "@bitwarden/angular/services/modal.service"; @@ -96,6 +97,8 @@ export class AppComponent implements OnInit { private isIdle = false; private activeUserId: string = null; + private destroy$: Subject = new Subject(); + constructor( private broadcasterService: BroadcasterService, private tokenService: TokenService, @@ -127,9 +130,10 @@ export class AppComponent implements OnInit { ) {} ngOnInit() { - this.stateService.activeAccount.subscribe((userId) => { + this.stateService.activeAccount.pipe(takeUntil(this.destroy$)).subscribe((userId) => { this.activeUserId = userId; }); + this.ngZone.runOutsideAngular(() => { setTimeout(async () => { await this.updateAppMenu(); @@ -360,6 +364,8 @@ export class AppComponent implements OnInit { } ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); this.broadcasterService.unsubscribe(BroadcasterSubscriptionId); }