diff --git a/komga-webui/src/types/themes.ts b/komga-webui/src/types/themes.ts
new file mode 100644
index 000000000..3004fd73c
--- /dev/null
+++ b/komga-webui/src/types/themes.ts
@@ -0,0 +1,5 @@
+export enum Theme {
+ LIGHT = 'Light',
+ DARK = 'Dark',
+ SYSTEM = 'System'
+}
diff --git a/komga-webui/src/views/Home.vue b/komga-webui/src/views/Home.vue
index 3ceff2680..e06a8118e 100644
--- a/komga-webui/src/views/Home.vue
+++ b/komga-webui/src/views/Home.vue
@@ -97,20 +97,22 @@
-
+
-
-
+
+
- mdi-brightness-7
- mdi-brightness-3
+ mdi-brightness-7
+ mdi-brightness-3
+ mdi-brightness-auto
-
- Light theme
- Dark theme
-
+
-
+
@@ -134,9 +136,10 @@
import Dialogs from '@/components/Dialogs.vue'
import LibraryActionsMenu from '@/components/menus/LibraryActionsMenu.vue'
import SearchBox from '@/components/SearchBox.vue'
+import { Theme } from '@/types/themes'
import Vue from 'vue'
-const cookieDarkMode = 'darkmode'
+const cookieTheme = 'theme'
export default Vue.extend({
name: 'home',
@@ -145,16 +148,36 @@ export default Vue.extend({
return {
drawerVisible: this.$vuetify.breakpoint.lgAndUp,
info: {} as ActuatorInfo,
+ activeTheme: Theme.LIGHT,
+ Theme,
+ themes: [
+ { text: Theme.LIGHT.valueOf(), value: Theme.LIGHT },
+ { text: Theme.DARK.valueOf(), value: Theme.DARK },
+ { text: Theme.SYSTEM.valueOf(), value: Theme.SYSTEM },
+ ],
}
},
+ watch: {
+ activeTheme (val) {
+ this.changeTheme(val)
+ },
+ },
async created () {
if (this.isAdmin) {
this.info = await this.$actuator.getInfo()
}
- if (this.$cookies.isKey(cookieDarkMode)) {
- this.$vuetify.theme.dark = (this.$cookies.get(cookieDarkMode) === 'true')
+ if (this.$cookies.isKey(cookieTheme)) {
+ const theme = this.$cookies.get(cookieTheme)
+ if (Object.values(Theme).includes(theme)) {
+ this.activeTheme = theme as Theme
+ }
}
+
+ window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', this.systemThemeChange)
+ },
+ async beforeDestroy () {
+ window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', this.systemThemeChange)
},
computed: {
libraries (): LibraryDto[] {
@@ -168,9 +191,26 @@ export default Vue.extend({
toggleDrawer () {
this.drawerVisible = !this.drawerVisible
},
- toggleDarkMode () {
- this.$vuetify.theme.dark = !this.$vuetify.theme.dark
- this.$cookies.set(cookieDarkMode, this.$vuetify.theme.dark, Infinity)
+ systemThemeChange () {
+ if (this.activeTheme === Theme.SYSTEM) {
+ this.changeTheme(this.activeTheme)
+ }
+ },
+ changeTheme (theme: Theme) {
+ this.$cookies.set(cookieTheme, theme.valueOf())
+ switch (theme) {
+ case Theme.DARK:
+ this.$vuetify.theme.dark = true
+ break
+
+ case Theme.SYSTEM:
+ this.$vuetify.theme.dark = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)
+ break
+
+ default:
+ this.$vuetify.theme.dark = false
+ break
+ }
},
logout () {
this.$store.dispatch('logout')