diff --git a/public/index.html b/public/index.html index 7d89479..b43bad0 100644 --- a/public/index.html +++ b/public/index.html @@ -68,7 +68,7 @@
- 请开启javascript,或 强制刷新 + 请开启javascript,或等待资源加载完成,或强制刷新
diff --git a/src/App.js b/src/App.js index fe81aef..a117bef 100644 --- a/src/App.js +++ b/src/App.js @@ -39,21 +39,24 @@ class App extends Component { window.BACKEND = localStorage['BACKEND'] || process.env.REACT_APP_BACKEND || '/'; - setTimeout(() => { - fetch('https://api.github.com/users/hole-thu') - .then((resp) => resp.json()) - .then((data) => { - let x = data.bio; - let len = x.length; - let address = atob( - Array.from({ length: len }, (_, i) => x[(i * 38) % len]) - .join('') - .split('|')[0], - ); - window.BACKEND = `https://${address}/`; - localStorage['BACKEND'] = window.BACKEND; - }); - }, 12345); + + if (process.env.NODE_ENV === 'production') { + setTimeout(() => { + fetch('https://api.github.com/users/hole-thu') + .then((resp) => resp.json()) + .then((data) => { + let x = data.bio; + let len = x.length; + let address = atob( + Array.from({ length: len }, (_, i) => x[(i * 38) % len]) + .join('') + .split('|')[0], + ); + window.BACKEND = `https://${address}/`; + localStorage['BACKEND'] = window.BACKEND; + }); + }, 12345); + } } static is_darkmode() { diff --git a/src/Common.js b/src/Common.js index 97fdbec..8304e7b 100644 --- a/src/Common.js +++ b/src/Common.js @@ -14,6 +14,9 @@ import renderMd from './Markdown'; export { format_time, Time, TitleLine }; +const pushServerPublicKey = + 'BLM6zZy2CWlsfQ9KsALDgrjPXBf8E3cJ7qQ5vZipN_IjOfeDXFjeYb_zRLzwglyiwr9QpVL9Lt1TS_sZKewJYuY'; + export const STORAGE_BASE = `${process.env.REACT_APP_STORAGE || '/'}`; export function get_api_base() { @@ -24,6 +27,22 @@ export function get_api_base_2() { return `${window.BACKEND}_api/v2`; } +export async function get_push_subscription() { + if (!('serviceWorker' in navigator)) return; + let serviceWorker = await navigator.serviceWorker.ready; + if (!('pushManager' in serviceWorker)) return; + let subscription = await serviceWorker.pushManager.getSubscription(); + //subscription.unsubscribe(); + if (!subscription) { + subscription = await serviceWorker.pushManager.subscribe({ + userVisibleOnly: true, + applicationServerKey: pushServerPublicKey, + }); + } + console.log('subscription:', JSON.stringify(subscription)); + return subscription; +} + // https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex function escape_regex(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string diff --git a/src/Flows.js b/src/Flows.js index b0e23b7..bb09507 100644 --- a/src/Flows.js +++ b/src/Flows.js @@ -9,6 +9,7 @@ import { ClickHandler, ColoredSpan, HighlightedMarkdown, + get_push_subscription, } from './Common'; import './Flows.css'; import LazyLoad, { forceCheck } from 'react-lazyload'; @@ -749,6 +750,29 @@ class FlowSidebar extends PureComponent { )} + {!!this.props.token && !!this.state.attention && ( + + { + console.log('set notifi'); + get_push_subscription().then((sc) => { + if (!sc) return; + fetch('/_test', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(sc), + }); + }); + }} + > + 提醒 + + + )} {!!this.state.filter_name && (
diff --git a/src/UserAction.js b/src/UserAction.js index 8bee06e..e3f7250 100644 --- a/src/UserAction.js +++ b/src/UserAction.js @@ -61,22 +61,27 @@ export function InfoSidebar(props) { href="###" onClick={() => { if ('serviceWorker' in navigator) { - navigator.serviceWorker - .getRegistrations() - .then((registrations) => { - for (let registration of registrations) { - console.log('unregister', registration); - registration.unregister(); - } - }); + navigator.serviceWorker.ready.then((serviceWorker) => { + const waitingServiceWorker = serviceWorker.waiting; + if (waitingServiceWorker) { + cache().clear(); + waitingServiceWorker.addEventListener( + 'statechange', + (event) => { + if (event.target.state === 'activated') { + window.location.reload(); + } + }, + ); + waitingServiceWorker.postMessage({ type: 'SKIP_WAITING' }); + } else { + alert('没有已下载的更新'); + } + }); } - cache().clear(); - setTimeout(() => { - window.location.reload(true); - }, 200); }} > - 强制检查更新 + 立即更新 (当前版本:【{process.env.REACT_APP_BUILD_INFO || '---'}{' '} {process.env.NODE_ENV}】 会自动在后台检查更新并在下次访问时更新) diff --git a/src/service-worker.js b/src/service-worker.js index c1566b0..ce08057 100644 --- a/src/service-worker.js +++ b/src/service-worker.js @@ -71,3 +71,28 @@ self.addEventListener('message', (event) => { }); // Any other custom service worker logic can go here. +function receivePushNotification(event) { + console.log('[Service Worker] Push Received.'); + + const { title, pid, text } = event.data.json(); + + const options = { + data: `${self.location.origin}/##${pid}`, + body: text, + }; + + event.waitUntil(self.registration.showNotification(title, options)); +} + +function openPushNotification(event) { + console.log( + '[Service Worker] Notification click Received.', + event.notification.data, + ); + + event.notification.close(); + event.waitUntil(self.clients.openWindow(event.notification.data)); +} + +self.addEventListener('push', receivePushNotification); +self.addEventListener('notificationclick', openPushNotification);