feat: 优化社区页面滚动和分页交互体验…)
⎿ [feature_2025/1028_event 5dedbb3] feat: 优化社区页面滚动和分页交互体验
6 files changed, 1355 insertions(+), 49 deletions(-)
create mode 100644 docs/test-cases/Community351241265351235242346265213350257225347224250344276213.md
This commit is contained in:
@@ -72,8 +72,8 @@ const DynamicNewsCard = forwardRef(({
|
||||
// 发起 Redux action 获取新页面数据
|
||||
dispatch(fetchDynamicNews({ page: newPage, per_page: pageSize }));
|
||||
|
||||
// 重置选中事件(等新数据加载后自动选中第一个)
|
||||
setSelectedEvent(null);
|
||||
// 保持当前选中事件,避免详情面板消失导致页面抖动
|
||||
// 新数据加载完成后,useEffect 会自动选中第一个事件
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -112,27 +112,8 @@ const DynamicNewsCard = forwardRef(({
|
||||
|
||||
{/* 主体内容 */}
|
||||
<CardBody position="relative">
|
||||
{/* Loading 状态 */}
|
||||
{loading && (
|
||||
<Center py={10}>
|
||||
<VStack>
|
||||
<Spinner size="xl" color="blue.500" thickness="4px" />
|
||||
<Text color="gray.500">正在加载最新事件...</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
)}
|
||||
|
||||
{/* Empty 状态 */}
|
||||
{!loading && (!events || events.length === 0) && (
|
||||
<Center py={10}>
|
||||
<VStack>
|
||||
<Text fontSize="lg" color="gray.500">暂无事件数据</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
)}
|
||||
|
||||
{/* 横向滚动事件列表 */}
|
||||
{!loading && events && events.length > 0 && (
|
||||
{/* 横向滚动事件列表 - 始终渲染(除非为空) */}
|
||||
{events && events.length > 0 ? (
|
||||
<EventScrollList
|
||||
events={events}
|
||||
selectedEvent={selectedEvent}
|
||||
@@ -141,11 +122,27 @@ const DynamicNewsCard = forwardRef(({
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={handlePageChange}
|
||||
loading={loading}
|
||||
/>
|
||||
) : !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>
|
||||
)}
|
||||
|
||||
{/* 详情面板 */}
|
||||
{!loading && events && events.length > 0 && (
|
||||
{/* 详情面板 - 始终显示(如果有选中事件) */}
|
||||
{events && events.length > 0 && selectedEvent && (
|
||||
<Box mt={6}>
|
||||
<DynamicNewsDetailPanel event={selectedEvent} />
|
||||
</Box>
|
||||
|
||||
@@ -6,6 +6,10 @@ import {
|
||||
Box,
|
||||
Flex,
|
||||
IconButton,
|
||||
Center,
|
||||
VStack,
|
||||
Spinner,
|
||||
Text,
|
||||
useColorModeValue
|
||||
} from '@chakra-ui/react';
|
||||
import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons';
|
||||
@@ -21,6 +25,7 @@ import PaginationControl from './PaginationControl';
|
||||
* @param {number} currentPage - 当前页码
|
||||
* @param {number} totalPages - 总页数(由服务端返回)
|
||||
* @param {Function} onPageChange - 页码改变回调
|
||||
* @param {boolean} loading - 加载状态
|
||||
*/
|
||||
const EventScrollList = ({
|
||||
events,
|
||||
@@ -29,7 +34,8 @@ const EventScrollList = ({
|
||||
borderColor,
|
||||
currentPage,
|
||||
totalPages,
|
||||
onPageChange
|
||||
onPageChange,
|
||||
loading = false
|
||||
}) => {
|
||||
const scrollContainerRef = useRef(null);
|
||||
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
||||
@@ -89,17 +95,6 @@ const EventScrollList = ({
|
||||
|
||||
return (
|
||||
<Box>
|
||||
{/* 分页控制器 - 右上角 */}
|
||||
{totalPages > 1 && (
|
||||
<Flex justify="flex-end" mb={3}>
|
||||
<PaginationControl
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={onPageChange}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
|
||||
{/* 横向滚动区域 */}
|
||||
<Box position="relative">
|
||||
{/* 左侧滚动按钮 */}
|
||||
@@ -149,6 +144,7 @@ const EventScrollList = ({
|
||||
py={4}
|
||||
px={2}
|
||||
onScroll={handleScroll}
|
||||
position="relative"
|
||||
css={{
|
||||
'&::-webkit-scrollbar': {
|
||||
height: '8px',
|
||||
@@ -170,6 +166,29 @@ const EventScrollList = ({
|
||||
WebkitOverflowScrolling: 'touch',
|
||||
}}
|
||||
>
|
||||
{/* 加载遮罩 */}
|
||||
{loading && (
|
||||
<Center
|
||||
position="absolute"
|
||||
top={0}
|
||||
left={0}
|
||||
right={0}
|
||||
bottom={0}
|
||||
bg={useColorModeValue('whiteAlpha.800', 'blackAlpha.700')}
|
||||
backdropFilter="blur(2px)"
|
||||
zIndex={10}
|
||||
borderRadius="md"
|
||||
>
|
||||
<VStack>
|
||||
<Spinner size="lg" color="blue.500" thickness="3px" />
|
||||
<Text fontSize="sm" color={useColorModeValue('gray.600', 'gray.300')}>
|
||||
加载中...
|
||||
</Text>
|
||||
</VStack>
|
||||
</Center>
|
||||
)}
|
||||
|
||||
{/* 事件卡片列表 */}
|
||||
{events.map((event, index) => (
|
||||
<Box
|
||||
key={event.id}
|
||||
@@ -199,6 +218,17 @@ const EventScrollList = ({
|
||||
))}
|
||||
</Flex>
|
||||
</Box>
|
||||
|
||||
{/* 分页控制器 - 右下角 */}
|
||||
{totalPages > 1 && (
|
||||
<Flex justify="flex-end" mt={3}>
|
||||
<PaginationControl
|
||||
currentPage={currentPage}
|
||||
totalPages={totalPages}
|
||||
onPageChange={onPageChange}
|
||||
/>
|
||||
</Flex>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user