Commit 3aa50319 authored by xiaoiver's avatar xiaoiver Committed by 陈帅

feat: support PWA features (#2816)

* feat: support PWA features

* fix: move to global.js
parent 2399fb31
...@@ -23,6 +23,12 @@ const plugins = [ ...@@ -23,6 +23,12 @@ const plugins = [
dynamicImport: { dynamicImport: {
loadingComponent: './components/PageLoading/index', loadingComponent: './components/PageLoading/index',
}, },
pwa: {
workboxPluginMode: 'InjectManifest',
workboxOptions: {
importWorkboxFrom: 'local',
},
},
...(!process.env.TEST && os.platform() === 'darwin' ...(!process.env.TEST && os.platform() === 'darwin'
? { ? {
dll: { dll: {
......
import { Modal, message } from 'antd';
import { formatMessage } from 'umi/locale';
// Notify user if offline now
window.addEventListener('sw.offline', () => {
message.warning(formatMessage({ id: 'app.pwa.offline' }));
});
// Pop up a prompt on the page asking the user if they want to use the latest version
window.addEventListener('sw.updated', e => {
Modal.confirm({
title: formatMessage({ id: 'app.pwa.serviceworker.updated' }),
content: formatMessage({ id: 'app.pwa.serviceworker.updated.hint' }),
okText: formatMessage({ id: 'app.pwa.serviceworker.updated.ok' }),
onOk: async () => {
// Check if there is sw whose state is waiting in ServiceWorkerRegistration
// https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
const worker = e.detail && e.detail.waiting;
if (!worker) {
return Promise.resolve();
}
// Send skip-waiting event to waiting SW with MessageChannel
await new Promise((resolve, reject) => {
const channel = new MessageChannel();
channel.port1.onmessage = event => {
if (event.data.error) {
reject(event.data.error);
} else {
resolve(event.data);
}
};
worker.postMessage({ type: 'skip-waiting' }, [channel.port2]);
});
// Refresh current page to use the updated HTML and other assets after SW has skiped waiting
window.location.reload(true);
return true;
},
});
});
...@@ -180,11 +180,11 @@ class BasicLayout extends React.PureComponent { ...@@ -180,11 +180,11 @@ class BasicLayout extends React.PureComponent {
if (!currRouterData) { if (!currRouterData) {
return 'Ant Design Pro'; return 'Ant Design Pro';
} }
const message = formatMessage({ const pageName = formatMessage({
id: currRouterData.locale || currRouterData.name, id: currRouterData.locale || currRouterData.name,
defaultMessage: currRouterData.name, defaultMessage: currRouterData.name,
}); });
return `${message} - Ant Design Pro`; return `${pageName} - Ant Design Pro`;
}; };
getLayoutStyle = () => { getLayoutStyle = () => {
......
...@@ -8,6 +8,7 @@ import monitor from './en-US/monitor'; ...@@ -8,6 +8,7 @@ import monitor from './en-US/monitor';
import result from './en-US/result'; import result from './en-US/result';
import settingDrawer from './en-US/settingDrawer'; import settingDrawer from './en-US/settingDrawer';
import settings from './en-US/settings'; import settings from './en-US/settings';
import pwa from './en-US/pwa';
export default { export default {
'navBar.lang': 'Languages', 'navBar.lang': 'Languages',
...@@ -28,4 +29,5 @@ export default { ...@@ -28,4 +29,5 @@ export default {
...result, ...result,
...settingDrawer, ...settingDrawer,
...settings, ...settings,
...pwa,
}; };
export default {
'app.pwa.offline': 'You are offline now',
'app.pwa.serviceworker.updated': 'New content is available',
'app.pwa.serviceworker.updated.hint': 'Please press the "Refresh" button to reload current page',
'app.pwa.serviceworker.updated.ok': 'Refresh',
};
...@@ -8,6 +8,7 @@ import monitor from './pt-BR/monitor'; ...@@ -8,6 +8,7 @@ import monitor from './pt-BR/monitor';
import result from './pt-BR/result'; import result from './pt-BR/result';
import settingDrawer from './pt-BR/settingDrawer'; import settingDrawer from './pt-BR/settingDrawer';
import settings from './pt-BR/settings'; import settings from './pt-BR/settings';
import pwa from './pt-BR/pwa';
export default { export default {
'navBar.lang': 'Idiomas', 'navBar.lang': 'Idiomas',
...@@ -28,4 +29,5 @@ export default { ...@@ -28,4 +29,5 @@ export default {
...result, ...result,
...settingDrawer, ...settingDrawer,
...settings, ...settings,
...pwa,
}; };
export default {
'app.pwa.offline': 'Você está offline agora',
'app.pwa.serviceworker.updated': 'Novo conteúdo está disponível',
'app.pwa.serviceworker.updated.hint':
'Por favor, pressione o botão "Atualizar" para recarregar a página atual',
'app.pwa.serviceworker.updated.ok': 'Atualizar',
};
...@@ -8,6 +8,7 @@ import monitor from './zh-CN/monitor'; ...@@ -8,6 +8,7 @@ import monitor from './zh-CN/monitor';
import result from './zh-CN/result'; import result from './zh-CN/result';
import settingDrawer from './zh-CN/settingDrawer'; import settingDrawer from './zh-CN/settingDrawer';
import settings from './zh-CN/settings'; import settings from './zh-CN/settings';
import pwa from './zh-CN/pwa';
export default { export default {
'navBar.lang': '语言', 'navBar.lang': '语言',
...@@ -28,4 +29,5 @@ export default { ...@@ -28,4 +29,5 @@ export default {
...result, ...result,
...settingDrawer, ...settingDrawer,
...settings, ...settings,
...pwa,
}; };
export default {
'app.pwa.offline': '当前处于离线状态',
'app.pwa.serviceworker.updated': '有新内容',
'app.pwa.serviceworker.updated.hint': '请点击“刷新”按钮或者手动刷新页面',
'app.pwa.serviceworker.updated.ok': '刷新',
};
...@@ -8,6 +8,7 @@ import monitor from './zh-TW/monitor'; ...@@ -8,6 +8,7 @@ import monitor from './zh-TW/monitor';
import result from './zh-TW/result'; import result from './zh-TW/result';
import settingDrawer from './zh-TW/settingDrawer'; import settingDrawer from './zh-TW/settingDrawer';
import settings from './zh-TW/settings'; import settings from './zh-TW/settings';
import pwa from './zh-TW/pwa';
export default { export default {
'navBar.lang': '語言', 'navBar.lang': '語言',
...@@ -28,4 +29,5 @@ export default { ...@@ -28,4 +29,5 @@ export default {
...result, ...result,
...settingDrawer, ...settingDrawer,
...settings, ...settings,
...pwa,
}; };
export default {
'app.pwa.offline': '當前處於離線狀態',
'app.pwa.serviceworker.updated': '有新內容',
'app.pwa.serviceworker.updated.hint': '請點擊“刷新”按鈕或者手動刷新頁面',
'app.pwa.serviceworker.updated.ok': '刷新',
};
{
"name": "ant-design-pro",
"short_name": "antd-pro",
"display": "standalone",
"start_url": "./?utm_source=homescreen",
"theme_color": "#002140",
"background_color": "#001529",
"icons": [
{
"src": "icons/icon-192x192.png",
"sizes": "192x192"
},{
"src": "icons/icon-128x128.png",
"sizes": "128x128"
}
]
}
\ No newline at end of file
...@@ -30,7 +30,7 @@ export default { ...@@ -30,7 +30,7 @@ export default {
if (redirectUrlParams.origin === urlParams.origin) { if (redirectUrlParams.origin === urlParams.origin) {
redirect = redirect.substr(urlParams.origin.length); redirect = redirect.substr(urlParams.origin.length);
if (redirect.match(/^\/.*#/)) { if (redirect.match(/^\/.*#/)) {
redirect = redirect.substr(redirect.indexOf('#')+1); redirect = redirect.substr(redirect.indexOf('#') + 1);
} }
} else { } else {
window.location.href = redirect; window.location.href = redirect;
......
/* globals workbox */
/* eslint-disable no-restricted-globals */
workbox.core.setCacheNameDetails({
prefix: 'antd-pro',
suffix: 'v1',
});
// Control all opened tabs ASAP
workbox.clientsClaim();
/**
* Use precaching list generated by workbox in build process.
* https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.precaching
*/
/* eslint-disable no-underscore-dangle */
workbox.precaching.precacheAndRoute(self.__precacheManifest || []);
/**
* Register a navigation route.
* https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route
*/
workbox.routing.registerNavigationRoute('/index.html');
/**
* Use runtime cache:
* https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.routing#.registerRoute
*
* Workbox provides all common caching strategies including CacheFirst, NetworkFirst etc.
* https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.strategies
*/
/**
* Handle API requests
*/
workbox.routing.registerRoute(/\/api\//, workbox.strategies.networkFirst());
/**
* Handle third party requests
*/
workbox.routing.registerRoute(
/^https:\/\/gw.alipayobjects.com\//,
workbox.strategies.networkFirst()
);
workbox.routing.registerRoute(
/^https:\/\/cdnjs.cloudflare.com\//,
workbox.strategies.networkFirst()
);
workbox.routing.registerRoute(/\/color.less/, workbox.strategies.networkFirst());
/**
* Response to client after skipping waiting with MessageChannel
*/
addEventListener('message', event => {
const replyPort = event.ports[0];
const message = event.data;
if (replyPort && message && message.type === 'skip-waiting') {
event.waitUntil(
self
.skipWaiting()
.then(
() => replyPort.postMessage({ error: null }),
error => replyPort.postMessage({ error })
)
);
}
});
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment