问题: - 事件列表组件包含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>
255 lines
8.9 KiB
JavaScript
255 lines
8.9 KiB
JavaScript
// 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;
|