Skip to content

Commit

Permalink
feat: detect and set preferred theme based on user settings (#634)
Browse files Browse the repository at this point in the history
* feat: detect and set preferred theme based on user settings

* feat: add auto theme settings

* fix: clarify dark theme application logic

* Lint
  • Loading branch information
BelKed authored Feb 21, 2025
1 parent 8ec401c commit 606112e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 10 deletions.
11 changes: 7 additions & 4 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ div#wrapper(v-if="loaded")
<script lang="ts">
import { useSettingsStore } from '~/stores/settings';
import { useServerStore } from '~/stores/server';
import { detectPreferredTheme } from '~/util/theme';
// if vite is used, you can import css file as module
//import darkCssUrl from '../static/dark.css?url';
//import darkCssContent from '../static/dark.css?inline';
Expand All @@ -39,8 +40,10 @@ export default {
const settingsStore = useSettingsStore();
await settingsStore.ensureLoaded();
const theme = settingsStore.theme;
// Check Application Mode (Light | Dark)
if (theme !== null && theme === 'dark') {
const detectedTheme = theme === 'auto' ? detectPreferredTheme() : theme;
// Apply the dark theme if detected
if (detectedTheme === 'dark') {
const method: 'link' | 'style' = 'link';
if (method === 'link') {
Expand All @@ -49,8 +52,8 @@ export default {
const themeLink = document.createElement('link');
themeLink.href = '/dark.css'; // darkCssUrl
themeLink.rel = 'stylesheet';
// Append Dark Theme Element If Selected Mode Is Dark
theme === 'dark' ? document.querySelector('head').appendChild(themeLink) : '';
// Append Dark Theme Element
document.querySelector('head').appendChild(themeLink);
} else {
// Not supported for Webpack due to not supporting ?inline import in a cross-compatible way (afaik)
// Method 2: Create <style> Element
Expand Down
4 changes: 2 additions & 2 deletions src/stores/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface State {
durationDefault: number;
useColorFallback: boolean;
landingpage: string;
theme: 'light' | 'dark';
theme: 'light' | 'dark' | 'auto';

newReleaseCheckData: Record<string, any>;
userSatisfactionPollData: {
Expand Down Expand Up @@ -59,7 +59,7 @@ export const useSettingsStore = defineStore('settings', {
useColorFallback: false,
landingpage: '/home',

theme: 'light',
theme: 'auto',

newReleaseCheckData: {
isEnabled: true,
Expand Down
6 changes: 6 additions & 0 deletions src/util/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function detectPreferredTheme(): 'light' | 'dark' {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
}
return 'light';
}
17 changes: 13 additions & 4 deletions src/views/settings/Theme.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ div
h5.mt-1.mb-2.mb-sm-0 Theme
div
b-select.landingpage(v-if="_loaded" size="sm" :value="theme", @change="theme = $event")
option(value="auto") Auto (System)
option(value="light") Light
option(value="dark") Dark
span(v-else)
Expand All @@ -16,6 +17,7 @@ div
<script lang="ts">
import { mapState } from 'pinia';
import { useSettingsStore } from '~/stores/settings';
import { detectPreferredTheme } from '~/util/theme';
export default {
name: 'Theme',
Expand All @@ -33,15 +35,22 @@ export default {
theme: value,
});
// Determine the actual theme to apply
const detectedTheme = value === 'auto' ? detectPreferredTheme() : value;
// Apply newly set theme
// Create Dark Theme Element
const themeLink = document.createElement('link');
themeLink.href = '/dark.css';
themeLink.rel = 'stylesheet';
// Append Dark Theme Element If Selected Mode Is Dark
value === 'dark'
? document.querySelector('head').appendChild(themeLink)
: document.querySelector(`link[href="${new URL(themeLink.href).pathname}"]`).remove();
// Remove existing theme link if present
document.querySelector(`link[href="${new URL(themeLink.href).pathname}"]`)?.remove();
// Append Dark Theme Element if dark theme should be applied
if (detectedTheme === 'dark') {
document.querySelector('head').appendChild(themeLink);
}
},
},
},
Expand Down

0 comments on commit 606112e

Please sign in to comment.