feat: 集成四排/纵向模式UI和优化交互逻辑
VirtualizedFourRowGrid: - 组件通用化,支持多列布局(通过 columnsPerRow 参数配置) - 支持自定义卡片组件(通过 CardComponent 参数传入) - 根据列数动态调整间距 EventScrollList: - 添加四排和纵向模式切换按钮 - 集成 VirtualizedFourRowGrid 组件(四排模式使用4列,纵向模式使用1列) - 添加纵向分栏布局(1:2 比例,左侧列表+右侧详情) - 启用纵向滚动和统一滚动条样式 - 接收新 props: displayEvents, isAccumulateMode, loadNextPage, onFourRowEventClick DynamicNewsCard: - 添加 Modal 弹窗显示四排模式详情 - 优化自动选中逻辑: · 首次加载时自动选中第一个事件 · 翻页时,单排/双排/纵向模式自动选中当前页第一个事件(保持详情显示) · 翻页时,四排模式清空选中状态(通过弹窗显示详情) - 传递新 props 到 EventScrollList - 添加调试日志
This commit is contained in:
@@ -16,8 +16,15 @@ import {
|
||||
Badge,
|
||||
Center,
|
||||
Spinner,
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
useColorModeValue,
|
||||
useToast
|
||||
useToast,
|
||||
useDisclosure
|
||||
} from '@chakra-ui/react';
|
||||
import { TimeIcon } from '@chakra-ui/icons';
|
||||
import EventScrollList from './DynamicNewsCard/EventScrollList';
|
||||
@@ -27,6 +34,9 @@ import { fetchDynamicNews, toggleEventFollow, selectEventFollowStatus } from '..
|
||||
import { usePagination } from './DynamicNewsCard/hooks/usePagination';
|
||||
import { PAGINATION_CONFIG } from './DynamicNewsCard/constants';
|
||||
|
||||
// 🔍 调试:渲染计数器
|
||||
let dynamicNewsCardRenderCount = 0;
|
||||
|
||||
/**
|
||||
* 实时要闻·动态追踪 - 事件展示卡片组件
|
||||
* @param {Array} allCachedEvents - 完整缓存事件列表(从 Redux 传入)
|
||||
@@ -56,6 +66,9 @@ const DynamicNewsCard = forwardRef(({
|
||||
onViewDetail,
|
||||
...rest
|
||||
}, ref) => {
|
||||
// 🔍 调试:记录每次渲染
|
||||
dynamicNewsCardRenderCount++;
|
||||
console.log(`%c🔍 [DynamicNewsCard] 渲染 #${dynamicNewsCardRenderCount} - allCachedEvents.length=${allCachedEvents.length}, total=${total}`, 'color: #FF9800; font-weight: bold; font-size: 14px;');
|
||||
const dispatch = useDispatch();
|
||||
const toast = useToast();
|
||||
const cardBg = useColorModeValue('white', 'gray.800');
|
||||
@@ -72,8 +85,14 @@ const DynamicNewsCard = forwardRef(({
|
||||
// 本地状态
|
||||
const [selectedEvent, setSelectedEvent] = useState(null);
|
||||
|
||||
// 弹窗状态(用于四排模式)
|
||||
const { isOpen: isModalOpen, onOpen: onModalOpen, onClose: onModalClose } = useDisclosure();
|
||||
const [modalEvent, setModalEvent] = useState(null);
|
||||
|
||||
// 初始化标记 - 确保初始加载只执行一次
|
||||
const hasInitialized = useRef(false);
|
||||
// 追踪是否已自动选中过首个事件
|
||||
const hasAutoSelectedFirstEvent = useRef(false);
|
||||
|
||||
// 使用分页 Hook
|
||||
const {
|
||||
@@ -84,8 +103,11 @@ const DynamicNewsCard = forwardRef(({
|
||||
totalPages,
|
||||
hasMore,
|
||||
currentPageEvents,
|
||||
displayEvents, // 新增:累积显示的事件列表
|
||||
isAccumulateMode, // 新增:是否累积模式
|
||||
handlePageChange,
|
||||
handleModeToggle
|
||||
handleModeToggle,
|
||||
loadNextPage // 新增:加载下一页
|
||||
} = usePagination({
|
||||
allCachedEvents,
|
||||
total,
|
||||
@@ -94,6 +116,13 @@ const DynamicNewsCard = forwardRef(({
|
||||
toast
|
||||
});
|
||||
|
||||
// 四排模式的事件点击处理(打开弹窗)
|
||||
const handleFourRowEventClick = useCallback((event) => {
|
||||
console.log('%c🔲 [四排模式] 点击事件,打开详情弹窗', 'color: #8B5CF6; font-weight: bold;', { eventId: event.id, title: event.title });
|
||||
setModalEvent(event);
|
||||
onModalOpen();
|
||||
}, [onModalOpen]);
|
||||
|
||||
// 初始加载 - 只在组件首次挂载且未初始化时执行
|
||||
useEffect(() => {
|
||||
if (!hasInitialized.current && allCachedEvents.length === 0) {
|
||||
@@ -107,20 +136,37 @@ const DynamicNewsCard = forwardRef(({
|
||||
}
|
||||
}, [dispatch, allCachedEvents.length]);
|
||||
|
||||
// 默认选中第一个事件 - 只在当前选中的事件不在当前页时重置
|
||||
// 自动选中逻辑 - 只在首次加载时自动选中第一个事件,翻页时不自动选中
|
||||
useEffect(() => {
|
||||
if (currentPageEvents.length > 0) {
|
||||
// 检查当前选中的事件是否在当前页中
|
||||
// 情况1: 首次加载 - 自动选中第一个事件并触发详情加载
|
||||
if (!hasAutoSelectedFirstEvent.current && !selectedEvent) {
|
||||
console.log('%c🎯 [首次加载] 自动选中第一个事件', 'color: #10B981; font-weight: bold;');
|
||||
hasAutoSelectedFirstEvent.current = true;
|
||||
setSelectedEvent(currentPageEvents[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
// 情况2: 翻页 - 如果选中的事件不在当前页,根据模式决定处理方式
|
||||
const selectedEventInCurrentPage = currentPageEvents.find(
|
||||
e => e.id === selectedEvent?.id
|
||||
);
|
||||
|
||||
// 如果选中的事件不在当前页,则选中当前页第一个事件
|
||||
if (!selectedEventInCurrentPage) {
|
||||
setSelectedEvent(currentPageEvents[0]);
|
||||
if (selectedEvent && !selectedEventInCurrentPage) {
|
||||
console.log('%c📄 [翻页] 选中的事件不在当前页', 'color: #F59E0B; font-weight: bold;');
|
||||
|
||||
// 单排/双排/纵向模式:自动选中当前页第一个事件(保持详情显示)
|
||||
// 四排模式:清空选中状态(不需要底部详情)
|
||||
if (mode === 'carousel' || mode === 'grid' || mode === 'vertical') {
|
||||
console.log('%c📄 [翻页] 自动选中当前页第一个事件', 'color: #10B981; font-weight: bold;');
|
||||
setSelectedEvent(currentPageEvents[0]);
|
||||
} else {
|
||||
console.log('%c📄 [翻页] 清空选中状态(四排模式)', 'color: #F59E0B; font-weight: bold;');
|
||||
setSelectedEvent(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [currentPageEvents, selectedEvent?.id]);
|
||||
}, [currentPageEvents, selectedEvent?.id, mode]);
|
||||
|
||||
// 组件卸载时清理选中状态
|
||||
useEffect(() => {
|
||||
@@ -169,6 +215,10 @@ const DynamicNewsCard = forwardRef(({
|
||||
{currentPageEvents && currentPageEvents.length > 0 ? (
|
||||
<EventScrollList
|
||||
events={currentPageEvents}
|
||||
displayEvents={displayEvents} // 新增:累积显示的事件列表
|
||||
isAccumulateMode={isAccumulateMode} // 新增:是否累积模式
|
||||
loadNextPage={loadNextPage} // 新增:加载下一页
|
||||
onFourRowEventClick={handleFourRowEventClick} // 新增:四排模式事件点击
|
||||
selectedEvent={selectedEvent}
|
||||
onEventSelect={setSelectedEvent}
|
||||
borderColor={borderColor}
|
||||
@@ -200,13 +250,30 @@ const DynamicNewsCard = forwardRef(({
|
||||
</Center>
|
||||
)}
|
||||
|
||||
{/* 详情面板 - 始终显示(如果有选中事件) */}
|
||||
{currentPageEvents && currentPageEvents.length > 0 && selectedEvent && (
|
||||
{/* 详情面板 - 仅在单排/双排模式下显示(四排模式不显示,纵向模式已在右侧显示) */}
|
||||
{currentPageEvents && currentPageEvents.length > 0 && selectedEvent &&
|
||||
(mode === 'carousel' || mode === 'grid') && (
|
||||
<Box mt={6}>
|
||||
<DynamicNewsDetailPanel event={selectedEvent} />
|
||||
</Box>
|
||||
)}
|
||||
</CardBody>
|
||||
|
||||
{/* 四排模式详情弹窗 - 未打开时不渲染 */}
|
||||
{isModalOpen && (
|
||||
<Modal isOpen={isModalOpen} onClose={onModalClose} size="6xl" scrollBehavior="inside">
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>
|
||||
{modalEvent?.title || '事件详情'}
|
||||
</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody pb={6}>
|
||||
{modalEvent && <DynamicNewsDetailPanel event={modalEvent} />}
|
||||
</ModalBody>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user