From 7d4be79c49abff3d568b0677b09cb3f65b5961e8 Mon Sep 17 00:00:00 2001 From: Craig Date: Sun, 8 Jun 2025 13:19:32 +0000 Subject: [PATCH] fix(offline state #5511) * Merge pending local state with server state before presenting --- .../use-shopping-list-item-actions.ts | 26 +++++++++++++++++-- frontend/package.json | 2 +- frontend/pages/shopping-lists/_id.vue | 5 ++-- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/frontend/composables/use-shopping-list-item-actions.ts b/frontend/composables/use-shopping-list-item-actions.ts index ec6491499..fe0745df2 100644 --- a/frontend/composables/use-shopping-list-item-actions.ts +++ b/frontend/composables/use-shopping-list-item-actions.ts @@ -89,9 +89,31 @@ export function useShoppingListItemActions(shoppingListId: string) { return true; } + function mergeListItemsByLatest( + list1: ShoppingListItemOut[], + list2: ShoppingListItemOut[] + ) { + const mergedList = [...list1]; + list2.forEach((list2Item) => { + const confictingItem = mergedList.find((item) => item.id === list2Item.id) + if (confictingItem && + list2Item.updatedAt && confictingItem.updatedAt && + list2Item.updatedAt > confictingItem.updatedAt) { + mergedList.splice(mergedList.indexOf(confictingItem), 1, list2Item) + } else if (!confictingItem) { + mergedList.push(list2Item) + } + }) + return mergedList + } + async function getList() { const response = await api.shopping.lists.getOne(shoppingListId); - return response.data; + if (response.data) { + const createAndUpdateQueues = mergeListItemsByLatest(queue.update, queue.create); + response.data.listItems = mergeListItemsByLatest(response.data.listItems ?? [], createAndUpdateQueues); + } + return response.data } function createItem(item: ShoppingListItemOut) { @@ -188,7 +210,7 @@ export function useShoppingListItemActions(shoppingListId: string) { } async function process() { - if(queueEmpty.value) { + if (queueEmpty.value) { queue.lastUpdate = Date.now(); return; } diff --git a/frontend/package.json b/frontend/package.json index a9d71ebe4..00a418ec4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "mealie", -"version": "2.8.0", + "version": "2.8.0", "private": true, "scripts": { "dev": "nuxt", diff --git a/frontend/pages/shopping-lists/_id.vue b/frontend/pages/shopping-lists/_id.vue index 62a8c4407..48a71625c 100644 --- a/frontend/pages/shopping-lists/_id.vue +++ b/frontend/pages/shopping-lists/_id.vue @@ -878,10 +878,9 @@ export default defineComponent({ // make sure the item is at the end of the list with the other checked items item.position = shoppingList.value.listItems.length; - - // set a temporary updatedAt timestamp prior to refresh so it appears at the top of the checked items - item.updatedAt = new Date().toISOString(); } + // set a temporary updatedAt timestamp prior to refresh so it appears at the top of the checked items + item.updatedAt = new Date().toISOString(); // make updates reflect immediately if (shoppingList.value.listItems) {