diff options
author | crupest <crupest@outlook.com> | 2020-06-12 15:42:08 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-06-12 15:42:08 +0800 |
commit | 45993fadcc7a4e40acfb75bd0baa19c1354395da (patch) | |
tree | 08e716275442f530382735480159926dd51c7fcc | |
parent | 1f6c3002791a0d4399171e87f3eeb9df0cce930a (diff) | |
download | timeline-45993fadcc7a4e40acfb75bd0baa19c1354395da.tar.gz timeline-45993fadcc7a4e40acfb75bd0baa19c1354395da.tar.bz2 timeline-45993fadcc7a4e40acfb75bd0baa19c1354395da.zip |
feat(front): 2 enhance on app upgrade.
1. Other pages show alert to refresh when a page confirm upgrade.
2. Upgrade success alert.
-rw-r--r-- | Timeline/ClientApp/src/app/App.tsx | 10 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/locales/en/translation.ts | 11 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/locales/scheme.ts | 5 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/locales/zh/translation.ts | 8 | ||||
-rw-r--r-- | Timeline/ClientApp/src/app/service-worker.tsx | 63 |
5 files changed, 72 insertions, 25 deletions
diff --git a/Timeline/ClientApp/src/app/App.tsx b/Timeline/ClientApp/src/app/App.tsx index befa2a9c..83ea4ea5 100644 --- a/Timeline/ClientApp/src/app/App.tsx +++ b/Timeline/ClientApp/src/app/App.tsx @@ -40,7 +40,7 @@ const App: React.FC = () => { body = <LoadingPage />; } else { body = ( - <React.Suspense fallback={<LoadingPage />}> + <Router> <Switch> <Route exact path="/"> <Home /> @@ -69,15 +69,15 @@ const App: React.FC = () => { <NoMatch /> </Route> </Switch> - </React.Suspense> + </Router> ); } return ( - <> - <Router>{body}</Router> + <React.Suspense fallback={<LoadingPage />}> + {body} <AlertHost /> - </> + </React.Suspense> ); }; diff --git a/Timeline/ClientApp/src/app/locales/en/translation.ts b/Timeline/ClientApp/src/app/locales/en/translation.ts index b9fa42c9..6bac41f9 100644 --- a/Timeline/ClientApp/src/app/locales/en/translation.ts +++ b/Timeline/ClientApp/src/app/locales/en/translation.ts @@ -5,9 +5,14 @@ const translation: TranslationResource = { search: 'Search', serviceWorker: { availableOffline: - 'This app will be cached in your computer and you can use it offline.', - upgradeTitle: 'App is getting a new version!', - upgradeNow: 'Upgrade Now', + 'Timeline is now cached in your computer and you can use it offline. 🎉🎉🎉', + upgradePrompt: 'App is getting a new version!', + upgradeNow: 'Update Now', + upgradeSuccess: + 'Congratulations! App update succeeded! Still you can use it offline. 🎉🎉🎉', + externalActivatedPrompt: + 'A new version of app is activated. Please refresh the page. Or it may be broken.', + reloadNow: 'Refresh Now', }, nav: { settings: 'Settings', diff --git a/Timeline/ClientApp/src/app/locales/scheme.ts b/Timeline/ClientApp/src/app/locales/scheme.ts index 0a8ce278..13d555d5 100644 --- a/Timeline/ClientApp/src/app/locales/scheme.ts +++ b/Timeline/ClientApp/src/app/locales/scheme.ts @@ -5,8 +5,11 @@ export default interface TranslationResource { loadImageError: string; serviceWorker: { availableOffline: string; - upgradeTitle: string; + upgradePrompt: string; upgradeNow: string; + upgradeSuccess: string; + externalActivatedPrompt: string; + reloadNow: string; }; nav: { settings: string; diff --git a/Timeline/ClientApp/src/app/locales/zh/translation.ts b/Timeline/ClientApp/src/app/locales/zh/translation.ts index 03fb470a..fba06c7f 100644 --- a/Timeline/ClientApp/src/app/locales/zh/translation.ts +++ b/Timeline/ClientApp/src/app/locales/zh/translation.ts @@ -4,9 +4,13 @@ const translation: TranslationResource = { welcome: '欢迎!', search: '搜索', serviceWorker: { - availableOffline: '这个 App 将会缓存在本地,你将可以离线使用它。', - upgradeTitle: 'App 有新版本!', + availableOffline: 'Timeline 已经缓存在本地,你可以离线使用它。🎉🎉🎉', + upgradePrompt: 'App 有新版本!', upgradeNow: '现在升级', + upgradeSuccess: 'App 升级成功,当然,你仍可以离线使用它。 🎉🎉🎉', + externalActivatedPrompt: + '一个新的 App 版本已经激活,请刷新页面使用,否则页面可能会出现故障。', + reloadNow: '立刻刷新', }, nav: { settings: '设置', diff --git a/Timeline/ClientApp/src/app/service-worker.tsx b/Timeline/ClientApp/src/app/service-worker.tsx index ca59445e..0dbab480 100644 --- a/Timeline/ClientApp/src/app/service-worker.tsx +++ b/Timeline/ClientApp/src/app/service-worker.tsx @@ -1,16 +1,60 @@ import React from 'react'; -import { WorkboxLifecycleEvent } from 'workbox-window/utils/WorkboxEvent'; import { Button } from 'reactstrap'; import { useTranslation } from 'react-i18next'; import { pushAlert } from './common/alert-service'; if ('serviceWorker' in navigator) { + let isThisTriggerUpgrade = false; + + const upgradeSuccessLocalStorageKey = 'TIMELINE_UPGRADE_SUCCESS'; + + if (window.localStorage.getItem(upgradeSuccessLocalStorageKey)) { + pushAlert({ + message: { + type: 'i18n', + key: 'serviceWorker.upgradeSuccess', + }, + type: 'success', + }); + window.localStorage.removeItem(upgradeSuccessLocalStorageKey); + } + void import('workbox-window').then(({ Workbox, messageSW }) => { const wb = new Workbox('/sw.js'); let registration: ServiceWorkerRegistration | undefined; - const showFirstPrompt = (event: WorkboxLifecycleEvent): void => { + // externalactivated is not usable but I still use its name. + wb.addEventListener('controlling', () => { + const upgradeReload = (): void => { + window.localStorage.setItem(upgradeSuccessLocalStorageKey, 'true'); + window.location.reload(); + }; + + if (isThisTriggerUpgrade) { + upgradeReload(); + } else { + const Message: React.FC = () => { + const { t } = useTranslation(); + return ( + <> + {t('serviceWorker.externalActivatedPrompt')} + <Button color="success" size="sm" onClick={upgradeReload} outline> + {t('serviceWorker.reloadNow')} + </Button> + </> + ); + }; + + pushAlert({ + message: Message, + dismissTime: 'never', + type: 'warning', + }); + } + }); + + wb.addEventListener('activated', (event) => { if (!event.isUpdate) { pushAlert({ message: { @@ -20,20 +64,11 @@ if ('serviceWorker' in navigator) { type: 'success', }); } - }; - - wb.addEventListener('activated', showFirstPrompt); - wb.addEventListener('externalactivated', showFirstPrompt); + }); const showSkipWaitingPrompt = (): void => { const upgrade = (): void => { - // Assuming the user accepted the update, set up a listener - // that will reload the page as soon as the previously waiting - // service worker has taken control. - wb.addEventListener('controlling', () => { - window.location.reload(); - }); - + isThisTriggerUpgrade = true; if (registration && registration.waiting) { // Send a message to the waiting service worker, // instructing it to activate. @@ -47,7 +82,7 @@ if ('serviceWorker' in navigator) { const { t } = useTranslation(); return ( <> - {t('serviceWorker.upgradeTitle')} + {t('serviceWorker.upgradePrompt')} <Button color="success" size="sm" onClick={upgrade} outline> {t('serviceWorker.upgradeNow')} </Button> |