mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-01 19:48:08 +00:00
128 lines
4.4 KiB
JavaScript
128 lines
4.4 KiB
JavaScript
import { adjustColorForContrast } from '../shared/helpers/colorHelper.js';
|
|
|
|
export const setPortalHoverColor = theme => {
|
|
// This function is to set the hover color for the portal
|
|
if (theme === 'system') {
|
|
const prefersDarkMode = window.matchMedia(
|
|
'(prefers-color-scheme: dark)'
|
|
).matches;
|
|
theme = prefersDarkMode ? 'dark' : 'light';
|
|
}
|
|
|
|
const portalColor = window.portalConfig.portalColor;
|
|
const bgColor = theme === 'dark' ? '#151718' : 'white';
|
|
const hoverColor = adjustColorForContrast(portalColor, bgColor);
|
|
|
|
// Set hover color for border and text dynamically
|
|
document.documentElement.style.setProperty(
|
|
'--dynamic-hover-color',
|
|
hoverColor
|
|
);
|
|
};
|
|
|
|
export const removeQueryParamsFromUrl = (queryParam = 'theme') => {
|
|
// This function is to remove the theme query param from the URL
|
|
// This is done so that the theme is not persisted in the URL
|
|
// This is called when the theme is switched from the dropdown
|
|
const url = new URL(window.location.href);
|
|
const param = url.searchParams.get(queryParam);
|
|
|
|
if (param) {
|
|
url.searchParams.delete(queryParam);
|
|
window.history.replaceState({}, '', url.toString()); // Convert URL to string
|
|
}
|
|
};
|
|
|
|
export const updateThemeInHeader = theme => {
|
|
// This function is to update the theme selection in the header in real time
|
|
const themeToggleButton = document.getElementById('toggle-appearance');
|
|
|
|
if (!themeToggleButton) return;
|
|
const allElementInButton =
|
|
themeToggleButton.querySelectorAll('.theme-button');
|
|
|
|
if (!allElementInButton) return;
|
|
allElementInButton.forEach(button => {
|
|
button.classList.toggle('hidden', button.dataset.theme !== theme);
|
|
button.classList.toggle('flex', button.dataset.theme === theme);
|
|
});
|
|
};
|
|
|
|
export const switchTheme = theme => {
|
|
if (theme === 'system') {
|
|
localStorage.removeItem('theme');
|
|
const prefersDarkMode = window.matchMedia(
|
|
'(prefers-color-scheme: dark)'
|
|
).matches;
|
|
// remove this so that the system theme is used
|
|
|
|
document.documentElement.classList.remove('dark', 'light');
|
|
document.documentElement.classList.add(prefersDarkMode ? 'dark' : 'light');
|
|
} else {
|
|
localStorage.theme = theme;
|
|
|
|
document.documentElement.classList.remove('dark', 'light');
|
|
document.documentElement.classList.add(theme);
|
|
}
|
|
|
|
setPortalHoverColor(theme);
|
|
updateThemeInHeader(theme);
|
|
removeQueryParamsFromUrl();
|
|
};
|
|
|
|
export const initializeThemeSwitchButtons = () => {
|
|
const appearanceDropdown = document.getElementById('appearance-dropdown');
|
|
appearanceDropdown.dataset.currentTheme = localStorage.theme || 'system';
|
|
|
|
appearanceDropdown.addEventListener('click', event => {
|
|
const target = event.target.closest('button[data-theme]');
|
|
|
|
if (target) {
|
|
const { theme } = target.dataset;
|
|
// setting this data property will automatically toggle the checkmark using CSS
|
|
appearanceDropdown.dataset.currentTheme = theme;
|
|
switchTheme(theme);
|
|
// wait for a bit before hiding the dropdown
|
|
appearanceDropdown.style.display = 'none';
|
|
}
|
|
});
|
|
};
|
|
|
|
export const initializeToggleButton = () => {
|
|
const themeToggleButton = document.getElementById('toggle-appearance');
|
|
|
|
themeToggleButton?.addEventListener('click', () => {
|
|
const appearanceDropdown = document.getElementById('appearance-dropdown');
|
|
|
|
const isCurrentlyHidden = appearanceDropdown.style.display === 'none';
|
|
// Toggle the appearanceDropdown
|
|
appearanceDropdown.style.display = isCurrentlyHidden ? 'flex' : 'none';
|
|
});
|
|
};
|
|
|
|
export const initializeMediaQueryListener = () => {
|
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
|
|
mediaQuery.addEventListener('change', () => {
|
|
if (['light', 'dark'].includes(localStorage.theme)) return;
|
|
|
|
switchTheme('system');
|
|
});
|
|
};
|
|
|
|
export const initializeTheme = () => {
|
|
if (window.portalConfig.isPlainLayoutEnabled === 'true') return;
|
|
// start with updating the theme in the header, this will set the current theme on the button
|
|
// and set the hover color at the start of init, this is set again when the theme is switched
|
|
setPortalHoverColor(localStorage.theme || 'system');
|
|
window.updateThemeInHeader = updateThemeInHeader;
|
|
updateThemeInHeader(localStorage.theme || 'system');
|
|
|
|
// add the event listeners for the dropdown toggle and theme buttons
|
|
initializeToggleButton();
|
|
initializeThemeSwitchButtons();
|
|
|
|
// add the media query listener to update the theme when the system theme changes
|
|
initializeMediaQueryListener();
|
|
};
|