Files
vf_react/src/views/Community/components/DynamicNewsCard/EventScrollList.js
zdl 743aefb2f0 refactor: 删除单排和双排模式,简化事件列表展示
问题:
- 事件列表组件包含4种模式(单排/双排/纵向/平铺)
- 单排(carousel)和双排(grid)模式代码已被注释,未实际使用
- 保留未使用代码增加维护成本和代码复杂度

修改:
1. 删除未使用的 import(DynamicNewsEventCard, CompactEventCard, Spinner, HStack)
2. 删除加载遮罩相关代码(仅单排/双排模式使用)
3. 删除已注释的单排/双排切换按钮代码
4. 删除单排轮播模式完整实现(~32行)
5. 删除双排网格模式完整实现(~33行)
6. 更新组件注释:明确只支持纵向和平铺两种模式
7. 更新默认模式:carousel → vertical
8. 简化条件判断(overflowX/overflowY/maxH)

效果:
- 代码从 361 行缩减到 254 行(删除 ~107 行)
- 只保留两种实际使用的模式:纵向(vertical)和平铺(four-row)
- 降低代码复杂度,提升可维护性

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-05 13:37:18 +08:00

255 lines
8.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// src/views/Community/components/DynamicNewsCard/EventScrollList.js
// 横向滚动事件列表组件
import React, { useRef } from 'react';
import {
Box,
Flex,
Grid,
GridItem,
Button,
ButtonGroup,
Center,
VStack,
Text,
useColorModeValue
} from '@chakra-ui/react';
import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard';
import DynamicNewsDetailPanel from '../DynamicNewsDetail';
import PaginationControl from './PaginationControl';
import VirtualizedFourRowGrid from './VirtualizedFourRowGrid';
import PageNavigationButton from './PageNavigationButton';
/**
* 事件列表组件 - 支持纵向和平铺两种展示模式
* @param {Array} events - 当前页的事件列表(服务端已分页)
* @param {Object} selectedEvent - 当前选中的事件
* @param {Function} onEventSelect - 事件选择回调
* @param {string} borderColor - 边框颜色
* @param {number} currentPage - 当前页码
* @param {number} totalPages - 总页数(由服务端返回)
* @param {Function} onPageChange - 页码改变回调
* @param {boolean} loading - 全局加载状态
* @param {number|null} loadingPage - 正在加载的目标页码(用于显示"正在加载第X页..."
* @param {string} mode - 展示模式:'vertical'(纵向分栏)| 'four-row'(平铺网格)
* @param {Function} onModeChange - 模式切换回调
* @param {boolean} hasMore - 是否还有更多数据
* @param {Object} eventFollowStatus - 事件关注状态 { [eventId]: { isFollowing, followerCount } }
* @param {Function} onToggleFollow - 关注按钮回调
*/
const EventScrollList = ({
events,
displayEvents, // 累积显示的事件列表(四排模式用)
isAccumulateMode, // 是否累积模式
loadNextPage, // 加载下一页(无限滚动)
loadPrevPage, // 加载上一页(双向无限滚动)
onFourRowEventClick, // 四排模式事件点击回调(打开弹窗)
selectedEvent,
onEventSelect,
borderColor,
currentPage,
totalPages,
onPageChange,
loading = false,
mode = 'vertical',
onModeChange,
hasMore = true,
eventFollowStatus = {},
onToggleFollow
}) => {
const scrollContainerRef = useRef(null);
// 所有 useColorModeValue 必须在组件顶层调用(不能在条件渲染中)
const timelineBg = useColorModeValue('gray.50', 'gray.700');
const timelineBorderColor = useColorModeValue('gray.400', 'gray.500');
const timelineTextColor = useColorModeValue('blue.600', 'blue.400');
// 滚动条颜色
const scrollbarTrackBg = useColorModeValue('#f1f1f1', '#2D3748');
const scrollbarThumbBg = useColorModeValue('#888', '#4A5568');
const scrollbarThumbHoverBg = useColorModeValue('#555', '#718096');
const getTimelineBoxStyle = () => {
return {
bg: timelineBg,
borderColor: timelineBorderColor,
borderWidth: '2px',
textColor: timelineTextColor,
boxShadow: 'sm',
};
};
return (
<Box>
{/* 顶部控制栏:模式切换按钮(左)+ 分页控制器(右) */}
<Flex justify="space-between" align="center" mb={2}>
{/* 模式切换按钮 */}
<ButtonGroup size="sm" isAttached>
<Button
onClick={() => onModeChange('vertical')}
colorScheme="blue"
variant={mode === 'vertical' ? 'solid' : 'outline'}
>
纵向
</Button>
<Button
onClick={() => onModeChange('four-row')}
colorScheme="blue"
variant={mode === 'four-row' ? 'solid' : 'outline'}
>
平铺
</Button>
</ButtonGroup>
{/* 分页控制器(平铺模式不显示,使用无限滚动) */}
{totalPages > 1 && mode !== 'four-row' && (
<PaginationControl
currentPage={currentPage}
totalPages={totalPages}
onPageChange={onPageChange}
/>
)}
</Flex>
{/* 横向滚动区域 */}
<Box position="relative">
{/* 翻页导航按钮(平铺模式不显示,使用无限滚动) */}
{mode !== 'four-row' && (
<>
<PageNavigationButton
direction="prev"
currentPage={currentPage}
totalPages={totalPages}
onPageChange={onPageChange}
mode={mode}
/>
<PageNavigationButton
direction="next"
currentPage={currentPage}
totalPages={totalPages}
onPageChange={onPageChange}
mode={mode}
/>
</>
)}
{/* 事件卡片容器 */}
<Box
ref={scrollContainerRef}
overflowX="hidden"
overflowY="hidden"
maxH={mode === 'vertical' ? '820px' : 'none'}
pt={0}
pb={4}
px={2}
position="relative"
css={{
// 统一滚动条样式(支持横向和纵向)
'&::-webkit-scrollbar': {
width: '1px',
height: '1px',
},
'&::-webkit-scrollbar-track': {
background: scrollbarTrackBg,
borderRadius: '10px',
},
'&::-webkit-scrollbar-thumb': {
background: scrollbarThumbBg,
borderRadius: '10px',
},
'&::-webkit-scrollbar-thumb:hover': {
background: scrollbarThumbHoverBg,
},
scrollBehavior: 'smooth',
WebkitOverflowScrolling: 'touch',
}}
>
{/* 平铺网格模式 - 使用虚拟滚动 + 双向无限滚动 */}
{mode === 'four-row' && (
<VirtualizedFourRowGrid
events={displayEvents || events} // 使用累积列表(如果有)
selectedEvent={selectedEvent}
onEventSelect={onFourRowEventClick} // 四排模式点击打开弹窗
eventFollowStatus={eventFollowStatus}
onToggleFollow={onToggleFollow}
getTimelineBoxStyle={getTimelineBoxStyle}
borderColor={borderColor}
loadNextPage={loadNextPage} // 加载下一页
loadPrevPage={loadPrevPage} // 加载上一页(双向滚动)
hasMore={hasMore} // 是否还有更多数据
loading={loading} // 加载状态
/>
)}
{/* 模式4: 纵向分栏模式 - 横向布局(时间在左,卡片在右) */}
{mode === 'vertical' && (
<Grid templateColumns="1fr 2fr" gap={6} h="800px">
{/* 左侧:事件列表 (33.3%) - 使用虚拟滚动 + 双向无限滚动 */}
<GridItem>
<VirtualizedFourRowGrid
events={displayEvents || events} // 使用累积列表
columnsPerRow={1} // 单列布局
CardComponent={HorizontalDynamicNewsEventCard} // 使用横向卡片
selectedEvent={selectedEvent}
onEventSelect={onEventSelect}
eventFollowStatus={eventFollowStatus}
onToggleFollow={onToggleFollow}
getTimelineBoxStyle={getTimelineBoxStyle}
borderColor={borderColor}
loadNextPage={loadNextPage} // 支持向下无限滚动
loadPrevPage={loadPrevPage} // 支持向上无限滚动(双向滚动)
hasMore={hasMore}
loading={loading}
/>
</GridItem>
{/* 右侧:事件详情 (66.7%) */}
<GridItem h="100%">
<Box
pl={2}
position="relative"
sx={{
height: '100% !important',
maxHeight: '800px !important',
overflowY: 'scroll !important',
overflowX: 'hidden !important',
'&::-webkit-scrollbar': {
width: '3px',
},
'&::-webkit-scrollbar-track': {
background: scrollbarTrackBg,
borderRadius: '10px',
},
'&::-webkit-scrollbar-thumb': {
background: scrollbarThumbBg,
borderRadius: '10px',
},
'&::-webkit-scrollbar-thumb:hover': {
background: scrollbarThumbHoverBg,
},
}}
>
{selectedEvent ? (
<DynamicNewsDetailPanel event={selectedEvent} />
) : (
<Center h="100%" minH="400px">
<VStack spacing={4}>
<Text fontSize="lg" color="gray.500">
请选择左侧事件查看详情
</Text>
</VStack>
</Center>
)}
</Box>
</GridItem>
</Grid>
)}
</Box>
</Box>
</Box>
);
};
export default EventScrollList;