fix(offline state #5511)

* Merge pending local state with server state before presenting
This commit is contained in:
Craig 2025-06-08 13:19:32 +00:00
commit 7d4be79c49
3 changed files with 27 additions and 6 deletions

View file

@ -89,9 +89,31 @@ export function useShoppingListItemActions(shoppingListId: string) {
return true; 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() { async function getList() {
const response = await api.shopping.lists.getOne(shoppingListId); 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) { function createItem(item: ShoppingListItemOut) {
@ -188,7 +210,7 @@ export function useShoppingListItemActions(shoppingListId: string) {
} }
async function process() { async function process() {
if(queueEmpty.value) { if (queueEmpty.value) {
queue.lastUpdate = Date.now(); queue.lastUpdate = Date.now();
return; return;
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "mealie", "name": "mealie",
"version": "2.8.0", "version": "2.8.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "nuxt", "dev": "nuxt",

View file

@ -878,10 +878,9 @@ export default defineComponent({
// make sure the item is at the end of the list with the other checked items // make sure the item is at the end of the list with the other checked items
item.position = shoppingList.value.listItems.length; item.position = shoppingList.value.listItems.length;
}
// set a temporary updatedAt timestamp prior to refresh so it appears at the top of the checked items // set a temporary updatedAt timestamp prior to refresh so it appears at the top of the checked items
item.updatedAt = new Date().toISOString(); item.updatedAt = new Date().toISOString();
}
// make updates reflect immediately // make updates reflect immediately
if (shoppingList.value.listItems) { if (shoppingList.value.listItems) {