1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-21 11:35:34 +01:00

[PM-14351] Migrate away from theme enum (#11812)

* update extension autofill concerns to use theme object and type over enum

* mark ThemeType enum as deprecated

* update theming service concerns to use theme object and type over enum
This commit is contained in:
Jonathan Prusik 2024-10-31 16:46:25 -04:00 committed by GitHub
parent eb67b73a09
commit eba1212e1c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 56 additions and 39 deletions

View File

@ -1,5 +1,5 @@
import { EVENTS } from "@bitwarden/common/autofill/constants"; import { EVENTS } from "@bitwarden/common/autofill/constants";
import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeTypes } from "@bitwarden/common/platform/enums";
import { setElementStyles } from "../../../utils"; import { setElementStyles } from "../../../utils";
import { import {
@ -210,19 +210,19 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
const { theme } = message; const { theme } = message;
let borderColor: string; let borderColor: string;
let verifiedTheme = theme; let verifiedTheme = theme;
if (verifiedTheme === ThemeType.System) { if (verifiedTheme === ThemeTypes.System) {
verifiedTheme = globalThis.matchMedia("(prefers-color-scheme: dark)").matches verifiedTheme = globalThis.matchMedia("(prefers-color-scheme: dark)").matches
? ThemeType.Dark ? ThemeTypes.Dark
: ThemeType.Light; : ThemeTypes.Light;
} }
if (verifiedTheme === ThemeType.Dark) { if (verifiedTheme === ThemeTypes.Dark) {
borderColor = "#4c525f"; borderColor = "#4c525f";
} }
if (theme === ThemeType.Nord) { if (theme === ThemeTypes.Nord) {
borderColor = "#2E3440"; borderColor = "#2E3440";
} }
if (theme === ThemeType.SolarizedDark) { if (theme === ThemeTypes.SolarizedDark) {
borderColor = "#073642"; borderColor = "#073642";
} }
if (borderColor) { if (borderColor) {

View File

@ -1,7 +1,9 @@
import { Theme } from "@bitwarden/common/platform/enums";
type NotificationBarIframeInitData = { type NotificationBarIframeInitData = {
type?: string; type?: string;
isVaultLocked?: boolean; isVaultLocked?: boolean;
theme?: string; theme?: Theme;
removeIndividualVault?: boolean; removeIndividualVault?: boolean;
importType?: string; importType?: string;
applyRedesign?: boolean; applyRedesign?: boolean;

View File

@ -1,4 +1,4 @@
import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeTypes } from "@bitwarden/common/platform/enums";
import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service"; import { ConsoleLogService } from "@bitwarden/common/platform/services/console-log.service";
import type { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import type { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
@ -392,10 +392,10 @@ function setupLogoLink(i18n: Record<string, string>) {
function setNotificationBarTheme() { function setNotificationBarTheme() {
let theme = notificationBarIframeInitData.theme; let theme = notificationBarIframeInitData.theme;
if (theme === ThemeType.System) { if (theme === ThemeTypes.System) {
theme = globalThis.matchMedia("(prefers-color-scheme: dark)").matches theme = globalThis.matchMedia("(prefers-color-scheme: dark)").matches
? ThemeType.Dark ? ThemeTypes.Dark
: ThemeType.Light; : ThemeTypes.Light;
} }
document.documentElement.classList.add(`theme_${theme}`); document.documentElement.classList.add(`theme_${theme}`);

View File

@ -1,5 +1,5 @@
import { EVENTS } from "@bitwarden/common/autofill/constants"; import { EVENTS } from "@bitwarden/common/autofill/constants";
import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeTypes } from "@bitwarden/common/platform/enums";
import { sendExtensionMessage, setElementStyles } from "../../../utils"; import { sendExtensionMessage, setElementStyles } from "../../../utils";
import { import {
@ -239,19 +239,19 @@ export class AutofillInlineMenuIframeService implements AutofillInlineMenuIframe
const { theme } = message; const { theme } = message;
let borderColor: string; let borderColor: string;
let verifiedTheme = theme; let verifiedTheme = theme;
if (verifiedTheme === ThemeType.System) { if (verifiedTheme === ThemeTypes.System) {
verifiedTheme = globalThis.matchMedia("(prefers-color-scheme: dark)").matches verifiedTheme = globalThis.matchMedia("(prefers-color-scheme: dark)").matches
? ThemeType.Dark ? ThemeTypes.Dark
: ThemeType.Light; : ThemeTypes.Light;
} }
if (verifiedTheme === ThemeType.Dark) { if (verifiedTheme === ThemeTypes.Dark) {
borderColor = "#4c525f"; borderColor = "#4c525f";
} }
if (theme === ThemeType.Nord) { if (theme === ThemeTypes.Nord) {
borderColor = "#2E3440"; borderColor = "#2E3440";
} }
if (theme === ThemeType.SolarizedDark) { if (theme === ThemeTypes.SolarizedDark) {
borderColor = "#073642"; borderColor = "#073642";
} }
if (borderColor) { if (borderColor) {

View File

@ -1,6 +1,8 @@
import { Theme } from "@bitwarden/common/platform/enums";
export type NotificationTypeData = { export type NotificationTypeData = {
isVaultLocked?: boolean; isVaultLocked?: boolean;
theme?: string; theme?: Theme;
removeIndividualVault?: boolean; removeIndividualVault?: boolean;
importType?: string; importType?: string;
launchTimestamp?: number; launchTimestamp?: number;

View File

@ -2,7 +2,7 @@ import { mock } from "jest-mock-extended";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
import { UriMatchStrategy } from "@bitwarden/common/models/domain/domain-service"; import { UriMatchStrategy } from "@bitwarden/common/models/domain/domain-service";
import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeTypes } from "@bitwarden/common/platform/enums";
import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherType } from "@bitwarden/common/vault/enums";
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
@ -210,7 +210,7 @@ export function createInitAutofillInlineMenuListMessageMock(
command: "initAutofillInlineMenuList", command: "initAutofillInlineMenuList",
translations: overlayPagesTranslations, translations: overlayPagesTranslations,
styleSheetUrl: "https://jest-testing-website.com", styleSheetUrl: "https://jest-testing-website.com",
theme: ThemeType.Light, theme: ThemeTypes.Light,
authStatus: AuthenticationStatus.Unlocked, authStatus: AuthenticationStatus.Unlocked,
portKey: "portKey", portKey: "portKey",
inlineMenuFillType: CipherType.Login, inlineMenuFillType: CipherType.Login,

View File

@ -1,7 +1,7 @@
import { Inject, Injectable } from "@angular/core"; import { Inject, Injectable } from "@angular/core";
import { fromEvent, map, merge, Observable, of, Subscription, switchMap } from "rxjs"; import { fromEvent, map, merge, Observable, of, Subscription, switchMap } from "rxjs";
import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeTypes, Theme } from "@bitwarden/common/platform/enums";
import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
import { SYSTEM_THEME_OBSERVABLE } from "../../../services/injection-tokens"; import { SYSTEM_THEME_OBSERVABLE } from "../../../services/injection-tokens";
@ -15,7 +15,7 @@ export class AngularThemingService implements AbstractThemingService {
* @param window The window that should be watched for system theme changes. * @param window The window that should be watched for system theme changes.
* @returns An observable that will track the system theme. * @returns An observable that will track the system theme.
*/ */
static createSystemThemeFromWindow(window: Window): Observable<ThemeType> { static createSystemThemeFromWindow(window: Window): Observable<Theme> {
return merge( return merge(
// This observable should always emit at least once, so go and get the current system theme designation // This observable should always emit at least once, so go and get the current system theme designation
of(AngularThemingService.getSystemThemeFromWindow(window)), of(AngularThemingService.getSystemThemeFromWindow(window)),
@ -23,7 +23,7 @@ export class AngularThemingService implements AbstractThemingService {
fromEvent<MediaQueryListEvent>( fromEvent<MediaQueryListEvent>(
window.matchMedia("(prefers-color-scheme: dark)"), window.matchMedia("(prefers-color-scheme: dark)"),
"change", "change",
).pipe(map((event) => (event.matches ? ThemeType.Dark : ThemeType.Light))), ).pipe(map((event) => (event.matches ? ThemeTypes.Dark : ThemeTypes.Light))),
); );
} }
@ -32,15 +32,15 @@ export class AngularThemingService implements AbstractThemingService {
* @param window The window to query for the current theme. * @param window The window to query for the current theme.
* @returns The active system theme. * @returns The active system theme.
*/ */
static getSystemThemeFromWindow(window: Window): ThemeType { static getSystemThemeFromWindow(window: Window): Theme {
return window.matchMedia("(prefers-color-scheme: dark)").matches return window.matchMedia("(prefers-color-scheme: dark)").matches
? ThemeType.Dark ? ThemeTypes.Dark
: ThemeType.Light; : ThemeTypes.Light;
} }
readonly theme$ = this.themeStateService.selectedTheme$.pipe( readonly theme$ = this.themeStateService.selectedTheme$.pipe(
switchMap((configuredTheme) => { switchMap((configuredTheme) => {
if (configuredTheme === ThemeType.System) { if (configuredTheme === ThemeTypes.System) {
return this.systemTheme$; return this.systemTheme$;
} }
@ -51,16 +51,16 @@ export class AngularThemingService implements AbstractThemingService {
constructor( constructor(
private themeStateService: ThemeStateService, private themeStateService: ThemeStateService,
@Inject(SYSTEM_THEME_OBSERVABLE) @Inject(SYSTEM_THEME_OBSERVABLE)
private systemTheme$: Observable<ThemeType>, private systemTheme$: Observable<Theme>,
) {} ) {}
applyThemeChangesTo(document: Document): Subscription { applyThemeChangesTo(document: Document): Subscription {
return this.theme$.subscribe((theme) => { return this.theme$.subscribe((theme) => {
document.documentElement.classList.remove( document.documentElement.classList.remove(
"theme_" + ThemeType.Light, "theme_" + ThemeTypes.Light,
"theme_" + ThemeType.Dark, "theme_" + ThemeTypes.Dark,
"theme_" + ThemeType.Nord, "theme_" + ThemeTypes.Nord,
"theme_" + ThemeType.SolarizedDark, "theme_" + ThemeTypes.SolarizedDark,
); );
document.documentElement.classList.add("theme_" + theme); document.documentElement.classList.add("theme_" + theme);
}); });

View File

@ -1,6 +1,6 @@
import { Observable, Subscription } from "rxjs"; import { Observable, Subscription } from "rxjs";
import { ThemeType } from "@bitwarden/common/platform/enums"; import { Theme } from "@bitwarden/common/platform/enums";
/** /**
* A service for managing and observing the current application theme. * A service for managing and observing the current application theme.
@ -9,9 +9,9 @@ import { ThemeType } from "@bitwarden/common/platform/enums";
export abstract class AbstractThemingService { export abstract class AbstractThemingService {
/** /**
* The effective theme based on the user configured choice and the current system theme if * The effective theme based on the user configured choice and the current system theme if
* the configured choice is {@link ThemeType.System}. * the configured choice is {@link ThemeTypes.System}.
*/ */
abstract theme$: Observable<ThemeType>; abstract theme$: Observable<Theme>;
/** /**
* Listens for effective theme changes and applies changes to the provided document. * Listens for effective theme changes and applies changes to the provided document.
* @param document The document that should have theme classes applied to it. * @param document The document that should have theme classes applied to it.

View File

@ -8,7 +8,7 @@ import {
AbstractStorageService, AbstractStorageService,
ObservableStorageService, ObservableStorageService,
} from "@bitwarden/common/platform/abstractions/storage.service"; } from "@bitwarden/common/platform/abstractions/storage.service";
import { ThemeType } from "@bitwarden/common/platform/enums"; import { Theme } from "@bitwarden/common/platform/enums";
import { StateFactory } from "@bitwarden/common/platform/factories/state-factory"; import { StateFactory } from "@bitwarden/common/platform/factories/state-factory";
import { Message } from "@bitwarden/common/platform/messaging"; import { Message } from "@bitwarden/common/platform/messaging";
import { VaultTimeout } from "@bitwarden/common/types/vault-timeout.type"; import { VaultTimeout } from "@bitwarden/common/types/vault-timeout.type";
@ -47,7 +47,7 @@ export const SUPPORTS_SECURE_STORAGE = new SafeInjectionToken<boolean>("SUPPORTS
export const LOCALES_DIRECTORY = new SafeInjectionToken<string>("LOCALES_DIRECTORY"); export const LOCALES_DIRECTORY = new SafeInjectionToken<string>("LOCALES_DIRECTORY");
export const SYSTEM_LANGUAGE = new SafeInjectionToken<string>("SYSTEM_LANGUAGE"); export const SYSTEM_LANGUAGE = new SafeInjectionToken<string>("SYSTEM_LANGUAGE");
export const LOG_MAC_FAILURES = new SafeInjectionToken<boolean>("LOG_MAC_FAILURES"); export const LOG_MAC_FAILURES = new SafeInjectionToken<boolean>("LOG_MAC_FAILURES");
export const SYSTEM_THEME_OBSERVABLE = new SafeInjectionToken<Observable<ThemeType>>( export const SYSTEM_THEME_OBSERVABLE = new SafeInjectionToken<Observable<Theme>>(
"SYSTEM_THEME_OBSERVABLE", "SYSTEM_THEME_OBSERVABLE",
); );
export const DEFAULT_VAULT_TIMEOUT = new SafeInjectionToken<VaultTimeout>("DEFAULT_VAULT_TIMEOUT"); export const DEFAULT_VAULT_TIMEOUT = new SafeInjectionToken<VaultTimeout>("DEFAULT_VAULT_TIMEOUT");

View File

@ -1,3 +1,6 @@
/**
* @deprecated prefer the `ThemeTypes` constants and `Theme` type over unsafe enum types
**/
export enum ThemeType { export enum ThemeType {
System = "system", System = "system",
Light = "light", Light = "light",
@ -5,3 +8,13 @@ export enum ThemeType {
Nord = "nord", Nord = "nord",
SolarizedDark = "solarizedDark", SolarizedDark = "solarizedDark",
} }
export const ThemeTypes = {
System: "system",
Light: "light",
Dark: "dark",
Nord: "nord",
SolarizedDark: "solarizedDark",
} as const;
export type Theme = (typeof ThemeTypes)[keyof typeof ThemeTypes];