diff --git a/client/components/app/BookShelfToolbar.vue b/client/components/app/BookShelfToolbar.vue index c0de0308..fe9b3ba1 100644 --- a/client/components/app/BookShelfToolbar.vue +++ b/client/components/app/BookShelfToolbar.vue @@ -367,11 +367,11 @@ export default { }, mounted() { this.init() - this.$store.commit('user/addSettingsListener', { id: 'bookshelftoolbar', meth: this.settingsUpdated }) + this.$eventBus.$on('user-settings', this.settingsUpdated) this.$eventBus.$on('bookshelf-total-entities', this.setBookshelfTotalEntities) }, beforeDestroy() { - this.$store.commit('user/removeSettingsListener', 'bookshelftoolbar') + this.$eventBus.$off('user-settings', this.settingsUpdated) this.$eventBus.$off('bookshelf-total-entities', this.setBookshelfTotalEntities) } } diff --git a/client/components/app/LazyBookshelf.vue b/client/components/app/LazyBookshelf.vue index f5eee3ce..0c40d38e 100644 --- a/client/components/app/LazyBookshelf.vue +++ b/client/components/app/LazyBookshelf.vue @@ -670,8 +670,7 @@ export default { this.$eventBus.$on('series-sort-updated', this.seriesSortUpdated) this.$eventBus.$on('bookshelf_clear_selection', this.clearSelectedEntities) this.$eventBus.$on('socket_init', this.socketInit) - - this.$store.commit('user/addSettingsListener', { id: 'lazy-bookshelf', meth: this.settingsUpdated }) + this.$eventBus.$on('user-settings', this.settingsUpdated) if (this.$root.socket) { this.$root.socket.on('item_updated', this.libraryItemUpdated) @@ -699,8 +698,7 @@ export default { this.$eventBus.$off('series-sort-updated', this.seriesSortUpdated) this.$eventBus.$off('bookshelf_clear_selection', this.clearSelectedEntities) this.$eventBus.$off('socket_init', this.socketInit) - - this.$store.commit('user/removeSettingsListener', 'lazy-bookshelf') + this.$eventBus.$off('user-settings', this.settingsUpdated) if (this.$root.socket) { this.$root.socket.off('item_updated', this.libraryItemUpdated) diff --git a/client/components/player/PlayerUi.vue b/client/components/player/PlayerUi.vue index b2edb81c..c230ced5 100644 --- a/client/components/player/PlayerUi.vue +++ b/client/components/player/PlayerUi.vue @@ -234,13 +234,10 @@ export default { this.showChaptersModal = false }, setUseChapterTrack() { - var useChapterTrack = !this.useChapterTrack - this.useChapterTrack = useChapterTrack - if (this.$refs.trackbar) this.$refs.trackbar.setUseChapterTrack(useChapterTrack) + this.useChapterTrack = !this.useChapterTrack + if (this.$refs.trackbar) this.$refs.trackbar.setUseChapterTrack(this.useChapterTrack) - this.$store.dispatch('user/updateUserSettings', { useChapterTrack }).catch((err) => { - console.error('Failed to update settings', err) - }) + this.$store.dispatch('user/updateUserSettings', { useChapterTrack: this.useChapterTrack }) this.updateTimestamp() }, checkUpdateChapterTrack() { @@ -311,7 +308,7 @@ export default { init() { this.playbackRate = this.$store.getters['user/getUserSetting']('playbackRate') || 1 - var _useChapterTrack = this.$store.getters['user/getUserSetting']('useChapterTrack') || false + const _useChapterTrack = this.$store.getters['user/getUserSetting']('useChapterTrack') || false this.useChapterTrack = this.chapters.length ? _useChapterTrack : false if (this.$refs.trackbar) this.$refs.trackbar.setUseChapterTrack(this.useChapterTrack) @@ -345,13 +342,14 @@ export default { } }, mounted() { - this.$store.commit('user/addSettingsListener', { id: 'audioplayer', meth: this.settingsUpdated }) - this.init() this.$eventBus.$on('player-hotkey', this.hotkey) + this.$eventBus.$on('user-settings', this.settingsUpdated) + + this.init() }, beforeDestroy() { - this.$store.commit('user/removeSettingsListener', 'audioplayer') this.$eventBus.$off('player-hotkey', this.hotkey) + this.$eventBus.$off('user-settings', this.settingsUpdated) } } diff --git a/client/layouts/default.vue b/client/layouts/default.vue index fe2aab53..05729252 100644 --- a/client/layouts/default.vue +++ b/client/layouts/default.vue @@ -280,7 +280,6 @@ export default { userUpdated(user) { if (this.$store.state.user.user.id === user.id) { this.$store.commit('user/setUser', user) - this.$store.commit('user/setSettings', user.settings) } }, userOnline(user) { diff --git a/client/pages/login.vue b/client/pages/login.vue index 2f5c4e75..b1bcf75b 100644 --- a/client/pages/login.vue +++ b/client/pages/login.vue @@ -137,6 +137,8 @@ export default { this.$store.commit('libraries/setCurrentLibrary', userDefaultLibraryId) this.$store.commit('user/setUser', user) + + this.$store.dispatch('user/loadUserSettings') }, async submitForm() { this.error = null diff --git a/client/plugins/init.client.js b/client/plugins/init.client.js index b65ab155..1f1aed59 100644 --- a/client/plugins/init.client.js +++ b/client/plugins/init.client.js @@ -5,8 +5,6 @@ import { formatDistance, format, addDays, isDate } from 'date-fns' Vue.directive('click-outside', vClickOutside.directive) -Vue.prototype.$eventBus = new Vue() - Vue.prototype.$dateDistanceFromNow = (unixms) => { if (!unixms) return '' return formatDistance(unixms, Date.now(), { addSuffix: true }) @@ -159,6 +157,7 @@ export { export default ({ app, store }, inject) => { app.$decode = decode app.$encode = encode + inject('eventBus', new Vue()) inject('isDev', process.env.NODE_ENV !== 'production') store.commit('setRouterBasePath', app.$config.routerBasePath) diff --git a/client/store/user.js b/client/store/user.js index 7b57b169..33623ba7 100644 --- a/client/store/user.js +++ b/client/store/user.js @@ -7,9 +7,9 @@ export const state = () => ({ playbackRate: 1, bookshelfCoverSize: 120, collapseSeries: false, - collapseBookSeries: false - }, - settingsListeners: [] + collapseBookSeries: false, + useChapterTrack: false + } }) export const getters = { @@ -66,7 +66,7 @@ export const getters = { export const actions = { // When changing libraries make sure sort and filter is still valid checkUpdateLibrarySortFilter({ state, dispatch, commit }, mediaType) { - var settingsUpdate = {} + const settingsUpdate = {} if (mediaType == 'podcast') { if (state.settings.orderBy == 'media.metadata.authorName' || state.settings.orderBy == 'media.metadata.authorNameLF') { settingsUpdate.orderBy = 'media.metadata.author' @@ -77,8 +77,8 @@ export const actions = { if (state.settings.orderBy == 'media.metadata.publishedYear') { settingsUpdate.orderBy = 'media.metadata.title' } - var invalidFilters = ['series', 'authors', 'narrators', 'languages', 'progress', 'issues'] - var filterByFirstPart = (state.settings.filterBy || '').split('.').shift() + const invalidFilters = ['series', 'authors', 'narrators', 'languages', 'progress', 'issues'] + const filterByFirstPart = (state.settings.filterBy || '').split('.').shift() if (invalidFilters.includes(filterByFirstPart)) { settingsUpdate.filterBy = 'all' } @@ -94,30 +94,47 @@ export const actions = { dispatch('updateUserSettings', settingsUpdate) } }, - updateUserSettings({ commit }, payload) { - var updatePayload = { - ...payload - } - // Immediately update - commit('setSettings', updatePayload) - return this.$axios.$patch('/api/me/settings', updatePayload).then((result) => { - if (result.success) { - commit('setSettings', result.settings) - return true - } else { - return false + updateUserSettings({ state, commit }, payload) { + if (!payload) return false + + let hasChanges = false + const existingSettings = { ...state.settings } + for (const key in existingSettings) { + if (payload[key] !== undefined && existingSettings[key] !== payload[key]) { + hasChanges = true + existingSettings[key] = payload[key] } - }).catch((error) => { - console.error('Failed to update settings', error) - return false - }) + } + if (hasChanges) { + localStorage.setItem('userSettings', JSON.stringify(existingSettings)) + commit('setSettings', existingSettings) + this.$eventBus.$emit('user-settings', state.settings) + } + }, + loadUserSettings({ state, commit }) { + // Load settings from local storage + try { + let userSettingsFromLocal = localStorage.getItem('userSettings') + if (userSettingsFromLocal) { + userSettingsFromLocal = JSON.parse(userSettingsFromLocal) + const userSettings = { ...state.settings } + for (const key in userSettings) { + if (userSettingsFromLocal[key] !== undefined) { + userSettings[key] = userSettingsFromLocal[key] + } + } + commit('setSettings', userSettings) + this.$eventBus.$emit('user-settings', state.settings) + } + } catch (error) { + console.error('Failed to load userSettings from local storage', error) + } } } export const mutations = { setUser(state, user) { state.user = user - state.settings = user.settings if (user) { if (user.token) localStorage.setItem('token', user.token) } else { @@ -143,25 +160,6 @@ export const mutations = { }, setSettings(state, settings) { if (!settings) return - var hasChanges = false - for (const key in settings) { - if (state.settings[key] !== settings[key]) { - hasChanges = true - state.settings[key] = settings[key] - } - } - if (hasChanges) { - state.settingsListeners.forEach((listener) => { - listener.meth(state.settings) - }) - } - }, - addSettingsListener(state, listener) { - var index = state.settingsListeners.findIndex(l => l.id === listener.id) - if (index >= 0) state.settingsListeners.splice(index, 1, listener) - else state.settingsListeners.push(listener) - }, - removeSettingsListener(state, listenerId) { - state.settingsListeners = state.settingsListeners.filter(l => l.id !== listenerId) + state.settings = settings } } \ No newline at end of file diff --git a/server/objects/user/User.js b/server/objects/user/User.js index b2db254b..cfaa5a17 100644 --- a/server/objects/user/User.js +++ b/server/objects/user/User.js @@ -63,13 +63,7 @@ class User { return { mobileOrderBy: 'recent', mobileOrderDesc: true, - mobileFilterBy: 'all', - orderBy: 'media.metadata.title', - orderDesc: false, - filterBy: 'all', - playbackRate: 1, - bookshelfCoverSize: 120, - collapseSeries: false + mobileFilterBy: 'all' } }