From 492357777c23aea2538804fe2785352c2933f463 Mon Sep 17 00:00:00 2001 From: Mo Date: Fri, 25 Mar 2022 07:49:08 -0500 Subject: [PATCH] fix: don't apply system color scheme anytime any preference changes --- .../javascripts/services/themeManager.ts | 114 ++++++++++-------- 1 file changed, 67 insertions(+), 47 deletions(-) diff --git a/app/assets/javascripts/services/themeManager.ts b/app/assets/javascripts/services/themeManager.ts index 9d4b8bcb2..e44372043 100644 --- a/app/assets/javascripts/services/themeManager.ts +++ b/app/assets/javascripts/services/themeManager.ts @@ -20,52 +20,16 @@ export class ThemeManager extends ApplicationService { private activeThemes: UuidString[] = []; private unregisterDesktop!: () => void; private unregisterStream!: () => void; + private lastUseDeviceThemeSettings = false; constructor(application: WebApplication) { super(application, new InternalEventBus()); this.colorSchemeEventHandler = this.colorSchemeEventHandler.bind(this); } - private colorSchemeEventHandler(event: MediaQueryListEvent) { - this.setThemeAsPerColorScheme(event.matches); - } - - private setThemeAsPerColorScheme(prefersDarkColorScheme: boolean) { - const useDeviceThemeSettings = this.application.getPreference( - PrefKey.UseSystemColorScheme, - false - ); - - if (useDeviceThemeSettings) { - const preference = prefersDarkColorScheme - ? PrefKey.AutoDarkThemeIdentifier - : PrefKey.AutoLightThemeIdentifier; - const themes = this.application.items.getDisplayableItems( - ContentType.Theme - ) as SNTheme[]; - - const enableDefaultTheme = () => { - const activeTheme = themes.find( - (theme) => theme.active && !theme.isLayerable() - ); - if (activeTheme) this.application.mutator.toggleTheme(activeTheme); - }; - - const themeIdentifier = this.application.getPreference( - preference, - 'Default' - ) as string; - if (themeIdentifier === 'Default') { - enableDefaultTheme(); - } else { - const theme = themes.find( - (theme) => theme.package_info.identifier === themeIdentifier - ); - if (theme && !theme.active) { - this.application.mutator.toggleTheme(theme); - } - } - } + async onAppStart() { + super.onAppStart(); + this.registerObservers(); } async onAppEvent(event: ApplicationEvent) { @@ -95,15 +59,33 @@ export class ThemeManager extends ApplicationService { break; } case ApplicationEvent.PreferencesChanged: { - const prefersDarkColorScheme = window.matchMedia( - '(prefers-color-scheme: dark)' - ); - this.setThemeAsPerColorScheme(prefersDarkColorScheme.matches); + this.handlePreferencesChangeEvent(); break; } } } + private handlePreferencesChangeEvent(): void { + const useDeviceThemeSettings = this.application.getPreference( + PrefKey.UseSystemColorScheme, + false + ); + + if (useDeviceThemeSettings === this.lastUseDeviceThemeSettings) { + return; + } + + this.lastUseDeviceThemeSettings = useDeviceThemeSettings; + + const prefersDarkColorScheme = window.matchMedia( + '(prefers-color-scheme: dark)' + ); + this.setThemeAsPerColorScheme( + useDeviceThemeSettings, + prefersDarkColorScheme.matches + ); + } + get webApplication() { return this.application as WebApplication; } @@ -158,9 +140,47 @@ export class ThemeManager extends ApplicationService { } } - async onAppStart() { - super.onAppStart(); - this.registerObservers(); + private colorSchemeEventHandler(event: MediaQueryListEvent) { + this.setThemeAsPerColorScheme( + this.lastUseDeviceThemeSettings, + event.matches + ); + } + + private setThemeAsPerColorScheme( + useDeviceThemeSettings: boolean, + prefersDarkColorScheme: boolean + ) { + if (useDeviceThemeSettings) { + const preference = prefersDarkColorScheme + ? PrefKey.AutoDarkThemeIdentifier + : PrefKey.AutoLightThemeIdentifier; + const themes = this.application.items.getDisplayableItems( + ContentType.Theme + ) as SNTheme[]; + + const enableDefaultTheme = () => { + const activeTheme = themes.find( + (theme) => theme.active && !theme.isLayerable() + ); + if (activeTheme) this.application.mutator.toggleTheme(activeTheme); + }; + + const themeIdentifier = this.application.getPreference( + preference, + 'Default' + ) as string; + if (themeIdentifier === 'Default') { + enableDefaultTheme(); + } else { + const theme = themes.find( + (theme) => theme.package_info.identifier === themeIdentifier + ); + if (theme && !theme.active) { + this.application.mutator.toggleTheme(theme); + } + } + } } private async activateCachedThemes() {