6.15.1: Фикс race condition при смене доски желаний
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m25s

This commit is contained in:
poignatov
2026-03-13 14:52:07 +03:00
parent c8a47ff408
commit 6f76c4a25c
4 changed files with 52 additions and 36 deletions

View File

@@ -1 +1 @@
6.15.0
6.15.1

Binary file not shown.

View File

@@ -1,6 +1,6 @@
{
"name": "play-life-web",
"version": "6.15.0",
"version": "6.15.1",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -51,9 +51,11 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
const fetchingCompletedRef = useRef(false)
const initialFetchDoneRef = useRef(false)
const prevIsActiveRef = useRef(isActive)
const selectedBoardIdRef = useRef(getInitialBoardId())
// Обёртка для setSelectedBoardId с сохранением в localStorage
const setSelectedBoardId = (boardId) => {
selectedBoardIdRef.current = boardId
setSelectedBoardIdState(boardId)
try {
if (boardId) {
@@ -171,20 +173,20 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
}
// Загрузка желаний выбранной доски
const fetchItems = async () => {
if (!selectedBoardId || fetchingRef.current) return
const fetchItems = async (boardId) => {
if (!boardId || fetchingRef.current) return
fetchingRef.current = true
try {
const hasDataInState = items.length > 0 || completedCount > 0
if (!hasDataInState) {
const cacheLoaded = loadItemsFromCache(selectedBoardId)
const cacheLoaded = loadItemsFromCache(boardId)
if (!cacheLoaded) {
setLoading(true)
}
}
const response = await authFetch(`${API_URL}/boards/${selectedBoardId}/items`)
const response = await authFetch(`${API_URL}/boards/${boardId}/items`)
if (!response.ok) {
throw new Error('Ошибка при загрузке желаний')
@@ -194,31 +196,37 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
const allItems = [...(data.unlocked || []), ...(data.locked || [])]
const count = data.completed_count || 0
// Проверяем, что пользователь не переключился на другую доску пока шёл запрос
if (selectedBoardIdRef.current !== boardId) return
setItems(allItems)
setCompletedCount(count)
saveItemsToCache(selectedBoardId, allItems, count)
saveItemsToCache(boardId, allItems, count)
setError('')
} catch (err) {
if (selectedBoardIdRef.current !== boardId) return
setError(err.message)
if (!loadItemsFromCache(selectedBoardId)) {
if (!loadItemsFromCache(boardId)) {
setItems([])
setCompletedCount(0)
}
} finally {
setLoading(false)
if (selectedBoardIdRef.current === boardId) {
setLoading(false)
}
fetchingRef.current = false
}
}
// Загрузка завершённых для текущей доски
const fetchCompleted = async () => {
if (fetchingCompletedRef.current || !selectedBoardId) return
const fetchCompleted = async (boardId) => {
if (fetchingCompletedRef.current || !boardId) return
fetchingCompletedRef.current = true
try {
setCompletedLoading(true)
// Используем новый API для получения завершённых на доске
const response = await authFetch(`${API_URL}/boards/${selectedBoardId}/completed`)
const response = await authFetch(`${API_URL}/boards/${boardId}/completed`)
if (!response.ok) {
const errText = await response.text()
@@ -228,12 +236,20 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
const data = await response.json()
const completedData = Array.isArray(data) ? data : []
// Проверяем, что пользователь не переключился на другую доску пока шёл запрос
if (selectedBoardIdRef.current !== boardId) return
setCompleted(completedData)
} catch (err) {
console.error('Error fetching completed items:', err)
setCompleted([])
if (selectedBoardIdRef.current === boardId) {
setCompleted([])
}
} finally {
setCompletedLoading(false)
if (selectedBoardIdRef.current === boardId) {
setCompletedLoading(false)
}
fetchingCompletedRef.current = false
}
}
@@ -292,7 +308,7 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
}
// Загружаем свежие данные
fetchItems()
fetchItems(selectedBoardId)
}
}, [selectedBoardId])
@@ -306,7 +322,7 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
if (isActive && !wasActive) {
fetchBoards()
if (selectedBoardId) {
fetchItems()
fetchItems(selectedBoardId)
}
}
}, [isActive])
@@ -321,9 +337,9 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
console.error('Error clearing cache:', err)
}
fetchBoards()
fetchItems()
fetchItems(selectedBoardId)
if (completedExpanded && completedCount > 0) {
fetchCompleted()
fetchCompleted(selectedBoardId)
}
}
}, [refreshTrigger, selectedBoardId])
@@ -421,7 +437,7 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
setCompletedExpanded(newExpanded)
if (newExpanded && completedCount > 0) {
fetchCompleted()
fetchCompleted(selectedBoardId)
}
}
@@ -465,9 +481,9 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
}
setSelectedItem(null)
await fetchItems()
await fetchItems(selectedBoardId)
if (completedExpanded) {
await fetchCompleted()
await fetchCompleted(selectedBoardId)
}
} catch (err) {
setError(err.message)
@@ -502,7 +518,7 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
}
// Обновляем список
await fetchItems()
await fetchItems(selectedBoardId)
// Открываем форму редактирования для нового желания
onNavigate?.('wishlist-form', { wishlistId: newItem.id, boardId: selectedBoardId })
@@ -682,7 +698,7 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
loading={boardsLoading}
showBoardAction={false}
/>
<LoadingError onRetry={() => fetchItems()} />
<LoadingError onRetry={() => fetchItems(selectedBoardId)} />
</div>
)
}
@@ -794,9 +810,9 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
onNavigate={onNavigate}
boardId={selectedBoardId}
onRefresh={async () => {
await fetchItems()
await fetchItems(selectedBoardId)
if (completedExpanded) {
await fetchCompleted()
await fetchCompleted(selectedBoardId)
}
}}
onClose={handleCloseDetail}