From ac984a2d049f6792c98aa2d85035fad0d9d76a30 Mon Sep 17 00:00:00 2001 From: Craig Matear Date: Tue, 17 Jun 2025 19:41:35 +0100 Subject: [PATCH] fix: #5511, list item state doesn't change when offline (#5512) Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com> --- .../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..ccc683fe7 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 conflictingItem = mergedList.find((item) => item.id === list2Item.id) + if (conflictingItem && + list2Item.updatedAt && conflictingItem.updatedAt && + list2Item.updatedAt > conflictingItem.updatedAt) { + mergedList.splice(mergedList.indexOf(conflictingItem), 1, list2Item) + } else if (!conflictingItem) { + mergedList.push(list2Item) + } + }) + return mergedList + } + async function getList() { const response = await api.shopping.lists.getOne(shoppingListId); - return response.data; + if (window.$nuxt.isOffline && 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) {