1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-24 12:06:15 +01:00

[PM-1400] Update IconComponent to use OnPush ChangeDetection (#5181)

* Add disableFavicon$ to stateService

* Change IconComponent's ChangeDetectionStrategy and use disableFavicon$ observable

* Only get first result from disableFavicon observable

* Move disabledFavicon$ to SettingsService

* Update usage of disableFavicon to use SettingsService

* Remove getting and setting of disabledFavicon on login

* Settings service observable adjustments

* Fix for popup initially having a null value for the disableFavicon setting in settingsService

* Move disabledFavicon$ subscription to ngOnInit

* feat: experiment with observables

* Remove SettingsService from browser app component

* Fix storybook changes

* Update apps/web/src/app/vault/components/vault-items/vault-items.stories.ts

Co-authored-by: Andreas Coroiu <acoroiu@bitwarden.com>

* Fix mock function signature

---------

Co-authored-by: Andreas Coroiu <andreas.coroiu@gmail.com>
Co-authored-by: Andreas Coroiu <acoroiu@bitwarden.com>
This commit is contained in:
Robyn MacCallum 2023-04-28 15:07:26 -04:00 committed by GitHub
parent a899ea370e
commit 671a9115bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 164 additions and 109 deletions

View File

@ -3,6 +3,7 @@ import { Component, OnInit } from "@angular/core";
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction"; import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service"; import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { SettingsService } from "@bitwarden/common/abstractions/settings.service";
import { StateService } from "@bitwarden/common/abstractions/state.service"; import { StateService } from "@bitwarden/common/abstractions/state.service";
import { TotpService } from "@bitwarden/common/abstractions/totp.service"; import { TotpService } from "@bitwarden/common/abstractions/totp.service";
import { ThemeType, UriMatchType } from "@bitwarden/common/enums"; import { ThemeType, UriMatchType } from "@bitwarden/common/enums";
@ -39,7 +40,8 @@ export class OptionsComponent implements OnInit {
private stateService: StateService, private stateService: StateService,
private totpService: TotpService, private totpService: TotpService,
i18nService: I18nService, i18nService: I18nService,
private themingService: AbstractThemingService private themingService: AbstractThemingService,
private settingsService: SettingsService
) { ) {
this.themeOptions = [ this.themeOptions = [
{ name: i18nService.t("default"), value: ThemeType.System }, { name: i18nService.t("default"), value: ThemeType.System },
@ -89,7 +91,7 @@ export class OptionsComponent implements OnInit {
this.enableAutoTotpCopy = !(await this.stateService.getDisableAutoTotpCopy()); this.enableAutoTotpCopy = !(await this.stateService.getDisableAutoTotpCopy());
this.enableFavicon = !(await this.stateService.getDisableFavicon()); this.enableFavicon = !this.settingsService.getDisableFavicon();
this.enableBadgeCounter = !(await this.stateService.getDisableBadgeCounter()); this.enableBadgeCounter = !(await this.stateService.getDisableBadgeCounter());
@ -129,7 +131,7 @@ export class OptionsComponent implements OnInit {
} }
async updateFavicon() { async updateFavicon() {
await this.stateService.setDisableFavicon(!this.enableFavicon); await this.settingsService.setDisableFavicon(!this.enableFavicon);
} }
async updateBadgeCounter() { async updateBadgeCounter() {

View File

@ -3,9 +3,13 @@ import { BehaviorSubject } from "rxjs";
import { AccountSettingsSettings } from "@bitwarden/common/models/domain/account"; import { AccountSettingsSettings } from "@bitwarden/common/models/domain/account";
import { SettingsService } from "@bitwarden/common/services/settings.service"; import { SettingsService } from "@bitwarden/common/services/settings.service";
import { sessionSync } from "../decorators/session-sync-observable"; import { browserSession, sessionSync } from "../decorators/session-sync-observable";
@browserSession
export class BrowserSettingsService extends SettingsService { export class BrowserSettingsService extends SettingsService {
@sessionSync({ initializer: (obj: string[][]) => obj }) @sessionSync({ initializer: (obj: string[][]) => obj })
protected _settings: BehaviorSubject<AccountSettingsSettings>; protected _settings: BehaviorSubject<AccountSettingsSettings>;
@sessionSync({ initializer: (b: boolean) => b })
protected _disableFavicon: BehaviorSubject<boolean>;
} }

View File

@ -9,10 +9,11 @@ import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service"; import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { SettingsService } from "@bitwarden/common/abstractions/settings.service";
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { DeviceType, ThemeType, StorageLocation, KeySuffixOptions } from "@bitwarden/common/enums"; import { DeviceType, ThemeType, KeySuffixOptions } from "@bitwarden/common/enums";
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
import { Utils } from "@bitwarden/common/misc/utils"; import { Utils } from "@bitwarden/common/misc/utils";
@ -107,7 +108,8 @@ export class SettingsComponent implements OnInit {
private messagingService: MessagingService, private messagingService: MessagingService,
private cryptoService: CryptoService, private cryptoService: CryptoService,
private modalService: ModalService, private modalService: ModalService,
private themingService: AbstractThemingService private themingService: AbstractThemingService,
private settingsService: SettingsService
) { ) {
const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop; const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
@ -437,10 +439,7 @@ export class SettingsComponent implements OnInit {
} }
async saveFavicons() { async saveFavicons() {
await this.stateService.setDisableFavicon(!this.form.value.enableFavicons); await this.settingsService.setDisableFavicon(!this.form.value.enableFavicons);
await this.stateService.setDisableFavicon(!this.form.value.enableFavicons, {
storageLocation: StorageLocation.Disk,
});
this.messagingService.send("refreshCiphers"); this.messagingService.send("refreshCiphers");
} }

View File

@ -6,6 +6,7 @@ import { AbstractThemingService } from "@bitwarden/angular/services/theming/them
import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { MessagingService } from "@bitwarden/common/abstractions/messaging.service"; import { MessagingService } from "@bitwarden/common/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { SettingsService } from "@bitwarden/common/abstractions/settings.service";
import { StateService } from "@bitwarden/common/abstractions/state.service"; import { StateService } from "@bitwarden/common/abstractions/state.service";
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaultTimeout/vaultTimeoutSettings.service";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
@ -51,7 +52,8 @@ export class PreferencesComponent implements OnInit {
private vaultTimeoutSettingsService: VaultTimeoutSettingsService, private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
private platformUtilsService: PlatformUtilsService, private platformUtilsService: PlatformUtilsService,
private messagingService: MessagingService, private messagingService: MessagingService,
private themingService: AbstractThemingService private themingService: AbstractThemingService,
private settingsService: SettingsService
) { ) {
this.vaultTimeoutOptions = [ this.vaultTimeoutOptions = [
{ name: i18nService.t("oneMinute"), value: 1 }, { name: i18nService.t("oneMinute"), value: 1 },
@ -128,11 +130,10 @@ export class PreferencesComponent implements OnInit {
takeUntil(this.destroy$) takeUntil(this.destroy$)
) )
.subscribe(); .subscribe();
const initialFormValues = { const initialFormValues = {
vaultTimeout: await this.vaultTimeoutSettingsService.getVaultTimeout(), vaultTimeout: await this.vaultTimeoutSettingsService.getVaultTimeout(),
vaultTimeoutAction: await this.vaultTimeoutSettingsService.getVaultTimeoutAction(), vaultTimeoutAction: await this.vaultTimeoutSettingsService.getVaultTimeoutAction(),
enableFavicons: !(await this.stateService.getDisableFavicon()), enableFavicons: !(await this.settingsService.getDisableFavicon()),
enableFullWidth: await this.stateService.getEnableFullWidth(), enableFullWidth: await this.stateService.getEnableFullWidth(),
theme: await this.stateService.getTheme(), theme: await this.stateService.getTheme(),
locale: (await this.stateService.getLocale()) ?? null, locale: (await this.stateService.getLocale()) ?? null,
@ -157,7 +158,7 @@ export class PreferencesComponent implements OnInit {
values.vaultTimeout, values.vaultTimeout,
values.vaultTimeoutAction values.vaultTimeoutAction
); );
await this.stateService.setDisableFavicon(!values.enableFavicons); await this.settingsService.setDisableFavicon(!values.enableFavicons);
await this.stateService.setEnableFullWidth(values.enableFullWidth); await this.stateService.setEnableFullWidth(values.enableFullWidth);
this.messagingService.send("setFullWidth"); this.messagingService.send("setFullWidth");
if (values.theme !== this.startingTheme) { if (values.theme !== this.startingTheme) {

View File

@ -5,6 +5,7 @@ import { BehaviorSubject } from "rxjs";
import { AvatarUpdateService } from "@bitwarden/common/abstractions/account/avatar-update.service"; import { AvatarUpdateService } from "@bitwarden/common/abstractions/account/avatar-update.service";
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service"; import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
import { SettingsService } from "@bitwarden/common/abstractions/settings.service";
import { StateService } from "@bitwarden/common/abstractions/state.service"; import { StateService } from "@bitwarden/common/abstractions/state.service";
import { OrganizationUserType } from "@bitwarden/common/admin-console/enums"; import { OrganizationUserType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
@ -69,6 +70,15 @@ export default {
}, },
} as Partial<StateService>, } as Partial<StateService>,
}, },
{
provide: SettingsService,
useValue: {
disableFavicon$: new BehaviorSubject(false).asObservable(),
getDisableFavicon() {
return false;
},
} as Partial<SettingsService>,
},
{ {
provide: AvatarUpdateService, provide: AvatarUpdateService,
useValue: { useValue: {

View File

@ -260,8 +260,6 @@ export class LockComponent implements OnInit, OnDestroy {
private async doContinue(evaluatePasswordAfterUnlock: boolean) { private async doContinue(evaluatePasswordAfterUnlock: boolean) {
await this.stateService.setEverBeenUnlocked(true); await this.stateService.setEverBeenUnlocked(true);
const disableFavicon = await this.stateService.getDisableFavicon();
await this.stateService.setDisableFavicon(!!disableFavicon);
this.messagingService.send("unlocked"); this.messagingService.send("unlocked");
if (evaluatePasswordAfterUnlock) { if (evaluatePasswordAfterUnlock) {

View File

@ -152,8 +152,6 @@ export class LoginComponent extends CaptchaProtectedComponent implements OnInit
this.router.navigate([this.forcePasswordResetRoute]); this.router.navigate([this.forcePasswordResetRoute]);
} }
} else { } else {
const disableFavicon = await this.stateService.getDisableFavicon();
await this.stateService.setDisableFavicon(!!disableFavicon);
if (this.onSuccessfulLogin != null) { if (this.onSuccessfulLogin != null) {
this.onSuccessfulLogin(); this.onSuccessfulLogin();
} }

View File

@ -212,8 +212,6 @@ export class SsoComponent {
this.router.navigate([this.forcePasswordResetRoute]); this.router.navigate([this.forcePasswordResetRoute]);
} }
} else { } else {
const disableFavicon = await this.stateService.getDisableFavicon();
await this.stateService.setDisableFavicon(!!disableFavicon);
if (this.onSuccessfulLogin != null) { if (this.onSuccessfulLogin != null) {
await this.onSuccessfulLogin(); await this.onSuccessfulLogin();
} }

View File

@ -197,8 +197,6 @@ export class TwoFactorComponent extends CaptchaProtectedComponent implements OnI
this.captchaToken this.captchaToken
); );
const response: AuthResult = await this.formPromise; const response: AuthResult = await this.formPromise;
const disableFavicon = await this.stateService.getDisableFavicon();
await this.stateService.setDisableFavicon(!!disableFavicon);
if (this.handleCaptchaRequired(response)) { if (this.handleCaptchaRequired(response)) {
return; return;
} }

View File

@ -1,11 +1,16 @@
<div class="icon" aria-hidden="true"> <div class="icon" aria-hidden="true">
<img <ng-container *ngIf="data$ | async as data">
[src]="image" <img
appFallbackSrc="{{ fallbackImage }}" [src]="data.image"
*ngIf="imageEnabled && image" [appFallbackSrc]="data.fallbackImage"
alt="" *ngIf="data.imageEnabled && data.image"
decoding="async" alt=""
loading="lazy" decoding="async"
/> loading="lazy"
<i class="tw-text-muted bwi bwi-lg {{ icon }}" *ngIf="!imageEnabled || !image"></i> />
<i
class="tw-text-muted bwi bwi-lg {{ data.icon }}"
*ngIf="!data.imageEnabled || !data.image"
></i>
</ng-container>
</div> </div>

View File

@ -1,7 +1,15 @@
import { Component, Input, OnChanges } from "@angular/core"; import { ChangeDetectionStrategy, Component, Input, OnInit } from "@angular/core";
import {
BehaviorSubject,
combineLatest,
distinctUntilChanged,
filter,
map,
Observable,
} from "rxjs";
import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service"; import { EnvironmentService } from "@bitwarden/common/abstractions/environment.service";
import { StateService } from "@bitwarden/common/abstractions/state.service"; import { SettingsService } from "@bitwarden/common/abstractions/settings.service";
import { Utils } from "@bitwarden/common/misc/utils"; import { Utils } from "@bitwarden/common/misc/utils";
import { CipherType } from "@bitwarden/common/vault/enums/cipher-type"; import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
@ -25,89 +33,101 @@ const cardIcons: Record<string, string> = {
@Component({ @Component({
selector: "app-vault-icon", selector: "app-vault-icon",
templateUrl: "icon.component.html", templateUrl: "icon.component.html",
changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class IconComponent implements OnChanges { export class IconComponent implements OnInit {
@Input() cipher: CipherView; @Input()
icon: string; set cipher(value: CipherView) {
image: string; this.cipher$.next(value);
fallbackImage: string;
imageEnabled: boolean;
private iconsUrl: string;
constructor(environmentService: EnvironmentService, private stateService: StateService) {
this.iconsUrl = environmentService.getIconsUrl();
} }
async ngOnChanges() { protected data$: Observable<{
// Components may be re-used when using cdk-virtual-scroll. Which puts the component in a weird state, imageEnabled: boolean;
// to avoid this we reset all state variables. image?: string;
this.image = null; fallbackImage: string;
this.fallbackImage = null; icon?: string;
this.imageEnabled = !(await this.stateService.getDisableFavicon()); }>;
this.load();
}
protected load() { private cipher$ = new BehaviorSubject<CipherView>(undefined);
switch (this.cipher.type) {
case CipherType.Login:
this.icon = "bwi-globe";
this.setLoginIcon();
break;
case CipherType.SecureNote:
this.icon = "bwi-sticky-note";
break;
case CipherType.Card:
this.icon = "bwi-credit-card";
this.setCardIcon();
break;
case CipherType.Identity:
this.icon = "bwi-id-card";
break;
default:
break;
}
}
private setLoginIcon() { constructor(
if (this.cipher.login.uri) { private environmentService: EnvironmentService,
let hostnameUri = this.cipher.login.uri; private settingsService: SettingsService
let isWebsite = false; ) {}
if (hostnameUri.indexOf("androidapp://") === 0) { async ngOnInit() {
this.icon = "bwi-android"; const iconsUrl = this.environmentService.getIconsUrl();
this.image = null;
} else if (hostnameUri.indexOf("iosapp://") === 0) {
this.icon = "bwi-apple";
this.image = null;
} else if (
this.imageEnabled &&
hostnameUri.indexOf("://") === -1 &&
hostnameUri.indexOf(".") > -1
) {
hostnameUri = "http://" + hostnameUri;
isWebsite = true;
} else if (this.imageEnabled) {
isWebsite = hostnameUri.indexOf("http") === 0 && hostnameUri.indexOf(".") > -1;
}
if (this.imageEnabled && isWebsite) { this.data$ = combineLatest([
try { this.settingsService.disableFavicon$.pipe(distinctUntilChanged()),
this.image = this.iconsUrl + "/" + Utils.getHostname(hostnameUri) + "/icon.png"; this.cipher$.pipe(filter((c) => c !== undefined)),
this.fallbackImage = "images/bwi-globe.png"; ]).pipe(
} catch (e) { map(([disableFavicon, cipher]) => {
// Ignore error since the fallback icon will be shown if image is null. const imageEnabled = !disableFavicon;
let image = undefined;
let fallbackImage = "";
let icon = undefined;
switch (cipher.type) {
case CipherType.Login:
icon = "bwi-globe";
if (cipher.login.uri) {
let hostnameUri = cipher.login.uri;
let isWebsite = false;
if (hostnameUri.indexOf("androidapp://") === 0) {
icon = "bwi-android";
image = null;
} else if (hostnameUri.indexOf("iosapp://") === 0) {
icon = "bwi-apple";
image = null;
} else if (
imageEnabled &&
hostnameUri.indexOf("://") === -1 &&
hostnameUri.indexOf(".") > -1
) {
hostnameUri = "http://" + hostnameUri;
isWebsite = true;
} else if (imageEnabled) {
isWebsite = hostnameUri.indexOf("http") === 0 && hostnameUri.indexOf(".") > -1;
}
if (imageEnabled && isWebsite) {
try {
image = iconsUrl + "/" + Utils.getHostname(hostnameUri) + "/icon.png";
fallbackImage = "images/bwi-globe.png";
} catch (e) {
// Ignore error since the fallback icon will be shown if image is null.
}
}
} else {
image = null;
}
break;
case CipherType.SecureNote:
icon = "bwi-sticky-note";
break;
case CipherType.Card:
icon = "bwi-credit-card";
if (imageEnabled && cipher.card.brand in cardIcons) {
icon = "credit-card-icon " + cardIcons[cipher.card.brand];
}
break;
case CipherType.Identity:
icon = "bwi-id-card";
break;
default:
break;
} }
}
} else {
this.image = null;
}
}
private setCardIcon() { return {
const brand = this.cipher.card.brand; imageEnabled,
if (this.imageEnabled && brand in cardIcons) { image,
this.icon = "credit-card-icon " + cardIcons[brand]; fallbackImage,
} icon,
};
})
);
} }
} }

View File

@ -4,8 +4,11 @@ import { AccountSettingsSettings } from "../models/domain/account";
export abstract class SettingsService { export abstract class SettingsService {
settings$: Observable<AccountSettingsSettings>; settings$: Observable<AccountSettingsSettings>;
disableFavicon$: Observable<boolean>;
setEquivalentDomains: (equivalentDomains: string[][]) => Promise<any>; setEquivalentDomains: (equivalentDomains: string[][]) => Promise<any>;
getEquivalentDomains: (url: string) => Set<string>; getEquivalentDomains: (url: string) => Set<string>;
setDisableFavicon: (value: boolean) => Promise<any>;
getDisableFavicon: () => boolean;
clear: (userId?: string) => Promise<void>; clear: (userId?: string) => Promise<void>;
} }

View File

@ -145,7 +145,13 @@ export abstract class StateService<T extends Account = Account> {
) => Promise<void>; ) => Promise<void>;
getDisableContextMenuItem: (options?: StorageOptions) => Promise<boolean>; getDisableContextMenuItem: (options?: StorageOptions) => Promise<boolean>;
setDisableContextMenuItem: (value: boolean, options?: StorageOptions) => Promise<void>; setDisableContextMenuItem: (value: boolean, options?: StorageOptions) => Promise<void>;
/**
* @deprecated Do not call this, use SettingsService
*/
getDisableFavicon: (options?: StorageOptions) => Promise<boolean>; getDisableFavicon: (options?: StorageOptions) => Promise<boolean>;
/**
* @deprecated Do not call this, use SettingsService
*/
setDisableFavicon: (value: boolean, options?: StorageOptions) => Promise<void>; setDisableFavicon: (value: boolean, options?: StorageOptions) => Promise<void>;
getDisableGa: (options?: StorageOptions) => Promise<boolean>; getDisableGa: (options?: StorageOptions) => Promise<boolean>;
setDisableGa: (value: boolean, options?: StorageOptions) => Promise<void>; setDisableGa: (value: boolean, options?: StorageOptions) => Promise<void>;

View File

@ -7,8 +7,10 @@ import { AccountSettingsSettings } from "../models/domain/account";
export class SettingsService implements SettingsServiceAbstraction { export class SettingsService implements SettingsServiceAbstraction {
protected _settings: BehaviorSubject<AccountSettingsSettings> = new BehaviorSubject({}); protected _settings: BehaviorSubject<AccountSettingsSettings> = new BehaviorSubject({});
protected _disableFavicon = new BehaviorSubject<boolean>(null);
settings$ = this._settings.asObservable(); settings$ = this._settings.asObservable();
disableFavicon$ = this._disableFavicon.asObservable();
constructor(private stateService: StateService) { constructor(private stateService: StateService) {
this.stateService.activeAccountUnlocked$ this.stateService.activeAccountUnlocked$
@ -24,8 +26,10 @@ export class SettingsService implements SettingsServiceAbstraction {
} }
const data = await this.stateService.getSettings(); const data = await this.stateService.getSettings();
const disableFavicon = await this.stateService.getDisableFavicon();
this._settings.next(data); this._settings.next(data);
this._disableFavicon.next(disableFavicon);
}) })
) )
.subscribe(); .subscribe();
@ -61,6 +65,15 @@ export class SettingsService implements SettingsServiceAbstraction {
return new Set(result); return new Set(result);
} }
async setDisableFavicon(value: boolean) {
this._disableFavicon.next(value);
await this.stateService.setDisableFavicon(value);
}
getDisableFavicon(): boolean {
return this._disableFavicon.getValue();
}
async clear(userId?: string): Promise<void> { async clear(userId?: string): Promise<void> {
if (userId == null || userId == (await this.stateService.getUserId())) { if (userId == null || userId == (await this.stateService.getUserId())) {
this._settings.next({}); this._settings.next({});

View File

@ -103,7 +103,6 @@ export class StateService<
} else if (userId == null) { } else if (userId == null) {
this.activeAccountUnlockedSubject.next(false); this.activeAccountUnlockedSubject.next(false);
} }
// FIXME: This should be refactored into AuthService or a similar service, // FIXME: This should be refactored into AuthService or a similar service,
// as checking for the existence of the crypto key is a low level // as checking for the existence of the crypto key is a low level
// implementation detail. // implementation detail.
@ -130,6 +129,7 @@ export class StateService<
} }
}); });
await this.initAccountState(); await this.initAccountState();
this.hasBeenInited = true; this.hasBeenInited = true;
} }