[refactor] Introduce ThemingService (#2943)
* [refactor] Introduce ThemingService * [refactor] Implement ThemingService for web * [refactor] Implement ThemingService on browser * [refactor] Implement ThemingService for desktop * [refactor] Remove deprecated platformUtils.service theme methods * [fix] Move ThemingService from libs/common to libs/angular * [fix] Simplify ThemeBuilder's constructor * [fix] Dont notify subscribers of null values from theme$ * [fix] Always notify PaymentComponent of theme changes
This commit is contained in:
parent
fd69e163ff
commit
57b8144013
|
@ -1,5 +1,6 @@
|
||||||
import { A11yModule } from "@angular/cdk/a11y";
|
import { A11yModule } from "@angular/cdk/a11y";
|
||||||
import { DragDropModule } from "@angular/cdk/drag-drop";
|
import { DragDropModule } from "@angular/cdk/drag-drop";
|
||||||
|
import { LayoutModule } from "@angular/cdk/layout";
|
||||||
import { OverlayModule } from "@angular/cdk/overlay";
|
import { OverlayModule } from "@angular/cdk/overlay";
|
||||||
import { ScrollingModule } from "@angular/cdk/scrolling";
|
import { ScrollingModule } from "@angular/cdk/scrolling";
|
||||||
import { CurrencyPipe, DatePipe, registerLocaleData } from "@angular/common";
|
import { CurrencyPipe, DatePipe, registerLocaleData } from "@angular/common";
|
||||||
|
@ -181,6 +182,7 @@ registerLocaleData(localeZhTw, "zh-TW");
|
||||||
DragDropModule,
|
DragDropModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
JslibModule,
|
JslibModule,
|
||||||
|
LayoutModule,
|
||||||
OverlayModule,
|
OverlayModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
ScrollingModule,
|
ScrollingModule,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Injectable } from "@angular/core";
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
|
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 { LogService as LogServiceAbstraction } from "@bitwarden/common/abstractions/log.service";
|
import { LogService as LogServiceAbstraction } from "@bitwarden/common/abstractions/log.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||||
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
|
||||||
|
|
||||||
import { StateService as StateServiceAbstraction } from "../../services/abstractions/state.service";
|
import { StateService as StateServiceAbstraction } from "../../services/abstractions/state.service";
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@ export class InitService {
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private popupUtilsService: PopupUtilsService,
|
private popupUtilsService: PopupUtilsService,
|
||||||
private stateService: StateServiceAbstraction,
|
private stateService: StateServiceAbstraction,
|
||||||
private logService: LogServiceAbstraction
|
private logService: LogServiceAbstraction,
|
||||||
|
private themingService: AbstractThemingService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
@ -32,15 +33,7 @@ export class InitService {
|
||||||
}
|
}
|
||||||
|
|
||||||
const htmlEl = window.document.documentElement;
|
const htmlEl = window.document.documentElement;
|
||||||
const theme = await this.platformUtilsService.getEffectiveTheme();
|
await this.themingService.monitorThemeChanges();
|
||||||
htmlEl.classList.add("theme_" + theme);
|
|
||||||
this.platformUtilsService.onDefaultSystemThemeChange(async (sysTheme) => {
|
|
||||||
const bwTheme = await this.stateService.getTheme();
|
|
||||||
if (bwTheme == null || bwTheme === ThemeType.System) {
|
|
||||||
htmlEl.classList.remove("theme_" + ThemeType.Light, "theme_" + ThemeType.Dark);
|
|
||||||
htmlEl.classList.add("theme_" + sysTheme);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
htmlEl.classList.add("locale_" + this.i18nService.translationLocale);
|
htmlEl.classList.add("locale_" + this.i18nService.translationLocale);
|
||||||
|
|
||||||
// Workaround for slow performance on external monitors on Chrome + MacOS
|
// Workaround for slow performance on external monitors on Chrome + MacOS
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
|
||||||
|
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 { StateService } from "@bitwarden/common/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||||
|
@ -38,7 +39,8 @@ export class OptionsComponent implements OnInit {
|
||||||
private messagingService: MessagingService,
|
private messagingService: MessagingService,
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private totpService: TotpService,
|
private totpService: TotpService,
|
||||||
i18nService: I18nService
|
i18nService: I18nService,
|
||||||
|
private themingService: AbstractThemingService
|
||||||
) {
|
) {
|
||||||
this.themeOptions = [
|
this.themeOptions = [
|
||||||
{ name: i18nService.t("default"), value: ThemeType.System },
|
{ name: i18nService.t("default"), value: ThemeType.System },
|
||||||
|
@ -145,8 +147,7 @@ export class OptionsComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveTheme() {
|
async saveTheme() {
|
||||||
await this.stateService.setTheme(this.theme);
|
await this.themingService.updateConfiguredTheme(this.theme);
|
||||||
window.setTimeout(() => window.location.reload(), 200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveDefaultUriMatch() {
|
async saveDefaultUriMatch() {
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { MessagingService } from "@bitwarden/common/abstractions/messaging.servi
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||||
import { ClientType } from "@bitwarden/common/enums/clientType";
|
import { ClientType } from "@bitwarden/common/enums/clientType";
|
||||||
import { DeviceType } from "@bitwarden/common/enums/deviceType";
|
import { DeviceType } from "@bitwarden/common/enums/deviceType";
|
||||||
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
|
||||||
|
|
||||||
import { BrowserApi } from "../browser/browserApi";
|
import { BrowserApi } from "../browser/browserApi";
|
||||||
import { SafariApp } from "../browser/safariApp";
|
import { SafariApp } from "../browser/safariApp";
|
||||||
|
@ -17,7 +16,6 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
||||||
{ tryResolve: (canceled: boolean, password: string) => Promise<boolean>; date: Date }
|
{ tryResolve: (canceled: boolean, password: string) => Promise<boolean>; date: Date }
|
||||||
>();
|
>();
|
||||||
private deviceCache: DeviceType = null;
|
private deviceCache: DeviceType = null;
|
||||||
private prefersColorSchemeDark = window.matchMedia("(prefers-color-scheme: dark)");
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private messagingService: MessagingService,
|
private messagingService: MessagingService,
|
||||||
|
@ -355,23 +353,4 @@ export default class BrowserPlatformUtilsService implements PlatformUtilsService
|
||||||
supportsSecureStorage(): boolean {
|
supportsSecureStorage(): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultSystemTheme(): Promise<ThemeType.Light | ThemeType.Dark> {
|
|
||||||
return Promise.resolve(this.prefersColorSchemeDark.matches ? ThemeType.Dark : ThemeType.Light);
|
|
||||||
}
|
|
||||||
|
|
||||||
onDefaultSystemThemeChange(callback: (theme: ThemeType.Light | ThemeType.Dark) => unknown) {
|
|
||||||
this.prefersColorSchemeDark.addEventListener("change", ({ matches }) => {
|
|
||||||
callback(matches ? ThemeType.Dark : ThemeType.Light);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async getEffectiveTheme() {
|
|
||||||
const theme = (await this.stateService.getTheme()) as ThemeType;
|
|
||||||
if (theme == null || theme === ThemeType.System) {
|
|
||||||
return this.getDefaultSystemTheme();
|
|
||||||
} else {
|
|
||||||
return theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { FormControl } from "@angular/forms";
|
||||||
import { debounceTime } from "rxjs/operators";
|
import { debounceTime } from "rxjs/operators";
|
||||||
|
|
||||||
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
import { ModalService } from "@bitwarden/angular/services/modal.service";
|
||||||
|
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
|
||||||
import { CryptoService } from "@bitwarden/common/abstractions/crypto.service";
|
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";
|
||||||
|
@ -74,7 +75,8 @@ export class SettingsComponent implements OnInit {
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private messagingService: MessagingService,
|
private messagingService: MessagingService,
|
||||||
private cryptoService: CryptoService,
|
private cryptoService: CryptoService,
|
||||||
private modalService: ModalService
|
private modalService: ModalService,
|
||||||
|
private themingService: AbstractThemingService
|
||||||
) {
|
) {
|
||||||
const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
|
const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
|
||||||
|
|
||||||
|
@ -342,8 +344,7 @@ export class SettingsComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveTheme() {
|
async saveTheme() {
|
||||||
await this.stateService.setTheme(this.theme);
|
await this.themingService.updateConfiguredTheme(this.theme);
|
||||||
window.setTimeout(() => window.location.reload(), 200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async saveMinOnCopyToClipboard() {
|
async saveMinOnCopyToClipboard() {
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { ipcRenderer } from "electron";
|
||||||
|
|
||||||
|
import { ThemingService } from "@bitwarden/angular/services/theming/theming.service";
|
||||||
|
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class DesktopThemingService extends ThemingService {
|
||||||
|
protected async getSystemTheme(): Promise<ThemeType> {
|
||||||
|
return await ipcRenderer.invoke("systemTheme");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected monitorSystemThemeChanges(): void {
|
||||||
|
ipcRenderer.on("systemThemeUpdated", (_event, theme: ThemeType) =>
|
||||||
|
this.updateSystemTheme(theme)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { Inject, Injectable } from "@angular/core";
|
import { Inject, Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { WINDOW } from "@bitwarden/angular/services/jslib-services.module";
|
import { WINDOW } from "@bitwarden/angular/services/jslib-services.module";
|
||||||
|
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
|
||||||
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/abstractions/crypto.service";
|
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/abstractions/crypto.service";
|
||||||
import { EnvironmentService as EnvironmentServiceAbstraction } from "@bitwarden/common/abstractions/environment.service";
|
import { EnvironmentService as EnvironmentServiceAbstraction } from "@bitwarden/common/abstractions/environment.service";
|
||||||
import { EventService as EventServiceAbstraction } from "@bitwarden/common/abstractions/event.service";
|
import { EventService as EventServiceAbstraction } from "@bitwarden/common/abstractions/event.service";
|
||||||
|
@ -11,7 +12,6 @@ import { StateService as StateServiceAbstraction } from "@bitwarden/common/abstr
|
||||||
import { SyncService as SyncServiceAbstraction } from "@bitwarden/common/abstractions/sync.service";
|
import { SyncService as SyncServiceAbstraction } from "@bitwarden/common/abstractions/sync.service";
|
||||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/abstractions/twoFactor.service";
|
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/abstractions/twoFactor.service";
|
||||||
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout.service";
|
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout.service";
|
||||||
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
|
||||||
import { ContainerService } from "@bitwarden/common/services/container.service";
|
import { ContainerService } from "@bitwarden/common/services/container.service";
|
||||||
import { EventService } from "@bitwarden/common/services/event.service";
|
import { EventService } from "@bitwarden/common/services/event.service";
|
||||||
import { VaultTimeoutService } from "@bitwarden/common/services/vaultTimeout.service";
|
import { VaultTimeoutService } from "@bitwarden/common/services/vaultTimeout.service";
|
||||||
|
@ -33,7 +33,8 @@ export class InitService {
|
||||||
private platformUtilsService: PlatformUtilsServiceAbstraction,
|
private platformUtilsService: PlatformUtilsServiceAbstraction,
|
||||||
private stateService: StateServiceAbstraction,
|
private stateService: StateServiceAbstraction,
|
||||||
private cryptoService: CryptoServiceAbstraction,
|
private cryptoService: CryptoServiceAbstraction,
|
||||||
private nativeMessagingService: NativeMessagingService
|
private nativeMessagingService: NativeMessagingService,
|
||||||
|
private themingService: AbstractThemingService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
@ -50,17 +51,7 @@ export class InitService {
|
||||||
setTimeout(() => this.notificationsService.init(), 3000);
|
setTimeout(() => this.notificationsService.init(), 3000);
|
||||||
const htmlEl = this.win.document.documentElement;
|
const htmlEl = this.win.document.documentElement;
|
||||||
htmlEl.classList.add("os_" + this.platformUtilsService.getDeviceString());
|
htmlEl.classList.add("os_" + this.platformUtilsService.getDeviceString());
|
||||||
|
await this.themingService.monitorThemeChanges();
|
||||||
const theme = await this.platformUtilsService.getEffectiveTheme();
|
|
||||||
htmlEl.classList.add("theme_" + theme);
|
|
||||||
this.platformUtilsService.onDefaultSystemThemeChange(async (sysTheme) => {
|
|
||||||
const bwTheme = await this.stateService.getTheme();
|
|
||||||
if (bwTheme == null || bwTheme === ThemeType.System) {
|
|
||||||
htmlEl.classList.remove("theme_" + ThemeType.Light, "theme_" + ThemeType.Dark);
|
|
||||||
htmlEl.classList.add("theme_" + sysTheme);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let installAction = null;
|
let installAction = null;
|
||||||
const installedVersion = await this.stateService.getInstalledVersion();
|
const installedVersion = await this.stateService.getInstalledVersion();
|
||||||
const currentVersion = await this.platformUtilsService.getApplicationVersion();
|
const currentVersion = await this.platformUtilsService.getApplicationVersion();
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
LOCALES_DIRECTORY,
|
LOCALES_DIRECTORY,
|
||||||
SYSTEM_LANGUAGE,
|
SYSTEM_LANGUAGE,
|
||||||
} from "@bitwarden/angular/services/jslib-services.module";
|
} from "@bitwarden/angular/services/jslib-services.module";
|
||||||
|
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
|
||||||
import { BroadcasterService as BroadcasterServiceAbstraction } from "@bitwarden/common/abstractions/broadcaster.service";
|
import { BroadcasterService as BroadcasterServiceAbstraction } from "@bitwarden/common/abstractions/broadcaster.service";
|
||||||
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/abstractions/crypto.service";
|
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/abstractions/crypto.service";
|
||||||
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/abstractions/cryptoFunction.service";
|
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/abstractions/cryptoFunction.service";
|
||||||
|
@ -43,6 +44,7 @@ import { StateService } from "../../services/state.service";
|
||||||
import { LoginGuard } from "../guards/login.guard";
|
import { LoginGuard } from "../guards/login.guard";
|
||||||
import { SearchBarService } from "../layout/search/search-bar.service";
|
import { SearchBarService } from "../layout/search/search-bar.service";
|
||||||
|
|
||||||
|
import { DesktopThemingService } from "./desktop-theming.service";
|
||||||
import { InitService } from "./init.service";
|
import { InitService } from "./init.service";
|
||||||
|
|
||||||
const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
|
const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
|
||||||
|
@ -129,6 +131,10 @@ const RELOAD_CALLBACK = new InjectionToken<() => any>("RELOAD_CALLBACK");
|
||||||
STATE_SERVICE_USE_CACHE,
|
STATE_SERVICE_USE_CACHE,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: AbstractThemingService,
|
||||||
|
useClass: DesktopThemingService,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ServicesModule {}
|
export class ServicesModule {}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { DragDropModule } from "@angular/cdk/drag-drop";
|
import { DragDropModule } from "@angular/cdk/drag-drop";
|
||||||
|
import { LayoutModule } from "@angular/cdk/layout";
|
||||||
import { NgModule } from "@angular/core";
|
import { NgModule } from "@angular/core";
|
||||||
import { FormsModule } from "@angular/forms";
|
import { FormsModule } from "@angular/forms";
|
||||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
|
@ -18,6 +19,7 @@ import { WildcardRoutingModule } from "./wildcard-routing.module";
|
||||||
ServicesModule,
|
ServicesModule,
|
||||||
InfiniteScrollModule,
|
InfiniteScrollModule,
|
||||||
DragDropModule,
|
DragDropModule,
|
||||||
|
LayoutModule,
|
||||||
OssRoutingModule,
|
OssRoutingModule,
|
||||||
WildcardRoutingModule, // Needs to be last to catch all non-existing routes
|
WildcardRoutingModule, // Needs to be last to catch all non-existing routes
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Inject, Injectable } from "@angular/core";
|
import { Inject, Injectable } from "@angular/core";
|
||||||
|
|
||||||
import { WINDOW } from "@bitwarden/angular/services/jslib-services.module";
|
import { WINDOW } from "@bitwarden/angular/services/jslib-services.module";
|
||||||
|
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
|
||||||
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/abstractions/crypto.service";
|
import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/abstractions/crypto.service";
|
||||||
import {
|
import {
|
||||||
EnvironmentService as EnvironmentServiceAbstraction,
|
EnvironmentService as EnvironmentServiceAbstraction,
|
||||||
|
@ -9,11 +10,9 @@ import {
|
||||||
import { EventService as EventLoggingServiceAbstraction } from "@bitwarden/common/abstractions/event.service";
|
import { EventService as EventLoggingServiceAbstraction } from "@bitwarden/common/abstractions/event.service";
|
||||||
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/abstractions/i18n.service";
|
import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
import { NotificationsService as NotificationsServiceAbstraction } from "@bitwarden/common/abstractions/notifications.service";
|
import { NotificationsService as NotificationsServiceAbstraction } from "@bitwarden/common/abstractions/notifications.service";
|
||||||
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwarden/common/abstractions/platformUtils.service";
|
|
||||||
import { StateService as StateServiceAbstraction } from "@bitwarden/common/abstractions/state.service";
|
import { StateService as StateServiceAbstraction } from "@bitwarden/common/abstractions/state.service";
|
||||||
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/abstractions/twoFactor.service";
|
import { TwoFactorService as TwoFactorServiceAbstraction } from "@bitwarden/common/abstractions/twoFactor.service";
|
||||||
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout.service";
|
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@bitwarden/common/abstractions/vaultTimeout.service";
|
||||||
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
|
||||||
import { ContainerService } from "@bitwarden/common/services/container.service";
|
import { ContainerService } from "@bitwarden/common/services/container.service";
|
||||||
import { EventService as EventLoggingService } from "@bitwarden/common/services/event.service";
|
import { EventService as EventLoggingService } from "@bitwarden/common/services/event.service";
|
||||||
import { VaultTimeoutService as VaultTimeoutService } from "@bitwarden/common/services/vaultTimeout.service";
|
import { VaultTimeoutService as VaultTimeoutService } from "@bitwarden/common/services/vaultTimeout.service";
|
||||||
|
@ -31,8 +30,8 @@ export class InitService {
|
||||||
private eventLoggingService: EventLoggingServiceAbstraction,
|
private eventLoggingService: EventLoggingServiceAbstraction,
|
||||||
private twoFactorService: TwoFactorServiceAbstraction,
|
private twoFactorService: TwoFactorServiceAbstraction,
|
||||||
private stateService: StateServiceAbstraction,
|
private stateService: StateServiceAbstraction,
|
||||||
private platformUtilsService: PlatformUtilsServiceAbstraction,
|
private cryptoService: CryptoServiceAbstraction,
|
||||||
private cryptoService: CryptoServiceAbstraction
|
private themingService: AbstractThemingService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
@ -44,7 +43,6 @@ export class InitService {
|
||||||
this.environmentService.setUrls(urls);
|
this.environmentService.setUrls(urls);
|
||||||
|
|
||||||
setTimeout(() => this.notificationsService.init(), 3000);
|
setTimeout(() => this.notificationsService.init(), 3000);
|
||||||
|
|
||||||
(this.vaultTimeoutService as VaultTimeoutService).init(true);
|
(this.vaultTimeoutService as VaultTimeoutService).init(true);
|
||||||
const locale = await this.stateService.getLocale();
|
const locale = await this.stateService.getLocale();
|
||||||
await (this.i18nService as I18nService).init(locale);
|
await (this.i18nService as I18nService).init(locale);
|
||||||
|
@ -52,16 +50,7 @@ export class InitService {
|
||||||
this.twoFactorService.init();
|
this.twoFactorService.init();
|
||||||
const htmlEl = this.win.document.documentElement;
|
const htmlEl = this.win.document.documentElement;
|
||||||
htmlEl.classList.add("locale_" + this.i18nService.translationLocale);
|
htmlEl.classList.add("locale_" + this.i18nService.translationLocale);
|
||||||
|
await this.themingService.monitorThemeChanges();
|
||||||
// Initial theme is set in index.html which must be updated if there are any changes to theming logic
|
|
||||||
this.platformUtilsService.onDefaultSystemThemeChange(async (sysTheme) => {
|
|
||||||
const bwTheme = await this.stateService.getTheme();
|
|
||||||
if (bwTheme === ThemeType.System) {
|
|
||||||
htmlEl.classList.remove("theme_" + ThemeType.Light, "theme_" + ThemeType.Dark);
|
|
||||||
htmlEl.classList.add("theme_" + sysTheme);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const containerService = new ContainerService(this.cryptoService);
|
const containerService = new ContainerService(this.cryptoService);
|
||||||
containerService.attachToWindow(this.win);
|
containerService.attachToWindow(this.win);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { Component, Input, OnInit } from "@angular/core";
|
import { Component, Input, OnDestroy, OnInit } from "@angular/core";
|
||||||
|
import { Subject, takeUntil } from "rxjs";
|
||||||
|
|
||||||
|
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
|
||||||
import { PaymentMethodType } from "@bitwarden/common/enums/paymentMethodType";
|
import { PaymentMethodType } from "@bitwarden/common/enums/paymentMethodType";
|
||||||
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ const darkInputPlaceholderColor = ThemeVariables.darkInputPlaceholderColor;
|
||||||
selector: "app-payment",
|
selector: "app-payment",
|
||||||
templateUrl: "payment.component.html",
|
templateUrl: "payment.component.html",
|
||||||
})
|
})
|
||||||
export class PaymentComponent implements OnInit {
|
export class PaymentComponent implements OnInit, OnDestroy {
|
||||||
@Input() showMethods = true;
|
@Input() showMethods = true;
|
||||||
@Input() showOptions = true;
|
@Input() showOptions = true;
|
||||||
@Input() method = PaymentMethodType.Card;
|
@Input() method = PaymentMethodType.Card;
|
||||||
|
@ -25,6 +26,8 @@ export class PaymentComponent implements OnInit {
|
||||||
@Input() hidePaypal = false;
|
@Input() hidePaypal = false;
|
||||||
@Input() hideCredit = false;
|
@Input() hideCredit = false;
|
||||||
|
|
||||||
|
private destroy$: Subject<void> = new Subject<void>();
|
||||||
|
|
||||||
bank: any = {
|
bank: any = {
|
||||||
routing_number: null,
|
routing_number: null,
|
||||||
account_number: null,
|
account_number: null,
|
||||||
|
@ -48,9 +51,9 @@ export class PaymentComponent implements OnInit {
|
||||||
private StripeElementClasses: any;
|
private StripeElementClasses: any;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private platformUtilsService: PlatformUtilsService,
|
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private logService: LogService
|
private logService: LogService,
|
||||||
|
private themingService: AbstractThemingService
|
||||||
) {
|
) {
|
||||||
this.stripeScript = window.document.createElement("script");
|
this.stripeScript = window.document.createElement("script");
|
||||||
this.stripeScript.src = "https://js.stripe.com/v3/";
|
this.stripeScript.src = "https://js.stripe.com/v3/";
|
||||||
|
@ -100,6 +103,8 @@ export class PaymentComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
|
this.destroy$.next();
|
||||||
|
this.destroy$.complete();
|
||||||
window.document.head.removeChild(this.stripeScript);
|
window.document.head.removeChild(this.stripeScript);
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
Array.from(window.document.querySelectorAll("iframe")).forEach((el) => {
|
Array.from(window.document.querySelectorAll("iframe")).forEach((el) => {
|
||||||
|
@ -275,8 +280,8 @@ export class PaymentComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setTheme() {
|
private async setTheme() {
|
||||||
const theme = await this.platformUtilsService.getEffectiveTheme();
|
this.themingService.theme$.pipe(takeUntil(this.destroy$)).subscribe((theme) => {
|
||||||
if (theme === ThemeType.Dark) {
|
if (theme.effectiveTheme === ThemeType.Dark) {
|
||||||
this.StripeElementStyle.base.color = darkInputColor;
|
this.StripeElementStyle.base.color = darkInputColor;
|
||||||
this.StripeElementStyle.base["::placeholder"].color = darkInputPlaceholderColor;
|
this.StripeElementStyle.base["::placeholder"].color = darkInputPlaceholderColor;
|
||||||
this.StripeElementStyle.invalid.color = darkInputColor;
|
this.StripeElementStyle.invalid.color = darkInputColor;
|
||||||
|
@ -285,5 +290,6 @@ export class PaymentComponent implements OnInit {
|
||||||
this.StripeElementStyle.base["::placeholder"].color = lightInputPlaceholderColor;
|
this.StripeElementStyle.base["::placeholder"].color = lightInputPlaceholderColor;
|
||||||
this.StripeElementStyle.invalid.color = lightInputColor;
|
this.StripeElementStyle.invalid.color = lightInputColor;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { FormControl } from "@angular/forms";
|
import { FormControl } from "@angular/forms";
|
||||||
|
|
||||||
|
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 { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||||
|
@ -34,7 +35,8 @@ export class PreferencesComponent implements OnInit {
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private vaultTimeoutService: VaultTimeoutService,
|
private vaultTimeoutService: VaultTimeoutService,
|
||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private messagingService: MessagingService
|
private messagingService: MessagingService,
|
||||||
|
private themingService: AbstractThemingService
|
||||||
) {
|
) {
|
||||||
this.vaultTimeouts = [
|
this.vaultTimeouts = [
|
||||||
{ name: i18nService.t("oneMinute"), value: 1 },
|
{ name: i18nService.t("oneMinute"), value: 1 },
|
||||||
|
@ -100,12 +102,8 @@ export class PreferencesComponent implements OnInit {
|
||||||
await this.stateService.setEnableFullWidth(this.enableFullWidth);
|
await this.stateService.setEnableFullWidth(this.enableFullWidth);
|
||||||
this.messagingService.send("setFullWidth");
|
this.messagingService.send("setFullWidth");
|
||||||
if (this.theme !== this.startingTheme) {
|
if (this.theme !== this.startingTheme) {
|
||||||
await this.stateService.setTheme(this.theme);
|
await this.themingService.updateConfiguredTheme(this.theme);
|
||||||
this.startingTheme = this.theme;
|
this.startingTheme = this.theme;
|
||||||
const effectiveTheme = await this.platformUtilsService.getEffectiveTheme();
|
|
||||||
const htmlEl = window.document.documentElement;
|
|
||||||
htmlEl.classList.remove("theme_" + ThemeType.Light, "theme_" + ThemeType.Dark);
|
|
||||||
htmlEl.classList.add("theme_" + effectiveTheme);
|
|
||||||
}
|
}
|
||||||
await this.stateService.setLocale(this.locale);
|
await this.stateService.setLocale(this.locale);
|
||||||
if (this.locale !== this.startingLocale) {
|
if (this.locale !== this.startingLocale) {
|
||||||
|
|
|
@ -5,21 +5,17 @@ import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
|
||||||
import { LogService } from "@bitwarden/common/abstractions/log.service";
|
import { LogService } from "@bitwarden/common/abstractions/log.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 { StateService } from "@bitwarden/common/abstractions/state.service";
|
|
||||||
import { ClientType } from "@bitwarden/common/enums/clientType";
|
import { ClientType } from "@bitwarden/common/enums/clientType";
|
||||||
import { DeviceType } from "@bitwarden/common/enums/deviceType";
|
import { DeviceType } from "@bitwarden/common/enums/deviceType";
|
||||||
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WebPlatformUtilsService implements PlatformUtilsService {
|
export class WebPlatformUtilsService implements PlatformUtilsService {
|
||||||
private browserCache: DeviceType = null;
|
private browserCache: DeviceType = null;
|
||||||
private prefersColorSchemeDark = window.matchMedia("(prefers-color-scheme: dark)");
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private messagingService: MessagingService,
|
private messagingService: MessagingService,
|
||||||
private logService: LogService,
|
private logService: LogService
|
||||||
private stateService: StateService
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
getDevice(): DeviceType {
|
getDevice(): DeviceType {
|
||||||
|
@ -303,32 +299,4 @@ export class WebPlatformUtilsService implements PlatformUtilsService {
|
||||||
supportsSecureStorage() {
|
supportsSecureStorage() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultSystemTheme(): Promise<ThemeType.Light | ThemeType.Dark> {
|
|
||||||
return Promise.resolve(this.prefersColorSchemeDark.matches ? ThemeType.Dark : ThemeType.Light);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getEffectiveTheme(): Promise<ThemeType.Light | ThemeType.Dark> {
|
|
||||||
const theme = await this.stateService.getTheme();
|
|
||||||
if (theme === ThemeType.Dark) {
|
|
||||||
return ThemeType.Dark;
|
|
||||||
} else if (theme === ThemeType.System) {
|
|
||||||
return this.getDefaultSystemTheme();
|
|
||||||
} else {
|
|
||||||
return ThemeType.Light;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onDefaultSystemThemeChange(callback: (theme: ThemeType.Light | ThemeType.Dark) => unknown) {
|
|
||||||
try {
|
|
||||||
this.prefersColorSchemeDark.addEventListener("change", ({ matches }) => {
|
|
||||||
callback(matches ? ThemeType.Dark : ThemeType.Light);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
// Safari older than v14
|
|
||||||
this.prefersColorSchemeDark.addListener((ev) => {
|
|
||||||
callback(ev.matches ? ThemeType.Dark : ThemeType.Light);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { InjectionToken, Injector, LOCALE_ID, NgModule } from "@angular/core";
|
import { InjectionToken, Injector, LOCALE_ID, NgModule } from "@angular/core";
|
||||||
|
|
||||||
|
import { ThemingService } from "@bitwarden/angular/services/theming/theming.service";
|
||||||
|
import { AbstractThemingService } from "@bitwarden/angular/services/theming/theming.service.abstraction";
|
||||||
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/abstractions/appId.service";
|
import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/abstractions/appId.service";
|
||||||
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
|
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
|
||||||
|
@ -423,6 +425,10 @@ export const SYSTEM_LANGUAGE = new InjectionToken<string>("SYSTEM_LANGUAGE");
|
||||||
useClass: TwoFactorService,
|
useClass: TwoFactorService,
|
||||||
deps: [I18nServiceAbstraction, PlatformUtilsServiceAbstraction],
|
deps: [I18nServiceAbstraction, PlatformUtilsServiceAbstraction],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: AbstractThemingService,
|
||||||
|
useClass: ThemingService,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class JslibServicesModule {}
|
export class JslibServicesModule {}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
||||||
|
|
||||||
|
export interface Theme {
|
||||||
|
configuredTheme: ThemeType;
|
||||||
|
effectiveTheme: ThemeType;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
||||||
|
|
||||||
|
import { Theme } from "./theme";
|
||||||
|
|
||||||
|
export class ThemeBuilder implements Theme {
|
||||||
|
get effectiveTheme(): ThemeType {
|
||||||
|
return this.configuredTheme != ThemeType.System ? this.configuredTheme : this.systemTheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(readonly configuredTheme: ThemeType, readonly systemTheme: ThemeType) {}
|
||||||
|
|
||||||
|
updateSystemTheme(systemTheme: ThemeType): ThemeBuilder {
|
||||||
|
return new ThemeBuilder(this.configuredTheme, systemTheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateConfiguredTheme(configuredTheme: ThemeType): ThemeBuilder {
|
||||||
|
return new ThemeBuilder(configuredTheme, this.systemTheme);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
|
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
||||||
|
|
||||||
|
import { Theme } from "./theme";
|
||||||
|
|
||||||
|
export abstract class AbstractThemingService {
|
||||||
|
theme$: Observable<Theme>;
|
||||||
|
monitorThemeChanges: () => Promise<void>;
|
||||||
|
updateSystemTheme: (systemTheme: ThemeType) => void;
|
||||||
|
updateConfiguredTheme: (theme: ThemeType) => Promise<void>;
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { MediaMatcher } from "@angular/cdk/layout";
|
||||||
|
import { DOCUMENT } from "@angular/common";
|
||||||
|
import { Inject, Injectable } from "@angular/core";
|
||||||
|
import { BehaviorSubject, filter, fromEvent, Observable } from "rxjs";
|
||||||
|
|
||||||
|
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||||
|
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
||||||
|
|
||||||
|
import { Theme } from "./theme";
|
||||||
|
import { ThemeBuilder } from "./themeBuilder";
|
||||||
|
import { AbstractThemingService } from "./theming.service.abstraction";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ThemingService implements AbstractThemingService {
|
||||||
|
private _theme = new BehaviorSubject<ThemeBuilder | null>(null);
|
||||||
|
theme$: Observable<Theme> = this._theme.pipe(filter((x) => x !== null));
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private stateService: StateService,
|
||||||
|
private mediaMatcher: MediaMatcher,
|
||||||
|
@Inject(DOCUMENT) private document: Document
|
||||||
|
) {
|
||||||
|
this.monitorThemeChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
async monitorThemeChanges(): Promise<void> {
|
||||||
|
this._theme.next(
|
||||||
|
new ThemeBuilder(await this.stateService.getTheme(), await this.getSystemTheme())
|
||||||
|
);
|
||||||
|
this.monitorConfiguredThemeChanges();
|
||||||
|
this.monitorSystemThemeChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateSystemTheme(systemTheme: ThemeType): void {
|
||||||
|
this._theme.next(this._theme.getValue().updateSystemTheme(systemTheme));
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateConfiguredTheme(theme: ThemeType): Promise<void> {
|
||||||
|
await this.stateService.setTheme(theme);
|
||||||
|
this._theme.next(this._theme.getValue().updateConfiguredTheme(theme));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected monitorConfiguredThemeChanges(): void {
|
||||||
|
this.theme$.subscribe((theme: Theme) => {
|
||||||
|
this.document.documentElement.classList.remove(
|
||||||
|
"theme_" + ThemeType.Light,
|
||||||
|
"theme_" + ThemeType.Dark,
|
||||||
|
"theme_" + ThemeType.Nord,
|
||||||
|
"theme_" + ThemeType.SolarizedDark
|
||||||
|
);
|
||||||
|
this.document.documentElement.classList.add("theme_" + theme.effectiveTheme);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// We use a media match query for monitoring the system theme on web and browser, but this doesn't work for electron apps on Linux.
|
||||||
|
// In desktop we override these methods to track systemTheme with the electron renderer instead, which works for all OSs.
|
||||||
|
protected async getSystemTheme(): Promise<ThemeType> {
|
||||||
|
return this.mediaMatcher.matchMedia("(prefers-color-scheme: dark)").matches
|
||||||
|
? ThemeType.Dark
|
||||||
|
: ThemeType.Light;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected monitorSystemThemeChanges(): void {
|
||||||
|
fromEvent<MediaQueryListEvent>(
|
||||||
|
this.mediaMatcher.matchMedia("(prefers-color-scheme: dark)"),
|
||||||
|
"change"
|
||||||
|
).subscribe((event) => {
|
||||||
|
this.updateSystemTheme(event.matches ? ThemeType.Dark : ThemeType.Light);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
import { ClientType } from "../enums/clientType";
|
import { ClientType } from "../enums/clientType";
|
||||||
import { DeviceType } from "../enums/deviceType";
|
import { DeviceType } from "../enums/deviceType";
|
||||||
import { ThemeType } from "../enums/themeType";
|
|
||||||
|
|
||||||
interface ToastOptions {
|
interface ToastOptions {
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
|
@ -43,10 +42,5 @@ export abstract class PlatformUtilsService {
|
||||||
readFromClipboard: (options?: any) => Promise<string>;
|
readFromClipboard: (options?: any) => Promise<string>;
|
||||||
supportsBiometric: () => Promise<boolean>;
|
supportsBiometric: () => Promise<boolean>;
|
||||||
authenticateBiometric: () => Promise<boolean>;
|
authenticateBiometric: () => Promise<boolean>;
|
||||||
getDefaultSystemTheme: () => Promise<ThemeType.Light | ThemeType.Dark>;
|
|
||||||
onDefaultSystemThemeChange: (
|
|
||||||
callback: (theme: ThemeType.Light | ThemeType.Dark) => unknown
|
|
||||||
) => unknown;
|
|
||||||
getEffectiveTheme: () => Promise<ThemeType>;
|
|
||||||
supportsSecureStorage: () => boolean;
|
supportsSecureStorage: () => boolean;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUti
|
||||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||||
import { ClientType } from "@bitwarden/common/enums/clientType";
|
import { ClientType } from "@bitwarden/common/enums/clientType";
|
||||||
import { DeviceType } from "@bitwarden/common/enums/deviceType";
|
import { DeviceType } from "@bitwarden/common/enums/deviceType";
|
||||||
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
|
||||||
|
|
||||||
import { isDev, isMacAppStore } from "../utils";
|
import { isDev, isMacAppStore } from "../utils";
|
||||||
|
|
||||||
|
@ -189,25 +188,6 @@ export class ElectronPlatformUtilsService implements PlatformUtilsService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultSystemTheme() {
|
|
||||||
return ipcRenderer.invoke("systemTheme");
|
|
||||||
}
|
|
||||||
|
|
||||||
onDefaultSystemThemeChange(callback: (theme: ThemeType.Light | ThemeType.Dark) => unknown) {
|
|
||||||
ipcRenderer.on("systemThemeUpdated", (event, theme: ThemeType.Light | ThemeType.Dark) =>
|
|
||||||
callback(theme)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getEffectiveTheme() {
|
|
||||||
const theme = await this.stateService.getTheme();
|
|
||||||
if (theme == null || theme === ThemeType.System) {
|
|
||||||
return this.getDefaultSystemTheme();
|
|
||||||
} else {
|
|
||||||
return theme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
supportsSecureStorage(): boolean {
|
supportsSecureStorage(): boolean {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ import * as child_process from "child_process";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
|
||||||
import { ClientType } from "@bitwarden/common/enums/clientType";
|
import { ClientType } from "@bitwarden/common/enums/clientType";
|
||||||
import { DeviceType } from "@bitwarden/common/enums/deviceType";
|
import { DeviceType } from "@bitwarden/common/enums/deviceType";
|
||||||
import { ThemeType } from "@bitwarden/common/enums/themeType";
|
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
const open = require("open");
|
const open = require("open");
|
||||||
|
@ -148,18 +147,6 @@ export class CliPlatformUtilsService implements PlatformUtilsService {
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultSystemTheme() {
|
|
||||||
return Promise.resolve(ThemeType.Light as ThemeType.Light | ThemeType.Dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
onDefaultSystemThemeChange() {
|
|
||||||
/* noop */
|
|
||||||
}
|
|
||||||
|
|
||||||
getEffectiveTheme() {
|
|
||||||
return Promise.resolve(ThemeType.Light);
|
|
||||||
}
|
|
||||||
|
|
||||||
supportsSecureStorage(): boolean {
|
supportsSecureStorage(): boolean {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue