auto sync proper data merging
This commit is contained in:
parent
71ea67dc30
commit
7de9758ee1
@ -1152,7 +1152,7 @@ class ShoppingListEntrySerializer(WritableNestedModelSerializer):
|
|||||||
'recipe_mealplan',
|
'recipe_mealplan',
|
||||||
'created_by', 'created_at', 'updated_at', 'completed_at', 'delay_until'
|
'created_by', 'created_at', 'updated_at', 'completed_at', 'delay_until'
|
||||||
)
|
)
|
||||||
read_only_fields = ('id', 'created_by', 'created_at',)
|
read_only_fields = ('id', 'created_by', 'created_at','updated_at',)
|
||||||
|
|
||||||
|
|
||||||
class ShoppingListEntryBulkSerializer(serializers.Serializer):
|
class ShoppingListEntryBulkSerializer(serializers.Serializer):
|
||||||
|
@ -1168,7 +1168,8 @@ class ShoppingListEntryViewSet(viewsets.ModelViewSet):
|
|||||||
try:
|
try:
|
||||||
last_autosync = self.request.query_params.get('last_autosync', None)
|
last_autosync = self.request.query_params.get('last_autosync', None)
|
||||||
if last_autosync:
|
if last_autosync:
|
||||||
last_autosync = make_aware(datetime.datetime.fromtimestamp(int(last_autosync) / 1000))
|
|
||||||
|
last_autosync = datetime.datetime.fromtimestamp(int(last_autosync) / 1000, datetime.timezone.utc)
|
||||||
self.queryset = self.queryset.filter(updated_at__gte=last_autosync)
|
self.queryset = self.queryset.filter(updated_at__gte=last_autosync)
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
@ -1189,7 +1190,10 @@ class ShoppingListEntryViewSet(viewsets.ModelViewSet):
|
|||||||
Q(created_by=self.request.user)
|
Q(created_by=self.request.user)
|
||||||
| Q(shoppinglist__shared=self.request.user)
|
| Q(shoppinglist__shared=self.request.user)
|
||||||
| Q(created_by__in=list(self.request.user.get_shopping_share()))
|
| Q(created_by__in=list(self.request.user.get_shopping_share()))
|
||||||
).filter(space=request.space, id__in=serializer.validated_data['ids']).update(checked=serializer.validated_data['checked'])
|
).filter(space=request.space, id__in=serializer.validated_data['ids']).update(
|
||||||
|
checked=serializer.validated_data['checked'],
|
||||||
|
updated_at=timezone.now(),
|
||||||
|
)
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
else:
|
else:
|
||||||
return Response(serializer.errors, 400)
|
return Response(serializer.errors, 400)
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<b-alert :show="shopping_list_store.has_failed_items" dismissible class="float-up mt-2" variant="warning">
|
<b-alert :show="shopping_list_store.has_failed_items" class="float-up mt-2" variant="warning">
|
||||||
{{$t('ShoppingBackgroundSyncWarning')}}
|
{{$t('ShoppingBackgroundSyncWarning')}}
|
||||||
</b-alert>
|
</b-alert>
|
||||||
|
|
||||||
|
|
||||||
<div class="row float-top w-100">
|
<div class="row float-top w-100">
|
||||||
<div class="col-auto no-gutter ml-auto">
|
<div class="col-auto no-gutter ml-auto">
|
||||||
<b-button variant="link" @click="useShoppingListStore().undoChange()"><i class="fas fa-undo"></i>
|
<b-button variant="link" @click="useShoppingListStore().undoChange()"><i class="fas fa-undo"></i>
|
||||||
@ -555,10 +554,6 @@ export default {
|
|||||||
useUserPreferenceStore().loadUserSettings()
|
useUserPreferenceStore().loadUserSettings()
|
||||||
useUserPreferenceStore().loadDeviceSettings()
|
useUserPreferenceStore().loadDeviceSettings()
|
||||||
this.autoSyncLoop()
|
this.autoSyncLoop()
|
||||||
|
|
||||||
setInterval(() => {
|
|
||||||
this.getSyncQueueLength()
|
|
||||||
},1000)
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
useUserPreferenceStore,
|
useUserPreferenceStore,
|
||||||
|
@ -157,6 +157,8 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
refreshFromAPI() {
|
refreshFromAPI() {
|
||||||
if (!this.currently_updating) {
|
if (!this.currently_updating) {
|
||||||
this.currently_updating = true
|
this.currently_updating = true
|
||||||
|
this.last_autosync = new Date().getTime();
|
||||||
|
|
||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
apiClient.listShoppingListEntrys().then((r) => {
|
apiClient.listShoppingListEntrys().then((r) => {
|
||||||
this.entries = {}
|
this.entries = {}
|
||||||
@ -189,6 +191,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
*/
|
*/
|
||||||
autosync() {
|
autosync() {
|
||||||
if (!this.currently_updating && this.autosync_has_focus) {
|
if (!this.currently_updating && this.autosync_has_focus) {
|
||||||
|
|
||||||
this.currently_updating = true
|
this.currently_updating = true
|
||||||
|
|
||||||
let previous_autosync = this.last_autosync
|
let previous_autosync = this.last_autosync
|
||||||
@ -200,6 +203,8 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
}).then((r) => {
|
}).then((r) => {
|
||||||
r.data.forEach((e) => {
|
r.data.forEach((e) => {
|
||||||
// dont update stale client data
|
// dont update stale client data
|
||||||
|
console.log('new: ', !(Object.keys(this.entries).includes(e.id.toString())), ' updated at ', Date.parse(this.entries[e.id].updated_at) < Date.parse(e.updated_at))
|
||||||
|
console.log('client updated at ', this.entries[e.id].updated_at,Date.parse(this.entries[e.id].updated_at), ' server updated at ', e.updated_at,Date.parse(e.updated_at))
|
||||||
if (!(Object.keys(this.entries).includes(e.id.toString())) || Date.parse(this.entries[e.id].updated_at) < Date.parse(e.updated_at)) {
|
if (!(Object.keys(this.entries).includes(e.id.toString())) || Date.parse(this.entries[e.id].updated_at) < Date.parse(e.updated_at)) {
|
||||||
console.log('auto sync updating entry ', e)
|
console.log('auto sync updating entry ', e)
|
||||||
Vue.set(this.entries, e.id, e)
|
Vue.set(this.entries, e.id, e)
|
||||||
@ -242,7 +247,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
let apiClient = new ApiApiFactory()
|
let apiClient = new ApiApiFactory()
|
||||||
// sets the update_at timestamp on the client to prevent auto sync from overriding with older changes
|
// sets 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
|
// moment().format() yields locale aware datetime without ms 2024-01-04T13:39:08.607238+01:00
|
||||||
Vue.set(object, 'update_at', moment().format())
|
Vue.set(object, 'updated_at', moment().format())
|
||||||
|
|
||||||
return apiClient.updateShoppingListEntry(object.id, object).then((r) => {
|
return apiClient.updateShoppingListEntry(object.id, object).then((r) => {
|
||||||
Vue.set(this.entries, r.data.id, r.data)
|
Vue.set(this.entries, r.data.id, r.data)
|
||||||
@ -321,11 +326,12 @@ export const useShoppingListStore = defineStore(_STORE_ID, {
|
|||||||
if (undo) {
|
if (undo) {
|
||||||
this.registerChange((checked ? 'CHECKED' : 'UNCHECKED'), entries)
|
this.registerChange((checked ? 'CHECKED' : 'UNCHECKED'), entries)
|
||||||
}
|
}
|
||||||
|
console.log('entry changed at ', Date.now(), ' setting to ', moment().format())
|
||||||
|
|
||||||
let entry_id_list = []
|
let entry_id_list = []
|
||||||
for (let i in entries) {
|
for (let i in entries) {
|
||||||
Vue.set(this.entries[i], 'checked', checked)
|
Vue.set(this.entries[i], 'checked', checked)
|
||||||
Vue.set(this.entries[i], 'update_at', moment().format())
|
Vue.set(this.entries[i], 'updated_at', moment().format())
|
||||||
entry_id_list.push(i)
|
entry_id_list.push(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user