feat(EventList): 功能增强 - 集成NotificationContext和添加动画

**主要变更**:

1. **集成NotificationContext**:
   - 引入 useNotification hook,替代本地通知权限状态
   - 删除本地 notificationPermission 状态和 useEffect
   - 使用 browserPermission 和 requestBrowserPermission
   - 添加 handlePushToggle 函数处理推送开关切换

2. **添加动画支持**:
   - 从 @emotion/react 引入 keyframes
   - 定义 pulseAnimation 脉冲动画(用于S/A级重要性标签)

3. **添加描述展开状态**:
   - 新增 expandedDescriptions 状态管理

**效果**:
- 推送权限管理更集中统一
- 支持动画效果增强视觉体验
- 为后续UI优化做准备

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-10-27 17:40:51 +08:00
parent 5e4c4e7cea
commit 0e3bdc9b8c

View File

@@ -1,5 +1,6 @@
// src/views/Community/components/EventList.js
import React, { useState, useEffect } from 'react';
import { keyframes } from '@emotion/react';
import {
Box,
VStack,
@@ -57,6 +58,21 @@ import { getApiBase } from '../../../utils/apiConfig';
import { useEventNotifications } from '../../../hooks/useEventNotifications';
import { getImportanceConfig, getAllImportanceLevels } from '../../../constants/importanceLevels';
import { browserNotificationService } from '../../../services/browserNotificationService';
import { useNotification } from '../../../contexts/NotificationContext';
// ========== 动画定义 ==========
// 脉冲动画 - 用于S/A级重要性标签
const pulseAnimation = keyframes`
0% {
box-shadow: 0 0 0 0 rgba(255, 77, 79, 0.7);
}
70% {
box-shadow: 0 0 0 10px rgba(255, 77, 79, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(255, 77, 79, 0);
}
`;
// ========== 工具函数定义在组件外部 ==========
// 涨跌颜色配置中国A股配色红涨绿跌- 分档次显示
@@ -137,19 +153,10 @@ const EventList = ({ events, pagination, onPageChange, onEventClick, onViewDetai
const [followingMap, setFollowingMap] = useState({});
const [followCountMap, setFollowCountMap] = useState({});
const [localEvents, setLocalEvents] = useState(events); // 用于实时更新的本地事件列表
const [notificationPermission, setNotificationPermission] = useState('default');
const [expandedDescriptions, setExpandedDescriptions] = useState({}); // 描述展开状态映射
// 请求浏览器通知权限
useEffect(() => {
const requestPermission = async () => {
if (browserNotificationService.isSupported()) {
const permission = await browserNotificationService.requestPermission();
setNotificationPermission(permission);
logger.info('EventList', '浏览器通知权限状态', { permission });
}
};
requestPermission();
}, []);
// 从 NotificationContext 获取推送权限相关状态和方法
const { browserPermission, requestBrowserPermission } = useNotification();
// 实时事件推送集成
const { isConnected } = useEventNotifications({
@@ -178,9 +185,8 @@ const EventList = ({ events, pagination, onPageChange, onEventClick, onViewDetai
// 发送浏览器原生通知
console.log('[EventList DEBUG] 准备发送浏览器原生通知');
const currentPermission = browserNotificationService.getPermissionStatus();
console.log('[EventList DEBUG] 通知权限状态:', currentPermission);
if (currentPermission === 'granted') {
console.log('[EventList DEBUG] 通知权限状态:', browserPermission);
if (browserPermission === 'granted') {
const importance = getImportanceConfig(event.importance);
const notification = browserNotificationService.sendNotification({
title: `🔔 ${importance.label}级事件`,
@@ -288,6 +294,43 @@ const EventList = ({ events, pagination, onPageChange, onEventClick, onViewDetai
}
};
// 处理推送开关切换
const handlePushToggle = async (e) => {
const isChecked = e.target.checked;
if (isChecked) {
// 用户想开启推送
logger.info('EventList', '用户请求开启推送');
const permission = await requestBrowserPermission();
if (permission === 'denied') {
// 权限被拒绝,显示设置指引
logger.warn('EventList', '用户拒绝了推送权限');
toast({
title: '推送权限被拒绝',
description: '如需开启推送,请在浏览器设置中允许通知权限',
status: 'warning',
duration: 5000,
isClosable: true,
position: 'top',
});
} else if (permission === 'granted') {
logger.info('EventList', '推送权限已授予');
}
} else {
// 用户想关闭推送 - 提示需在浏览器设置中操作
logger.info('EventList', '用户尝试关闭推送');
toast({
title: '关闭推送通知',
description: '如需关闭,请在浏览器设置中撤销通知权限',
status: 'info',
duration: 5000,
isClosable: true,
position: 'top',
});
}
};
// 专业的金融配色方案
const bgColor = useColorModeValue('gray.50', 'gray.900');
const cardBg = useColorModeValue('white', 'gray.800');