From 0e3bdc9b8caaaf776c04d9170a97ca6b57ce3847 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Mon, 27 Oct 2025 17:40:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(EventList):=20=E5=8A=9F=E8=83=BD=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=20-=20=E9=9B=86=E6=88=90NotificationContext=E5=92=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=8A=A8=E7=94=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **主要变更**: 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 --- src/views/Community/components/EventList.js | 73 ++++++++++++++++----- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/src/views/Community/components/EventList.js b/src/views/Community/components/EventList.js index fd3e0497..9a2a4943 100644 --- a/src/views/Community/components/EventList.js +++ b/src/views/Community/components/EventList.js @@ -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');