diff --git a/komga-webui/package-lock.json b/komga-webui/package-lock.json
index 380eee9df..f75ed7337 100644
--- a/komga-webui/package-lock.json
+++ b/komga-webui/package-lock.json
@@ -27,6 +27,7 @@
"vuelidate": "^0.7.5",
"vuetify": "^2.3.7",
"vuex": "^3.5.1",
+ "vuex-persistedstate": "^3.2.0",
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
@@ -6618,7 +6619,6 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -17559,6 +17559,11 @@
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
"dev": true
},
+ "node_modules/shvl": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.2.tgz",
+ "integrity": "sha512-G3KkIXPza3dgkt6Bo8zIl5K/KvAAhbG6o9KfAjhPvrIIzzAhnfc2ztv1i+iPTbNNM43MaBUqIaZwqVjkSgY/rw=="
+ },
"node_modules/sigmund": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
@@ -19884,6 +19889,19 @@
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz",
"integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw=="
},
+ "node_modules/vuex-persistedstate": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-3.2.0.tgz",
+ "integrity": "sha512-1Q4zV9cNaJtl59jN6rXbndemEtXKywZr0OFZnqgpYdwvdyy+64KNsEltKldQW+i03st5LuDwHsdOEevXIZUgdg==",
+ "dependencies": {
+ "deepmerge": "^4.2.2",
+ "shvl": "^2.0.2"
+ },
+ "peerDependencies": {
+ "vue": "^2.0.0",
+ "vuex": "^2.0.0 || ^3.0.0"
+ }
+ },
"node_modules/vuex-router-sync": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/vuex-router-sync/-/vuex-router-sync-5.0.0.tgz",
@@ -26653,8 +26671,7 @@
"deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
- "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
- "dev": true
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
},
"default-gateway": {
"version": "5.0.5",
@@ -35712,6 +35729,11 @@
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
"dev": true
},
+ "shvl": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/shvl/-/shvl-2.0.2.tgz",
+ "integrity": "sha512-G3KkIXPza3dgkt6Bo8zIl5K/KvAAhbG6o9KfAjhPvrIIzzAhnfc2ztv1i+iPTbNNM43MaBUqIaZwqVjkSgY/rw=="
+ },
"sigmund": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
@@ -37677,6 +37699,15 @@
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.5.1.tgz",
"integrity": "sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw=="
},
+ "vuex-persistedstate": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/vuex-persistedstate/-/vuex-persistedstate-3.2.0.tgz",
+ "integrity": "sha512-1Q4zV9cNaJtl59jN6rXbndemEtXKywZr0OFZnqgpYdwvdyy+64KNsEltKldQW+i03st5LuDwHsdOEevXIZUgdg==",
+ "requires": {
+ "deepmerge": "^4.2.2",
+ "shvl": "^2.0.2"
+ }
+ },
"vuex-router-sync": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/vuex-router-sync/-/vuex-router-sync-5.0.0.tgz",
diff --git a/komga-webui/package.json b/komga-webui/package.json
index 3bba07955..64a9b0d75 100644
--- a/komga-webui/package.json
+++ b/komga-webui/package.json
@@ -30,6 +30,7 @@
"vuelidate": "^0.7.5",
"vuetify": "^2.3.7",
"vuex": "^3.5.1",
+ "vuex-persistedstate": "^3.2.0",
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
diff --git a/komga-webui/src/App.vue b/komga-webui/src/App.vue
index edf698bd6..375b4f277 100644
--- a/komga-webui/src/App.vue
+++ b/komga-webui/src/App.vue
@@ -5,19 +5,69 @@
diff --git a/komga-webui/src/main.ts b/komga-webui/src/main.ts
index 4a0c36bc7..967449d5d 100644
--- a/komga-webui/src/main.ts
+++ b/komga-webui/src/main.ts
@@ -28,16 +28,16 @@ Vue.use(lineClamp)
Vue.use(VueCookies)
Vue.use(httpPlugin)
-Vue.use(komgaFileSystem, { http: Vue.prototype.$http })
-Vue.use(komgaSeries, { http: Vue.prototype.$http })
-Vue.use(komgaCollections, { http: Vue.prototype.$http })
-Vue.use(komgaReadLists, { http: Vue.prototype.$http })
-Vue.use(komgaBooks, { http: Vue.prototype.$http })
-Vue.use(komgaReferential, { http: Vue.prototype.$http })
-Vue.use(komgaClaim, { http: Vue.prototype.$http })
-Vue.use(komgaUsers, { store: store, http: Vue.prototype.$http })
-Vue.use(komgaLibraries, { store: store, http: Vue.prototype.$http })
-Vue.use(actuator, { http: Vue.prototype.$http })
+Vue.use(komgaFileSystem, {http: Vue.prototype.$http})
+Vue.use(komgaSeries, {http: Vue.prototype.$http})
+Vue.use(komgaCollections, {http: Vue.prototype.$http})
+Vue.use(komgaReadLists, {http: Vue.prototype.$http})
+Vue.use(komgaBooks, {http: Vue.prototype.$http})
+Vue.use(komgaReferential, {http: Vue.prototype.$http})
+Vue.use(komgaClaim, {http: Vue.prototype.$http})
+Vue.use(komgaUsers, {store: store, http: Vue.prototype.$http})
+Vue.use(komgaLibraries, {store: store, http: Vue.prototype.$http})
+Vue.use(actuator, {http: Vue.prototype.$http})
Vue.prototype.$_ = _
Vue.prototype.$eventHub = new Vue()
diff --git a/komga-webui/src/plugins/persisted-state.ts b/komga-webui/src/plugins/persisted-state.ts
new file mode 100644
index 000000000..6914a5330
--- /dev/null
+++ b/komga-webui/src/plugins/persisted-state.ts
@@ -0,0 +1,17 @@
+import {Module} from "vuex"
+import {Theme} from "@/types/themes";
+
+export const persistedModule: Module = {
+ state: {
+ locale: '',
+ theme: Theme.LIGHT,
+ },
+ mutations: {
+ setLocale (state, val) {
+ state.locale = val
+ },
+ setTheme (state, val) {
+ state.theme = val
+ },
+ },
+}
diff --git a/komga-webui/src/store.ts b/komga-webui/src/store.ts
index a95483685..057086a8c 100644
--- a/komga-webui/src/store.ts
+++ b/komga-webui/src/store.ts
@@ -1,10 +1,16 @@
import Vue from 'vue'
import Vuex from 'vuex'
-import { BookDto } from '@/types/komga-books'
-import {SeriesDto} from "@/types/komga-series";
+import {BookDto} from '@/types/komga-books'
+import {SeriesDto} from "@/types/komga-series"
+import createPersistedState from "vuex-persistedstate"
+import {persistedModule} from './plugins/persisted-state'
Vue.use(Vuex)
+const persistedState = createPersistedState({
+ paths: ['persistedState'],
+})
+
export default new Vuex.Store({
state: {
// collections
@@ -181,4 +187,8 @@ export default new Vuex.Store({
commit('setUpdateSeriesDialog', value)
},
},
+ modules: {
+ persistedState: persistedModule,
+ },
+ plugins: [persistedState],
})
diff --git a/komga-webui/src/views/Home.vue b/komga-webui/src/views/Home.vue
index 01c57331b..e2eaffef0 100644
--- a/komga-webui/src/views/Home.vue
+++ b/komga-webui/src/views/Home.vue
@@ -102,9 +102,7 @@
- mdi-brightness-7
- mdi-brightness-3
- mdi-brightness-auto
+ {{ themeIcon }}
({text: this.$i18n.t('common.locale_name', x), value: x})),
}
},
@@ -173,18 +164,6 @@ export default Vue.extend({
if (this.isAdmin) {
this.info = await this.$actuator.getInfo()
}
-
- if (this.$cookies.isKey(cookieTheme)) {
- const theme = this.$cookies.get(cookieTheme)
- if (Object.values(Theme).includes(theme)) {
- this.theme = 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[] {
@@ -200,16 +179,25 @@ export default Vue.extend({
{text: this.$i18n.t(Theme.SYSTEM), value: Theme.SYSTEM},
]
},
+ themeIcon(): string {
+ switch (this.theme) {
+ case Theme.LIGHT:
+ return 'mdi-brightness-7'
+ case Theme.DARK:
+ return 'mdi-brightness-3'
+ case Theme.SYSTEM:
+ return 'mdi-brightness-auto'
+ }
+ return ''
+ },
theme: {
get: function (): Theme {
- return this.settings.theme
+ return this.$store.state.persistedState.theme
},
set: function (theme: Theme): void {
if (Object.values(Theme).includes(theme)) {
- this.settings.theme = theme
- this.changeTheme(theme)
- this.$cookies.set(cookieTheme, theme, Infinity)
+ this.$store.commit('setTheme', theme)
}
},
},
@@ -219,9 +207,7 @@ export default Vue.extend({
},
set: function (locale: string): void {
if (this.$i18n.availableLocales.includes(locale)) {
- this.$i18n.locale = locale
- this.$cookies.set(cookieLocale, locale, Infinity)
- this.$vuetify.rtl = (this.$t('common.locale_rtl') === 'true')
+ this.$store.commit('setLocale', locale)
}
},
},
@@ -230,26 +216,6 @@ export default Vue.extend({
toggleDrawer() {
this.drawerVisible = !this.drawerVisible
},
- systemThemeChange() {
- if (this.theme === Theme.SYSTEM) {
- this.changeTheme(this.theme)
- }
- },
- changeTheme(theme: Theme) {
- 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')
this.$router.push({name: 'login'})
diff --git a/komga-webui/src/views/Login.vue b/komga-webui/src/views/Login.vue
index 7ed943a5d..1ec0d9e19 100644
--- a/komga-webui/src/views/Login.vue
+++ b/komga-webui/src/views/Login.vue
@@ -64,7 +64,7 @@
-
+
+
+
+
+
+
@@ -93,8 +102,7 @@