diff --git a/src/components/Auth/WechatRegister.js b/src/components/Auth/WechatRegister.js
index b5d221e1..d878afaf 100644
--- a/src/components/Auth/WechatRegister.js
+++ b/src/components/Auth/WechatRegister.js
@@ -508,19 +508,19 @@ export default function WechatRegister() {
title="微信扫码登录"
width="300"
height="350"
- scrolling="no" // ✅ 新增:禁止滚动
- // sandbox="allow-scripts allow-same-origin allow-forms" // ✅ 阻止iframe跳转父页面
+ scrolling="no"
+ sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation"
+ allow="clipboard-write"
style={{
border: 'none',
- transform: 'scale(0.77) translateY(-35px)', // ✅ 裁剪顶部logo
+ transform: 'scale(0.77) translateY(-35px)',
transformOrigin: 'top left',
marginLeft: '-5px',
- pointerEvents: 'auto', // 允许点击 │ │
- overflow: 'hidden', // 尝试隐藏滚动条(可能不起作用)
+ pointerEvents: 'auto',
+ overflow: 'hidden',
}}
- // 使用 onWheel 事件阻止滚动 │ │
- onWheel={(e) => e.preventDefault()} // ✅ 在父容器上阻止滚动
- onTouchMove={(e) => e.preventDefault()} // ✅ 移动端也阻止
+ onWheel={(e) => e.preventDefault()}
+ onTouchMove={(e) => e.preventDefault()}
/>
) : (
/* 未获取:显示占位符 */
diff --git a/src/views/Community/components/DynamicNewsCard.js b/src/views/Community/components/DynamicNewsCard.js
index b355e42f..f8d5cbdc 100644
--- a/src/views/Community/components/DynamicNewsCard.js
+++ b/src/views/Community/components/DynamicNewsCard.js
@@ -25,8 +25,12 @@ import {
useColorModeValue,
useToast,
useDisclosure,
+ Switch,
+ Tooltip,
+ Icon,
} from '@chakra-ui/react';
-import { TimeIcon } from '@chakra-ui/icons';
+import { TimeIcon, BellIcon } from '@chakra-ui/icons';
+import { useNotification } from '../../../contexts/NotificationContext';
import EventScrollList from './DynamicNewsCard/EventScrollList';
import ModeToggleButtons from './DynamicNewsCard/ModeToggleButtons';
import PaginationControl from './DynamicNewsCard/PaginationControl';
@@ -73,6 +77,9 @@ const DynamicNewsCard = forwardRef(({
const cardBg = useColorModeValue('white', 'gray.800');
const borderColor = useColorModeValue('gray.200', 'gray.700');
+ // 通知权限相关
+ const { browserPermission, requestBrowserPermission } = useNotification();
+
// 固定模式状态
const [isFixedMode, setIsFixedMode] = useState(false);
const [headerHeight, setHeaderHeight] = useState(0);
@@ -146,6 +153,23 @@ const [currentMode, setCurrentMode] = useState('vertical');
dispatch(toggleEventFollow(eventId));
}, [dispatch]);
+ // 通知开关处理
+ const handleNotificationToggle = useCallback(async () => {
+ if (browserPermission === 'granted') {
+ // 已授权,提示用户去浏览器设置中关闭
+ toast({
+ title: '已开启通知',
+ description: '要关闭通知,请在浏览器地址栏左侧点击锁图标,找到"通知"选项进行设置',
+ status: 'info',
+ duration: 5000,
+ isClosable: true,
+ });
+ } else {
+ // 未授权,请求权限
+ await requestBrowserPermission();
+ }
+ }, [browserPermission, requestBrowserPermission, toast]);
+
// 本地状态
const [selectedEvent, setSelectedEvent] = useState(null);
@@ -511,9 +535,66 @@ const [currentMode, setCurrentMode] = useState('vertical');
快讯
-
- 最后更新: {lastUpdateTime?.toLocaleTimeString() || '未知'}
-
+
+
+ {/* 通知开关 */}
+
+
+
+
+ {browserPermission === 'granted' ? '通知已开启' : '开启通知'}
+
+
+
+
+
+
+ 最后更新: {lastUpdateTime?.toLocaleTimeString() || '未知'}
+
+
{/* 搜索和筛选组件 */}
diff --git a/src/views/Community/index.js b/src/views/Community/index.js
index 8f522468..531d93aa 100644
--- a/src/views/Community/index.js
+++ b/src/views/Community/index.js
@@ -1,5 +1,5 @@
// src/views/Community/index.js
-import React, { useEffect, useRef } from 'react';
+import React, { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import {
@@ -10,6 +10,15 @@ import {
Box,
Container,
useColorModeValue,
+ Alert,
+ AlertIcon,
+ AlertTitle,
+ AlertDescription,
+ Button,
+ CloseButton,
+ HStack,
+ VStack,
+ Text,
} from '@chakra-ui/react';
// 导入组件
@@ -40,7 +49,10 @@ const Community = () => {
const containerRef = useRef(null);
// ⚡ 通知权限引导
- const { showCommunityGuide } = useNotification();
+ const { browserPermission, requestBrowserPermission } = useNotification();
+
+ // 通知横幅显示状态
+ const [showNotificationBanner, setShowNotificationBanner] = useState(false);
// 🎯 初始化Community埋点Hook
const communityEvents = useCommunityEvents({ navigate });
@@ -71,17 +83,38 @@ const Community = () => {
}
}, [events, loading, pagination, filters]);
- // ⚡ 首次访问社区时,延迟显示权限引导
+ // ⚡ 检查通知权限状态,显示横幅提示
useEffect(() => {
- if (showCommunityGuide) {
- const timer = setTimeout(() => {
- logger.info('Community', '显示社区权限引导');
- showCommunityGuide();
- }, 5000); // 延迟 5 秒,让用户先浏览页面
+ // 延迟3秒显示,让用户先浏览页面
+ const timer = setTimeout(() => {
+ // 如果未授权或未请求过权限,显示横幅
+ if (browserPermission !== 'granted') {
+ const hasClosedBanner = localStorage.getItem('notification_banner_closed');
+ if (!hasClosedBanner) {
+ setShowNotificationBanner(true);
+ logger.info('Community', '显示通知权限横幅');
+ }
+ }
+ }, 3000);
- return () => clearTimeout(timer);
+ return () => clearTimeout(timer);
+ }, [browserPermission]);
+
+ // 处理开启通知
+ const handleEnableNotifications = async () => {
+ const permission = await requestBrowserPermission();
+ if (permission === 'granted') {
+ setShowNotificationBanner(false);
+ logger.info('Community', '通知权限已授予');
}
- }, [showCommunityGuide]); // 只在组件挂载时执行一次
+ };
+
+ // 处理关闭横幅
+ const handleCloseBanner = () => {
+ setShowNotificationBanner(false);
+ localStorage.setItem('notification_banner_closed', 'true');
+ logger.info('Community', '通知横幅已关闭');
+ };
// ⚡ 首次进入页面时滚动到内容区域(考虑导航栏高度)
useEffect(() => {
@@ -104,6 +137,42 @@ const Community = () => {
{/* 主内容区域 */}
+ {/* 通知权限提示横幅 */}
+ {showNotificationBanner && (
+
+
+
+
+ 开启桌面通知,不错过重要事件
+
+
+ 即使浏览器最小化,也能第一时间接收新事件推送通知
+
+
+
+
+
+
+
+ )}
{/* 热点事件区域 */}