4.13.3: Исправлена обработка кнопки назад
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 2m2s

This commit is contained in:
poignatov
2026-02-04 14:09:48 +03:00
parent a169da9387
commit 43df4d76ce
5 changed files with 142 additions and 3 deletions

View File

@@ -1 +1 @@
4.13.2 4.13.3

View File

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

View File

@@ -591,6 +591,20 @@ function AppContent() {
// Обработчик кнопки "назад" в браузере (только для глубоких табов) // Обработчик кнопки "назад" в браузере (только для глубоких табов)
useEffect(() => { useEffect(() => {
const handlePopState = (event) => { const handlePopState = (event) => {
// Проверяем, есть ли открытые модальные окна в DOM
const taskDetailModal = document.querySelector('.task-detail-modal-overlay')
const wishlistDetailModal = document.querySelector('.wishlist-detail-modal-overlay')
// Если есть открытые модальные окна, не обрабатываем здесь - компоненты сами закроют их
if (taskDetailModal || wishlistDetailModal) {
return
}
// Если это модальное окно, не обрабатываем здесь - компоненты сами закроют его
if (event.state && event.state.modalOpen) {
return
}
const validTabs = ['current', 'priorities', 'full', 'words', 'add-words', 'dictionaries', 'test', 'tasks', 'task-form', 'wishlist', 'wishlist-form', 'wishlist-detail', 'profile', 'todoist-integration', 'telegram-integration'] const validTabs = ['current', 'priorities', 'full', 'words', 'add-words', 'dictionaries', 'test', 'tasks', 'task-form', 'wishlist', 'wishlist-form', 'wishlist-detail', 'profile', 'todoist-integration', 'telegram-integration']
// Проверяем state текущей записи истории (куда мы вернулись) // Проверяем state текущей записи истории (куда мы вернулись)

View File

@@ -72,6 +72,50 @@ function TaskList({ onNavigate, data, loading, backgroundLoading, error, onRetry
setSelectedTaskForDetail(null) setSelectedTaskForDetail(null)
} }
// Добавляем запись в историю при открытии модального окна и обрабатываем "назад"
const historyPushedRef = useRef(false)
const selectedTaskForDetailRef = useRef(selectedTaskForDetail)
// Обновляем ref при изменении значения
useEffect(() => {
selectedTaskForDetailRef.current = selectedTaskForDetail
}, [selectedTaskForDetail])
useEffect(() => {
if (selectedTaskForDetail && !historyPushedRef.current) {
// Добавляем запись в историю при открытии модального окна
window.history.pushState({ modalOpen: true, type: 'task-detail' }, '', window.location.href)
historyPushedRef.current = true
} else if (!selectedTaskForDetail) {
historyPushedRef.current = false
}
if (!selectedTaskForDetail) return
const handlePopState = (event) => {
// Проверяем наличие модального окна в DOM
const taskDetailModal = document.querySelector('.task-detail-modal-overlay')
// Используем ref для получения актуального состояния
const currentTaskDetail = selectedTaskForDetailRef.current
// Проверяем, открыто ли модальное окно (по состоянию или в DOM)
if (currentTaskDetail || taskDetailModal) {
// Закрываем модальное окно
setSelectedTaskForDetail(null)
historyPushedRef.current = false
// Предотвращаем дальнейшую обработку в App.jsx
// Следующее нажатие "назад" обработается App.jsx нормально
return
}
}
window.addEventListener('popstate', handlePopState)
return () => {
window.removeEventListener('popstate', handlePopState)
}
}, [selectedTaskForDetail])
// Функция для вычисления следующей даты по repetition_date // Функция для вычисления следующей даты по repetition_date

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback } from 'react' import React, { useState, useEffect, useCallback, useRef } from 'react'
import { useAuth } from './auth/AuthContext' import { useAuth } from './auth/AuthContext'
import TaskDetail from './TaskDetail' import TaskDetail from './TaskDetail'
import LoadingError from './LoadingError' import LoadingError from './LoadingError'
@@ -160,6 +160,87 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p
setSelectedTaskForDetail(null) setSelectedTaskForDetail(null)
} }
// Добавляем запись в историю при открытии модальных окон и обрабатываем "назад"
const historyPushedForWishlistRef = useRef(false)
const historyPushedForTaskRef = useRef(false)
const wishlistIdRef = useRef(wishlistId)
const selectedTaskForDetailRef = useRef(selectedTaskForDetail)
// Обновляем refs при изменении значений
useEffect(() => {
wishlistIdRef.current = wishlistId
selectedTaskForDetailRef.current = selectedTaskForDetail
}, [wishlistId, selectedTaskForDetail])
useEffect(() => {
if (wishlistId && !historyPushedForWishlistRef.current) {
// Добавляем запись в историю при открытии модального окна WishlistDetail
window.history.pushState({ modalOpen: true, type: 'wishlist-detail' }, '', window.location.href)
historyPushedForWishlistRef.current = true
} else if (!wishlistId) {
historyPushedForWishlistRef.current = false
}
if (selectedTaskForDetail && !historyPushedForTaskRef.current) {
// Добавляем запись в историю при открытии вложенного модального окна TaskDetail
window.history.pushState({ modalOpen: true, type: 'task-detail', nested: true }, '', window.location.href)
historyPushedForTaskRef.current = true
} else if (!selectedTaskForDetail) {
historyPushedForTaskRef.current = false
}
if (!wishlistId && !selectedTaskForDetail) return
const handlePopState = (event) => {
// Проверяем наличие модальных окон в DOM
const taskDetailModal = document.querySelector('.task-detail-modal-overlay')
const wishlistDetailModal = document.querySelector('.wishlist-detail-modal-overlay')
// Используем refs для получения актуального состояния
const currentTaskDetail = selectedTaskForDetailRef.current
const currentWishlistId = wishlistIdRef.current
// Сначала проверяем вложенное модальное окно TaskDetail
if (currentTaskDetail || taskDetailModal) {
setSelectedTaskForDetail(null)
historyPushedForTaskRef.current = false
// Возвращаем запись для WishlistDetail
if (currentWishlistId || wishlistDetailModal) {
window.history.pushState({ modalOpen: true, type: 'wishlist-detail' }, '', window.location.href)
}
return
}
// Если открыто модальное окно WishlistDetail, закрываем его
if (currentWishlistId || wishlistDetailModal) {
if (onClose) {
onClose()
} else {
// Возвращаемся на предыдущий таб, если он был сохранен, иначе на wishlist
if (previousTab) {
if (boardId) {
onNavigate?.(previousTab, { boardId })
} else {
onNavigate?.(previousTab)
}
} else if (boardId) {
onNavigate?.('wishlist', { boardId })
} else {
onNavigate?.('wishlist')
}
}
historyPushedForWishlistRef.current = false
// Следующее нажатие "назад" обработается App.jsx нормально
return
}
}
window.addEventListener('popstate', handlePopState)
return () => {
window.removeEventListener('popstate', handlePopState)
}
}, [wishlistId, selectedTaskForDetail, onClose, onNavigate, previousTab, boardId])
const handleClose = () => { const handleClose = () => {
// Используем onClose если передан, иначе возвращаемся на wishlist // Используем onClose если передан, иначе возвращаемся на wishlist
if (onClose) { if (onClose) {