update ui

This commit is contained in:
2025-11-13 23:06:19 +08:00
parent 6113a3fefd
commit d3b980b3ca
2 changed files with 78 additions and 122 deletions

View File

@@ -146,7 +146,7 @@ const HorizontalDynamicNewsEventCard = ({
>
<CardBody p={3} pb={2}>
{/* 右上角:关注按钮 */}
<Box position="absolute" top={2} right={2} zIndex={1}>
<Box position="absolute" top={2} right={2} zIndex={2}>
<EventFollowButton
isFollowing={isFollowing}
followerCount={followerCount}
@@ -156,6 +156,18 @@ const HorizontalDynamicNewsEventCard = ({
/>
</Box>
{/* Keywords梦幻轮播 - 绝对定位在卡片右侧空白处 */}
{event.keywords && event.keywords.length > 0 && (
<KeywordsCarousel
keywords={event.keywords}
interval={4000}
onKeywordClick={(keyword) => {
console.log('Keyword clicked:', keyword);
// TODO: 实现关键词筛选功能
}}
/>
)}
<VStack align="stretch" spacing={1.5}>
{/* 标题 - 最多两行hover 显示完整内容 */}
<Tooltip
@@ -173,7 +185,7 @@ const HorizontalDynamicNewsEventCard = ({
cursor="pointer"
onClick={(e) => onTitleClick?.(e, event)}
mt={1}
paddingRight="10px"
paddingRight="120px"
>
<Text
fontSize="md"
@@ -188,37 +200,13 @@ const HorizontalDynamicNewsEventCard = ({
</Box>
</Tooltip>
{/* 第二行:涨跌幅数据 + Keywords轮播 */}
<HStack spacing={3} align="center" justify="space-between" w="full">
{/* 左侧:涨跌幅数据 */}
{/* 第二行:涨跌幅数据 */}
<StockChangeIndicators
avgChange={event.related_avg_chg}
maxChange={event.related_max_chg}
weekChange={event.related_week_chg}
size={indicatorSize}
/>
{/* 右侧Keywords轮播半透明效果 */}
{event.keywords && event.keywords.length > 0 && (
<Box
flex="1"
minW={0}
opacity={0.85}
_hover={{ opacity: 1 }}
transition="opacity 0.2s"
>
<KeywordsCarousel
keywords={event.keywords}
displayCount={3}
interval={3500}
onKeywordClick={(keyword) => {
console.log('Keyword clicked:', keyword);
// TODO: 实现关键词筛选功能
}}
/>
</Box>
)}
</HStack>
</VStack>
</CardBody>
</Card>

View File

@@ -1,31 +1,31 @@
// src/views/Community/components/EventCard/KeywordsCarousel.js
// Keywords标签轮播组件
// Keywords标签梦幻淡入淡出轮播组件
import React, { useState, useEffect } from 'react';
import { Box, Tag, HStack, useColorModeValue, Tooltip } from '@chakra-ui/react';
import { Box, Text, useColorModeValue } from '@chakra-ui/react';
import { motion, AnimatePresence } from 'framer-motion';
const MotionBox = motion(Box);
/**
* Keywords标签轮播组件
* Keywords标签梦幻轮播组件(单个显示,淡入淡出)
* @param {Array} keywords - 关键词数组
* @param {number} displayCount - 显示的标签数量默认3个
* @param {number} interval - 轮播间隔毫秒默认3000ms
* @param {number} interval - 轮播间隔毫秒默认4000ms
* @param {Function} onKeywordClick - 关键词点击回调
*/
const KeywordsCarousel = ({
keywords = [],
displayCount = 3,
interval = 3000,
interval = 4000,
onKeywordClick
}) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [isPaused, setIsPaused] = useState(false);
// 颜色配置
const tagBg = useColorModeValue('rgba(66, 153, 225, 0.1)', 'rgba(66, 153, 225, 0.2)');
const tagColor = useColorModeValue('blue.600', 'blue.300');
const tagBorder = useColorModeValue('blue.200', 'blue.600');
// 颜色配置 - 梦幻渐变效果
const textColor = useColorModeValue(
'linear(to-r, purple.400, pink.400, blue.400)',
'linear(to-r, purple.300, pink.300, blue.300)'
);
const hoverBg = useColorModeValue('rgba(159, 122, 234, 0.1)', 'rgba(159, 122, 234, 0.15)');
// 如果没有keywords不渲染
if (!keywords || keywords.length === 0) {
@@ -34,98 +34,66 @@ const KeywordsCarousel = ({
// 自动轮播
useEffect(() => {
if (isPaused || keywords.length <= displayCount) return;
if (isPaused || keywords.length <= 1) return;
const timer = setInterval(() => {
setCurrentIndex((prev) => (prev + 1) % keywords.length);
}, interval);
return () => clearInterval(timer);
}, [isPaused, keywords.length, displayCount, interval]);
}, [isPaused, keywords.length, interval]);
// 获取当前显示的关键词
const getVisibleKeywords = () => {
if (keywords.length <= displayCount) {
return keywords;
}
const visible = [];
for (let i = 0; i < displayCount; i++) {
const index = (currentIndex + i) % keywords.length;
visible.push(keywords[index]);
}
return visible;
};
const visibleKeywords = getVisibleKeywords();
const currentKeyword = keywords[currentIndex];
return (
<Box
onMouseEnter={() => setIsPaused(true)}
onMouseLeave={() => setIsPaused(false)}
position="relative"
>
<HStack spacing={1.5} flexWrap="wrap">
<AnimatePresence mode="wait">
{visibleKeywords.map((keyword, index) => (
<MotionBox
key={`${keyword}-${currentIndex}-${index}`}
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.8 }}
transition={{ duration: 0.3 }}
>
<Tooltip
label={`点击筛选"${keyword}"`}
placement="top"
hasArrow
>
<Tag
size="sm"
variant="subtle"
bg={tagBg}
color={tagColor}
borderWidth="1px"
borderColor={tagBorder}
cursor="pointer"
fontSize="10px"
fontWeight="medium"
px={2}
py={0.5}
borderRadius="full"
_hover={{
bg: useColorModeValue('blue.100', 'blue.700'),
transform: 'scale(1.05)',
boxShadow: 'md'
}}
transition="all 0.2s"
onClick={(e) => {
e.stopPropagation();
onKeywordClick?.(keyword);
}}
>
#{keyword}
</Tag>
</Tooltip>
</MotionBox>
))}
</AnimatePresence>
</HStack>
{/* 如果有更多关键词,显示指示器 */}
{keywords.length > displayCount && (
<Box
position="absolute"
right={-2}
right={4}
top="50%"
transform="translateY(-50%)"
fontSize="10px"
color="gray.400"
fontWeight="bold"
onMouseEnter={() => setIsPaused(true)}
onMouseLeave={() => setIsPaused(false)}
pointerEvents="auto"
zIndex={1}
>
+{keywords.length - displayCount}
</Box>
)}
<AnimatePresence mode="wait">
<MotionBox
key={`keyword-${currentKeyword}-${currentIndex}`}
initial={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}
animate={{ opacity: 1, scale: 1, filter: 'blur(0px)' }}
exit={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}
transition={{
duration: 0.8,
ease: [0.4, 0, 0.2, 1]
}}
cursor="pointer"
onClick={(e) => {
e.stopPropagation();
onKeywordClick?.(currentKeyword);
}}
px={3}
py={1.5}
borderRadius="full"
bg="transparent"
_hover={{
bg: hoverBg,
transform: 'scale(1.05)',
}}
transition="background 0.3s, transform 0.2s"
>
<Text
bgGradient={textColor}
bgClip="text"
fontSize="md"
fontWeight="bold"
letterSpacing="wide"
whiteSpace="nowrap"
textShadow="0 0 20px rgba(159, 122, 234, 0.3)"
>
{currentKeyword}
</Text>
</MotionBox>
</AnimatePresence>
</Box>
);
};