mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-06-07 07:03:55 +02:00
0f38561e15
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
111 lines
2.8 KiB
JavaScript
111 lines
2.8 KiB
JavaScript
import { writable } from 'svelte/store';
|
|
import { browser } from '$app/environment';
|
|
|
|
// mode constants
|
|
export const modeLight = 'light';
|
|
export const modeDark = 'dark';
|
|
const modeNotSet = 'not-set';
|
|
const modeKey = 'theme-mode';
|
|
|
|
/**
|
|
* theme store - either 'light' or 'dark'
|
|
* use it to know which theme is current and subscribe to know when it changes
|
|
*/
|
|
export const theme = writable(modeLight);
|
|
|
|
/**
|
|
* toggle the theme mode from light to dark or vice versa
|
|
* @returns {void}
|
|
*/
|
|
export const toggleMode = () => {
|
|
theme.update((current) => {
|
|
const newMode = current === modeLight ? modeDark : modeLight;
|
|
setModeToLocalStorage(newMode);
|
|
applyThemeToHTML(newMode);
|
|
return newMode;
|
|
});
|
|
};
|
|
|
|
/**
|
|
* setup the theme mode - must be called once during app bootstrapping
|
|
* checks localStorage, then OS preference, defaults to light
|
|
* @returns {string} the mode that was set
|
|
*/
|
|
export function setupTheme() {
|
|
if (!browser) return modeLight;
|
|
|
|
let mode = getModeFromLocalStorage();
|
|
if (mode === modeNotSet) {
|
|
mode = getOSPreferredMode();
|
|
setModeToLocalStorage(mode);
|
|
}
|
|
|
|
applyThemeToHTML(mode);
|
|
theme.set(mode);
|
|
return mode;
|
|
}
|
|
|
|
/**
|
|
* get the OS preferred light or dark mode
|
|
* @returns {string} either 'light' or 'dark'
|
|
*/
|
|
export const getOSPreferredMode = () => {
|
|
if (!browser) return modeLight;
|
|
|
|
const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
return darkMediaQuery.matches ? modeDark : modeLight;
|
|
};
|
|
|
|
/**
|
|
* get the theme mode from localStorage
|
|
* @returns {string} the stored mode or 'not-set'
|
|
*/
|
|
export const getModeFromLocalStorage = () => {
|
|
if (!browser) return modeNotSet;
|
|
return localStorage.getItem(modeKey) ?? modeNotSet;
|
|
};
|
|
|
|
/**
|
|
* set the theme mode in localStorage
|
|
* @param {string} mode - either 'light' or 'dark'
|
|
*/
|
|
export const setModeToLocalStorage = (mode) => {
|
|
if (!browser) return;
|
|
localStorage.setItem(modeKey, mode);
|
|
};
|
|
|
|
/**
|
|
* apply the theme to the HTML element by adding/removing the 'dark' class
|
|
* @param {string} mode - either 'light' or 'dark'
|
|
*/
|
|
const applyThemeToHTML = (mode) => {
|
|
if (!browser) return;
|
|
|
|
const html = document.documentElement;
|
|
if (mode === modeDark) {
|
|
html.classList.add('dark');
|
|
html.style.backgroundColor = '#111827';
|
|
} else {
|
|
html.classList.remove('dark');
|
|
html.style.removeProperty('background-color');
|
|
}
|
|
};
|
|
|
|
/**
|
|
* set up theme change listener for OS preference changes
|
|
*/
|
|
export const setupOSThemeListener = () => {
|
|
if (!browser) return;
|
|
|
|
const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
darkMediaQuery.addEventListener('change', (e) => {
|
|
// only update if user hasn't manually set a preference
|
|
const storedMode = getModeFromLocalStorage();
|
|
if (storedMode === modeNotSet) {
|
|
const newMode = e.matches ? modeDark : modeLight;
|
|
applyThemeToHTML(newMode);
|
|
theme.set(newMode);
|
|
}
|
|
});
|
|
};
|