diff --git a/public/service-worker.js b/public/service-worker.js new file mode 100644 index 00000000..6dd051da --- /dev/null +++ b/public/service-worker.js @@ -0,0 +1,92 @@ +// public/service-worker.js +/** + * Service Worker for Browser Notifications + * 主要功能:支持浏览器通知的稳定运行 + */ + +const CACHE_NAME = 'valuefrontier-v1'; + +// Service Worker 安装事件 +self.addEventListener('install', (event) => { + console.log('[Service Worker] Installing...'); + // 跳过等待,立即激活 + self.skipWaiting(); +}); + +// Service Worker 激活事件 +self.addEventListener('activate', (event) => { + console.log('[Service Worker] Activating...'); + // 立即接管所有页面 + event.waitUntil(self.clients.claim()); +}); + +// 通知点击事件 +self.addEventListener('notificationclick', (event) => { + console.log('[Service Worker] Notification clicked:', event.notification.tag); + + event.notification.close(); + + // 获取通知数据中的链接 + const urlToOpen = event.notification.data?.link; + + if (urlToOpen) { + event.waitUntil( + clients.matchAll({ type: 'window', includeUncontrolled: true }) + .then((windowClients) => { + // 查找是否已有打开的窗口 + for (let client of windowClients) { + if (client.url.includes(window.location.origin) && 'focus' in client) { + // 聚焦现有窗口并导航到目标页面 + return client.focus().then(client => { + return client.navigate(urlToOpen); + }); + } + } + // 如果没有打开的窗口,打开新窗口 + if (clients.openWindow) { + return clients.openWindow(urlToOpen); + } + }) + ); + } +}); + +// 通知关闭事件 +self.addEventListener('notificationclose', (event) => { + console.log('[Service Worker] Notification closed:', event.notification.tag); +}); + +// Fetch 事件 - 基础的网络优先策略 +self.addEventListener('fetch', (event) => { + // 对于通知相关的资源,使用网络优先策略 + event.respondWith( + fetch(event.request) + .catch(() => { + // 网络失败时,尝试从缓存获取 + return caches.match(event.request); + }) + ); +}); + +// 推送消息事件(预留,用于未来的 Push API 集成) +self.addEventListener('push', (event) => { + console.log('[Service Worker] Push message received:', event); + + if (event.data) { + const data = event.data.json(); + const options = { + body: data.body || '您有新消息', + icon: data.icon || '/favicon.png', + badge: '/favicon.png', + data: data.data || {}, + requireInteraction: data.requireInteraction || false, + tag: data.tag || `notification_${Date.now()}`, + }; + + event.waitUntil( + self.registration.showNotification(data.title || '价值前沿', options) + ); + } +}); + +console.log('[Service Worker] Loaded successfully'); diff --git a/src/index.js b/src/index.js index 33162ea0..9e77e897 100755 --- a/src/index.js +++ b/src/index.js @@ -11,6 +11,40 @@ import './styles/brainwave-colors.css'; // Import the main App component import App from './App'; +// 注册 Service Worker(用于支持浏览器通知) +function registerServiceWorker() { + // 仅在支持 Service Worker 的浏览器中注册 + if ('serviceWorker' in navigator) { + // 在页面加载完成后注册 + window.addEventListener('load', () => { + navigator.serviceWorker + .register('/service-worker.js') + .then((registration) => { + console.log('[App] Service Worker registered successfully:', registration.scope); + + // 监听更新 + registration.addEventListener('updatefound', () => { + const newWorker = registration.installing; + console.log('[App] Service Worker update found'); + + if (newWorker) { + newWorker.addEventListener('statechange', () => { + if (newWorker.state === 'activated') { + console.log('[App] Service Worker activated'); + } + }); + } + }); + }) + .catch((error) => { + console.error('[App] Service Worker registration failed:', error); + }); + }); + } else { + console.warn('[App] Service Worker is not supported in this browser'); + } +} + // 启动 Mock Service Worker(如果启用) async function startApp() { // 只在开发环境启动 MSW @@ -35,6 +69,9 @@ async function startApp() { ); + + // 注册 Service Worker + registerServiceWorker(); } // 启动应用