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:
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user