global.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import { Button, message, notification } from 'antd';
  2. import { useIntl } from 'umi';
  3. import defaultSettings from '../config/defaultSettings';
  4. const { pwa } = defaultSettings;
  5. const isHttps = document.location.protocol === 'https:';
  6. const clearCache = () => {
  7. // remove all caches
  8. if (window.caches) {
  9. caches
  10. .keys()
  11. .then((keys) => {
  12. keys.forEach((key) => {
  13. caches.delete(key);
  14. });
  15. })
  16. .catch((e) => console.log(e));
  17. }
  18. };
  19. // if pwa is true
  20. if (pwa) {
  21. // Notify user if offline now
  22. window.addEventListener('sw.offline', () => {
  23. message.warning(useIntl().formatMessage({ id: 'app.pwa.offline' }));
  24. });
  25. // Pop up a prompt on the page asking the user if they want to use the latest version
  26. window.addEventListener('sw.updated', (event: Event) => {
  27. const e = event as CustomEvent;
  28. const reloadSW = async () => {
  29. // Check if there is sw whose state is waiting in ServiceWorkerRegistration
  30. // https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
  31. const worker = e.detail && e.detail.waiting;
  32. if (!worker) {
  33. return true;
  34. }
  35. // Send skip-waiting event to waiting SW with MessageChannel
  36. await new Promise((resolve, reject) => {
  37. const channel = new MessageChannel();
  38. channel.port1.onmessage = (msgEvent) => {
  39. if (msgEvent.data.error) {
  40. reject(msgEvent.data.error);
  41. } else {
  42. resolve(msgEvent.data);
  43. }
  44. };
  45. worker.postMessage({ type: 'skip-waiting' }, [channel.port2]);
  46. });
  47. clearCache();
  48. window.location.reload();
  49. return true;
  50. };
  51. const key = `open${Date.now()}`;
  52. const btn = (
  53. <Button
  54. type="primary"
  55. onClick={() => {
  56. notification.close(key);
  57. reloadSW();
  58. }}
  59. >
  60. {useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.ok' })}
  61. </Button>
  62. );
  63. notification.open({
  64. message: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated' }),
  65. description: useIntl().formatMessage({ id: 'app.pwa.serviceworker.updated.hint' }),
  66. btn,
  67. key,
  68. onClose: async () => null,
  69. });
  70. });
  71. } else if ('serviceWorker' in navigator && isHttps) {
  72. // unregister service worker
  73. const { serviceWorker } = navigator;
  74. if (serviceWorker.getRegistrations) {
  75. serviceWorker.getRegistrations().then((sws) => {
  76. sws.forEach((sw) => {
  77. sw.unregister();
  78. });
  79. });
  80. }
  81. serviceWorker.getRegistration().then((sw) => {
  82. if (sw) sw.unregister();
  83. });
  84. clearCache();
  85. }