Fix duplicate item display immediately after adding to shopping list
This commit is contained in:
+3
-2
@@ -1181,8 +1181,9 @@ async def api_add_shopping_item(payload: ShoppingItemCreate):
|
||||
category=payload.category,
|
||||
note=payload.note or ""
|
||||
)
|
||||
await shopping_ws_manager.broadcast({"action": "items_updated", "items": get_shopping_list()})
|
||||
return {"status": "ok", "item": item}
|
||||
current_items = get_shopping_list()
|
||||
await shopping_ws_manager.broadcast({"action": "items_updated", "items": current_items})
|
||||
return {"status": "ok", "item": item, "items": current_items}
|
||||
|
||||
|
||||
@app.put("/api/shopping-list/{item_id}")
|
||||
|
||||
@@ -955,10 +955,25 @@
|
||||
localStorage.setItem('wtc_shop_cats_cache', JSON.stringify(allCategories));
|
||||
}
|
||||
|
||||
function deduplicateItems(items) {
|
||||
if (!Array.isArray(items)) return [];
|
||||
const seenIds = new Set();
|
||||
const unique = [];
|
||||
for (const item of items) {
|
||||
if (!item) continue;
|
||||
const key = item.id ? `id_${item.id}` : `name_${(item.item_name || '').toLowerCase().trim()}_${item.checked ? '1' : '0'}`;
|
||||
if (!seenIds.has(key)) {
|
||||
seenIds.add(key);
|
||||
unique.push(item);
|
||||
}
|
||||
}
|
||||
return unique;
|
||||
}
|
||||
|
||||
function saveLocalCache(items) {
|
||||
allItems = items;
|
||||
allItems = deduplicateItems(items);
|
||||
try {
|
||||
localStorage.setItem('wtc_shop_items_cache', JSON.stringify(items));
|
||||
localStorage.setItem('wtc_shop_items_cache', JSON.stringify(allItems));
|
||||
} catch (e) {
|
||||
console.warn('LocalStorage voll oder nicht verfügbar:', e);
|
||||
}
|
||||
@@ -1227,8 +1242,8 @@
|
||||
const emptyState = document.getElementById('empty-state');
|
||||
if (!container) return;
|
||||
|
||||
// Filter anwenden
|
||||
let filtered = allItems;
|
||||
// Filter anwenden (dedupliziert gegen parallele WebSocket- & Fetch-Ereignisse)
|
||||
let filtered = deduplicateItems(allItems);
|
||||
if (currentFilterCategory !== null) {
|
||||
filtered = filtered.filter(it => (it.category || 'Sonstiges') === currentFilterCategory);
|
||||
}
|
||||
@@ -1459,12 +1474,19 @@
|
||||
});
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
if (data.item) {
|
||||
allItems.push(data.item);
|
||||
saveLocalCache(allItems);
|
||||
renderShoppingList();
|
||||
renderCategoryFilterChips();
|
||||
if (data.items && Array.isArray(data.items)) {
|
||||
allItems = data.items;
|
||||
} else if (data.item) {
|
||||
const existingIdx = allItems.findIndex(it => it.id === data.item.id);
|
||||
if (existingIdx >= 0) {
|
||||
allItems[existingIdx] = data.item;
|
||||
} else {
|
||||
allItems.push(data.item);
|
||||
}
|
||||
}
|
||||
saveLocalCache(allItems);
|
||||
renderShoppingList();
|
||||
renderCategoryFilterChips();
|
||||
} else {
|
||||
throw new Error('Server-Fehler');
|
||||
}
|
||||
@@ -1480,7 +1502,12 @@
|
||||
checked: false,
|
||||
source: ''
|
||||
};
|
||||
allItems.push(tempItem);
|
||||
const existingIdx = allItems.findIndex(it => (it.item_name || '').toLowerCase().trim() === name.toLowerCase().trim() && !it.checked);
|
||||
if (existingIdx >= 0) {
|
||||
allItems[existingIdx] = tempItem;
|
||||
} else {
|
||||
allItems.push(tempItem);
|
||||
}
|
||||
pushOfflineQueue({ method: 'POST', url: '/api/shopping-list', body: payload });
|
||||
saveLocalCache(allItems);
|
||||
renderShoppingList();
|
||||
|
||||
Reference in New Issue
Block a user