Browse Source

feat: prepare for push notification

pull/16/head
hole-thu 3 years ago
parent
commit
c1431ba051
  1. 2
      public/index.html
  2. 3
      src/App.js
  3. 19
      src/Common.js
  4. 24
      src/Flows.js
  5. 27
      src/UserAction.js
  6. 25
      src/service-worker.js

2
public/index.html

@ -68,7 +68,7 @@
<body>
<div id="root">
请开启javascript,或 <a href="#" onClick="force_reload">强制刷新</a>
请开启javascript,或等待资源加载完成,或<a href="#" onClick="force_reload">强制刷新</a>
</div>
</body>
</html>

3
src/App.js

@ -39,6 +39,8 @@ class App extends Component {
window.BACKEND =
localStorage['BACKEND'] || process.env.REACT_APP_BACKEND || '/';
if (process.env.NODE_ENV === 'production') {
setTimeout(() => {
fetch('https://api.github.com/users/hole-thu')
.then((resp) => resp.json())
@ -55,6 +57,7 @@ class App extends Component {
});
}, 12345);
}
}
static is_darkmode() {
if (window.config.color_scheme === 'dark') return true;

19
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

24
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 {
</a>
</span>
)}
{!!this.props.token && !!this.state.attention && (
<span>
<a
href="###"
style={{ display: 'none' }}
onClick={() => {
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),
});
});
}}
>
<span className="icon icon-star">提醒</span>
</a>
</span>
)}
</div>
{!!this.state.filter_name && (
<div className="box box-tip flow-item filter-name-bar">

27
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);
}}
>
强制检查更新
立即更新
</a>
当前版本{process.env.REACT_APP_BUILD_INFO || '---'}{' '}
{process.env.NODE_ENV} 会自动在后台检查更新并在下次访问时更新

25
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);

Loading…
Cancel
Save