Add auto dark/light theme switch based on OS preference

Related to #825

Add automatic theme switching based on OS preference

* Add logic in `src/mixins/ThemingMixin.js` to detect OS theme preference using `window.matchMedia`.
* Update `initializeTheme` method in `src/mixins/ThemingMixin.js` to set theme based on OS preference.
* Modify `applyLocalTheme` method in `src/mixins/ThemingMixin.js` to apply the detected theme dynamically.
* Include logic in `src/App.vue` to detect and apply theme based on OS preference during app initialization.
This commit is contained in:
Vishwanath Martur 2024-12-17 22:03:15 +05:30
parent 85f842587b
commit c2bad0b0a9
2 changed files with 18 additions and 0 deletions

View File

@ -155,11 +155,21 @@ export default {
e.preventDefault(); e.preventDefault();
return 'You may have unsaved edits. Are you sure you want to exit the page?'; return 'You may have unsaved edits. Are you sure you want to exit the page?';
}, },
/* Detect and apply theme based on OS preference */
applyThemeBasedOnOSPreference() {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
const osTheme = prefersDark ? this.appConfig.nightTheme : this.appConfig.dayTheme;
if (osTheme) {
this.$store.commit(Keys.SET_THEME, osTheme);
this.updateTheme(osTheme);
}
},
}, },
/* Basic initialization tasks on app load */ /* Basic initialization tasks on app load */
async mounted() { async mounted() {
await this.$store.dispatch(Keys.INITIALIZE_CONFIG); // Initialize config before moving on await this.$store.dispatch(Keys.INITIALIZE_CONFIG); // Initialize config before moving on
this.applyLanguage(); // Apply users local language this.applyLanguage(); // Apply users local language
this.applyThemeBasedOnOSPreference(); // Apply theme based on OS preference
this.hideSplash(); // Hide the splash screen, if visible this.hideSplash(); // Hide the splash screen, if visible
if (this.appConfig.customCss) { // Inject users custom CSS, if present if (this.appConfig.customCss) { // Inject users custom CSS, if present
const cleanedCss = this.appConfig.customCss.replace(/<\/?[^>]+(>|$)/g, ''); const cleanedCss = this.appConfig.customCss.replace(/<\/?[^>]+(>|$)/g, '');

View File

@ -136,6 +136,14 @@ const ThemingMixin = {
} else if (hasExternal) { } else if (hasExternal) {
this.applyRemoteTheme(this.externalThemes[initialTheme]); this.applyRemoteTheme(this.externalThemes[initialTheme]);
} }
// Detect OS theme preference and apply the corresponding theme
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
const osTheme = prefersDark ? this.appConfig.nightTheme : this.appConfig.dayTheme;
if (osTheme) {
this.$store.commit(Keys.SET_THEME, osTheme);
this.updateTheme(osTheme);
}
}, },
}, },
}; };