fix: 优化模式切换体验和渲染逻辑

## 问题修复
1. 模式切换时不再闪现"暂无事件数据"
2. 模式切换按钮始终可见,不会因加载状态而隐藏

## 技术改进
- 将控制栏(模式切换+分页)提取到 EventScrollList 外层
- 使用 mode(立即同步)而非 currentMode(延迟一帧)检查缓存
- 优化渲染顺序:loading → 数据 → 空状态,避免闪烁

## 文件修改
- DynamicNewsCard.js: 添加控制栏导入,优化渲染逻辑
- EventScrollList.js: 移除重复的控制栏代码

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-11-06 01:40:24 +08:00
parent 31e5a4ee48
commit ebb737427f
2 changed files with 75 additions and 54 deletions

View File

@@ -28,6 +28,8 @@ import {
} from '@chakra-ui/react';
import { TimeIcon } from '@chakra-ui/icons';
import EventScrollList from './DynamicNewsCard/EventScrollList';
import ModeToggleButtons from './DynamicNewsCard/ModeToggleButtons';
import PaginationControl from './DynamicNewsCard/PaginationControl';
import DynamicNewsDetailPanel from './DynamicNewsDetail';
import UnifiedSearchBox from './UnifiedSearchBox';
import {
@@ -326,45 +328,79 @@ const DynamicNewsCard = forwardRef(({
{/* 主体内容 */}
<CardBody position="relative" pt={0}>
{/* 横向滚动事件列表 - 始终渲染(除非为空 */}
{currentPageEvents && currentPageEvents.length > 0 ? (
<EventScrollList
events={currentPageEvents}
displayEvents={displayEvents} // 累积显示的事件列表(平铺模式)
loadNextPage={loadNextPage} // 加载下一页
loadPrevPage={loadPrevPage} // 加载上一页
onFourRowEventClick={handleFourRowEventClick} // 四排模式事件点击
selectedEvent={selectedEvent}
onEventSelect={setSelectedEvent}
borderColor={borderColor}
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
loading={loadingPage !== null}
loadingPage={loadingPage}
error={error}
mode={mode}
onModeChange={handleModeToggle}
eventFollowStatus={eventFollowStatus}
onToggleFollow={handleToggleFollow}
hasMore={hasMore}
/>
) : !loading ? (
/* Empty 状态 - 只在非加载且无数据时显示 */
<Center py={10}>
<VStack>
<Text fontSize="lg" color="gray.500">暂无事件数据</Text>
</VStack>
</Center>
) : (
/* 首次加载状态 */
<Center py={10}>
<VStack>
<Spinner size="xl" color="blue.500" thickness="4px" />
<Text color="gray.500">正在加载最新事件...</Text>
</VStack>
</Center>
)}
{/* 顶部控制栏:模式切换按钮 + 分页控制器(始终显示 */}
<Flex justify="space-between" align="center" mb={2}>
{/* 左侧:模式切换按钮 */}
<ModeToggleButtons mode={mode} onModeChange={handleModeToggle} />
{/* 右侧:分页控制器(仅在纵向模式显示) */}
{mode === 'vertical' && totalPages > 1 && (
<PaginationControl
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
/>
)}
</Flex>
{/* 横向滚动事件列表 - 根据数据情况渲染 */}
{(() => {
// 检查对应模式是否有缓存数据(使用 mode 而非 currentMode避免延迟
const hasCachedData = mode === 'vertical'
? Object.keys(allCachedEventsByPage || {}).length > 0
: (allCachedEvents?.length || 0) > 0;
// 【优化渲染顺序】优先判断 loading避免闪现空状态
// 1. 首次加载(无缓存 + 加载中)→ 显示 loading
// 2. 有数据或有缓存 → 显示列表
// 3. 无数据且未加载 → 显示空状态
if (loading) {
/* 首次加载状态 - 无缓存数据时显示 loading */
return (
<Center py={10}>
<VStack>
<Spinner size="xl" color="blue.500" thickness="4px" />
<Text color="gray.500">正在加载最新事件...</Text>
</VStack>
</Center>
);
} else if (currentPageEvents.length > 0 || hasCachedData) {
/* 有数据 - 显示列表(可能在后台加载下一页) */
return (
<EventScrollList
events={currentPageEvents}
displayEvents={displayEvents} // 累积显示的事件列表(平铺模式)
loadNextPage={loadNextPage} // 加载下一页
loadPrevPage={loadPrevPage} // 加载上一页
onFourRowEventClick={handleFourRowEventClick} // 四排模式事件点击
selectedEvent={selectedEvent}
onEventSelect={setSelectedEvent}
borderColor={borderColor}
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
loading={loadingPage !== null}
loadingPage={loadingPage}
error={error}
mode={mode}
onModeChange={handleModeToggle}
eventFollowStatus={eventFollowStatus}
onToggleFollow={handleToggleFollow}
hasMore={hasMore}
/>
);
} else {
/* 空状态 - 确实无数据时才显示 */
return (
<Center py={10}>
<VStack>
<Text fontSize="lg" color="gray.500">暂无事件数据</Text>
</VStack>
</Center>
);
}
})()}
</CardBody>
{/* 四排模式详情弹窗 - 未打开时不渲染 */}

View File

@@ -81,21 +81,6 @@ const EventScrollList = ({
return (
<Box>
{/* 顶部控制栏:模式切换按钮 + 分页控制器 */}
<Flex justify="space-between" align="center" mb={2}>
{/* 左侧:模式切换按钮 */}
<ModeToggleButtons mode={mode} onModeChange={onModeChange} />
{/* 右侧:分页控制器(仅在纵向模式显示) */}
{mode === 'vertical' && totalPages > 1 && (
<PaginationControl
currentPage={currentPage}
totalPages={totalPages}
onPageChange={onPageChange}
/>
)}
</Flex>
{/* 横向滚动区域 */}
<Box position="relative">