Skip to content

Commit

Permalink
fix theme
Browse files Browse the repository at this point in the history
  • Loading branch information
FelixTJDietrich committed Sep 22, 2024
1 parent 3d26821 commit c5c3006
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 40 deletions.
87 changes: 47 additions & 40 deletions webapp/src/app/core/theme/theme-switcher.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,71 +5,78 @@ export enum AppTheme {
DARK = 'dark'
}

const IS_CLIENT_RENDER = typeof localStorage !== 'undefined';
const LOCAL_STORAGE_THEME_KEY = 'theme';

let selectedTheme: AppTheme | undefined = undefined;

if (IS_CLIENT_RENDER) {
selectedTheme = (localStorage.getItem(LOCAL_STORAGE_THEME_KEY) as AppTheme) || undefined;
}

@Injectable({
providedIn: 'root'
})
export class ThemeSwitcherService {
currentTheme = signal<AppTheme | undefined>(selectedTheme);
private htmlElement = document.documentElement;
private metaThemeColor = document.querySelector<HTMLMetaElement>('meta[name="theme-color"]');

currentTheme = signal<AppTheme | 'auto' | undefined>(this.getInitialTheme());

constructor() {
if (this.currentTheme() === 'auto') {
this.applySystemTheme();
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', this.handleSystemThemeChange);
}
}

setLightTheme() {
this.currentTheme.set(AppTheme.LIGHT);
this.setToLocalStorage(AppTheme.LIGHT);
this.removeClassFromHtml('dark');
document.documentElement.setAttribute('data-color-mode', 'light');
this.applyTheme(AppTheme.LIGHT);
}

setDarkTheme() {
this.currentTheme.set(AppTheme.DARK);
this.setToLocalStorage(AppTheme.DARK);
this.addClassToHtml('dark');
document.documentElement.setAttribute('data-color-mode', 'dark');
this.applyTheme(AppTheme.DARK);
}

setSystemTheme() {
this.currentTheme.set(undefined);
this.removeFromLocalStorage();
this.currentTheme.set('auto');
localStorage.removeItem(LOCAL_STORAGE_THEME_KEY);
this.applySystemTheme();
this.updateMetaThemeColor();
}

const isSystemDark = window?.matchMedia('(prefers-color-scheme: dark)').matches ?? false;
if (isSystemDark) {
this.addClassToHtml('dark');
} else {
this.removeClassFromHtml('dark');
}
private applyTheme(theme: AppTheme) {
this.currentTheme.set(theme);
localStorage.setItem(LOCAL_STORAGE_THEME_KEY, theme);
this.htmlElement.classList.toggle(AppTheme.DARK, theme === AppTheme.DARK);
this.htmlElement.setAttribute('data-color-mode', theme);
this.updateMetaThemeColor();
}

document.documentElement.setAttribute('data-color-mode', 'auto');
private applySystemTheme() {
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
this.htmlElement.classList.toggle(AppTheme.DARK, isDark);
this.htmlElement.setAttribute('data-color-mode', 'auto');
this.updateMetaThemeColor();
}

private addClassToHtml(className: string) {
if (IS_CLIENT_RENDER) {
this.removeClassFromHtml(className);
document.documentElement.classList.add(className);
private handleSystemThemeChange = (event: MediaQueryListEvent) => {
if (this.currentTheme() === 'auto') {
this.htmlElement.classList.toggle(AppTheme.DARK, event.matches);
this.updateMetaThemeColor();
}
}
};

private removeClassFromHtml(className: string) {
if (IS_CLIENT_RENDER) {
document.documentElement.classList.remove(className);
private updateMetaThemeColor() {
if (this.metaThemeColor) {
const backgroundColor = getComputedStyle(this.htmlElement).getPropertyValue('--background').trim();
this.metaThemeColor.setAttribute('content', `hsl(${backgroundColor})`);
}
}

private setToLocalStorage(theme: AppTheme) {
if (IS_CLIENT_RENDER) {
localStorage.setItem(LOCAL_STORAGE_THEME_KEY, theme);
private getInitialTheme(): AppTheme | 'auto' | undefined {
if (typeof localStorage === 'undefined') {
return 'auto';
}
}

private removeFromLocalStorage() {
if (IS_CLIENT_RENDER) {
localStorage.removeItem(LOCAL_STORAGE_THEME_KEY);
const storedTheme = localStorage.getItem(LOCAL_STORAGE_THEME_KEY) as AppTheme | null;
if (storedTheme === AppTheme.LIGHT || storedTheme === AppTheme.DARK) {
return storedTheme;
}

return 'auto';
}
}
7 changes: 7 additions & 0 deletions webapp/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<html lang="en" data-color-mode="auto" data-light-theme="light" data-dark-theme="dark">
<head>
<meta charset="utf-8" />
<meta name="theme-color" content="hsl(0 0% 100%)" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<title>Hephaestus</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
Expand Down Expand Up @@ -30,6 +32,11 @@
document.documentElement.setAttribute('data-color-mode', browserDark ? 'dark' : 'light');
localStorage.setItem('theme', browserDark ? 'dark' : 'light');
}

const metaThemeColor = document.querySelector('meta[name="theme-color"]');
if (metaThemeColor) {
metaThemeColor.setAttribute('content', `hsl(${getComputedStyle(document.documentElement).getPropertyValue('--background')})`);
}
</script>
<body>
<app-root></app-root>
Expand Down

0 comments on commit c5c3006

Please sign in to comment.