diff --git a/vue/src/apps/ShoppingListView/ShoppingListView.vue b/vue/src/apps/ShoppingListView/ShoppingListView.vue
index 893c06aa..0c58d393 100644
--- a/vue/src/apps/ShoppingListView/ShoppingListView.vue
+++ b/vue/src/apps/ShoppingListView/ShoppingListView.vue
@@ -12,11 +12,11 @@
@@ -341,7 +341,7 @@
@@ -444,11 +444,11 @@
-
-
-
@@ -518,19 +518,7 @@ export default {
entry_mode_simple: true,
selected_supermarket: undefined,
},
- settings: {
- shopping_auto_sync: 0,
- default_delay: 4,
- mealplan_autoadd_shopping: false,
- mealplan_autoinclude_related: false,
- mealplan_autoexclude_onhand: true,
- filter_to_supermarket: false,
- shopping_recent_days: 7,
- csv_delim: ",",
- csv_prefix: undefined,
- shopping_add_onhand: true,
- left_handed: false,
- },
+
user_id: parseInt(localStorage.getItem('USER_ID')),
editing_supermarket_categories: [],
editing_supermarket: null,
@@ -585,6 +573,8 @@ export default {
this.$i18n.locale = window.CUSTOM_LOCALE
this.shopping_list_store.refreshFromAPI()
+ useUserPreferenceStore().loadUserSettings()
+ useUserPreferenceStore().loadDeviceSettings()
this.setupAutoSync()
},
methods: {
@@ -595,10 +585,10 @@ export default {
clearInterval(this.autosync_id)
this.autosync_id = undefined
- let timeout = Math.max(this.settings.shopping_auto_sync, 1) * 1000 // if disabled (shopping_auto_sync=0) check again after 1 second if enabled
+ let timeout = Math.max(this.user_preference_store.user_settings.shopping_auto_sync, 1) * 1000 // if disabled (shopping_auto_sync=0) check again after 1 second if enabled
this.autosync_id = setInterval(() => { //TODO does setInterval automatically loop (because it kind of did)
- if (this.online && this.settings.shopping_auto_sync > 0) {
+ if (this.online && this.user_preference_store.user_settings.shopping_auto_sync > 0) {
this.shopping_list_store.autosync()
this.setupAutoSync()
}
diff --git a/vue/src/stores/ShoppingListStore.js b/vue/src/stores/ShoppingListStore.js
index 80d8cb73..02279b46 100644
--- a/vue/src/stores/ShoppingListStore.js
+++ b/vue/src/stores/ShoppingListStore.js
@@ -215,7 +215,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
// set the update_at timestamp on the client to prevent auto sync from overriding with older changes
// moment().format() yields locale aware datetime without ms 2024-01-04T13:39:08.607238+01:00
Vue.set(object, 'update_at', moment().format())
- console.log('set local update timestamp to ', moment().format())
+
return apiClient.updateShoppingListEntry(object.id, object).then((r) => {
Vue.set(this.entries, r.data.id, r.data)
}).catch((err) => {
diff --git a/vue/src/stores/UserPreferenceStore.js b/vue/src/stores/UserPreferenceStore.js
index b378eeb3..8328c3d0 100644
--- a/vue/src/stores/UserPreferenceStore.js
+++ b/vue/src/stores/UserPreferenceStore.js
@@ -1,14 +1,15 @@
import {defineStore} from 'pinia'
-import {ApiApiFactory} from "@/utils/openapi/api";
+import {ApiApiFactory, UserPreference} from "@/utils/openapi/api";
import Vue from "vue";
const _STALE_TIME_IN_MS = 1000 * 30
const _STORE_ID = 'user_preference_store'
-const _LOCAL_STORAGE_KEY = 'TANDOOR_LOCAL_SETTINGS'
-
+const _LS_DEVICE_SETTINGS = 'TANDOOR_LOCAL_SETTINGS'
+const _LS_USER_SETTINGS = 'TANDOOR_USER_SETTINGS'
+const _USER_ID = localStorage.getItem('USER_ID')
export const useUserPreferenceStore = defineStore(_STORE_ID, {
state: () => ({
@@ -16,7 +17,41 @@ export const useUserPreferenceStore = defineStore(_STORE_ID, {
updated_at: null,
currently_updating: false,
+ user_settings_loaded_at: new Date(0),
+ user_settings: {
+ image: null,
+ theme: "TANDOOR",
+ nav_bg_color: "#ddbf86",
+ nav_text_color: "DARK",
+ nav_show_logo: true,
+ default_unit: "g",
+ default_page: "SEARCH",
+ use_fractions: false,
+ use_kj: false,
+ plan_share: [],
+ nav_sticky: true,
+ ingredient_decimals: 2,
+ comments: true,
+ shopping_auto_sync: 5,
+ mealplan_autoadd_shopping: false,
+ food_inherit_default: [],
+ default_delay: "4.0000",
+ mealplan_autoinclude_related: true,
+ mealplan_autoexclude_onhand: true,
+ shopping_share: [],
+ shopping_recent_days: 7,
+ csv_delim: ",",
+ csv_prefix: "",
+ filter_to_supermarket: false,
+ shopping_add_onhand: false,
+ left_handed: false,
+ show_step_ingredients: true,
+ food_children_exist: false,
+ locally_updated_at: new Date(0),
+ },
+
device_settings_initialized: false,
+ device_settings_loaded_at: new Date(0),
device_settings: {
// shopping
shopping_show_checked_entries: false,
@@ -29,36 +64,69 @@ export const useUserPreferenceStore = defineStore(_STORE_ID, {
shopping_item_info_recipe: true,
},
}),
- getters: {
- get_device_settings: function () {
- if (!this.device_settings_initialized) {
- // stupid hack to initialize device settings variable when store loads
- this.loadDeviceSettings()
- this.device_settings_initialized = true
- }
- return this.device_settings
- }
- },
+ getters: {},
actions: {
// Device settings (on device settings stored in local storage)
/**
* Load device settings from local storage and update state device_settings
*/
loadDeviceSettings() {
- let s = localStorage.getItem(_LOCAL_STORAGE_KEY)
+ let s = localStorage.getItem(_LS_DEVICE_SETTINGS)
if (!(s === null || s === {})) {
let settings = JSON.parse(s)
for (s in settings) {
Vue.set(this.device_settings, s, settings[s])
}
}
+ this.device_settings_initialized = true
},
/**
* persist changes to device settings into local storage
*/
updateDeviceSettings: function () {
- localStorage.setItem(_LOCAL_STORAGE_KEY, JSON.stringify(this.device_settings))
+ localStorage.setItem(_LS_DEVICE_SETTINGS, JSON.stringify(this.device_settings))
},
+ // ---------------- new methods for user settings
+ loadUserSettings: function () {
+ let s = localStorage.getItem(_LS_USER_SETTINGS)
+ if (!(s === null || s === {})) {
+ let settings = JSON.parse(s)
+ for (s in settings) {
+ Vue.set(this.user_settings, s, settings[s])
+ }
+ console.log(`loaded local user settings age ${((new Date().getTime()) - this.user_settings.locally_updated_at) / 1000} `)
+ }
+ if (((new Date().getTime()) - this.user_settings.locally_updated_at) > _STALE_TIME_IN_MS) {
+ console.log('refreshing user settings from API')
+ let apiClient = new ApiApiFactory()
+ apiClient.retrieveUserPreference(localStorage.getItem('USER_ID')).then(r => {
+ for (s in r.data) {
+ if (!(s in this.user_settings) && s !== 'user') {
+ // dont load new keys if no default exists (to prevent forgetting to add defaults)
+ console.error(`API returned UserPreference key "${s}" which has no default in UserPreferenceStore.user_settings.`)
+ } else {
+ Vue.set(this.user_settings, s, r.data[s])
+ }
+ }
+ Vue.set(this.user_settings, 'locally_updated_at', new Date().getTime())
+ localStorage.setItem(_LS_USER_SETTINGS, JSON.stringify(this.user_settings))
+ }).catch(err => {
+ this.currently_updating = false
+ })
+ }
+
+ },
+ updateUserSettings: function () {
+ let apiClient = new ApiApiFactory()
+ apiClient.partialUpdateUserPreference(_USER_ID, this.user_settings).then(r => {
+ this.user_settings = r.data
+ Vue.set(this.user_settings, 'locally_updated_at', new Date().getTime())
+ localStorage.setItem(_LS_USER_SETTINGS, JSON.stringify(this.user_settings))
+ }).catch(err => {
+ this.currently_updating = false
+ })
+ },
+ // ----------------
// User Preferences (database settings stored in user preference model)
/**
* gets data from the store either directly or refreshes from API if data is considered stale
@@ -120,6 +188,10 @@ export const useUserPreferenceStore = defineStore(_STORE_ID, {
this.data = r.data
this.updated_at = new Date()
this.currently_updating = false
+
+ this.user_settings = r.data
+ this.user_settings_loaded_at = new Date()
+
return this.data
}).catch(err => {
this.currently_updating = false