Skip to content

Commit

Permalink
Merge pull request #1188 from jinzo/pwa-sw-update-check
Browse files Browse the repository at this point in the history
PWA regularly check for service worker updates and automaticially reload the page
  • Loading branch information
tananaev authored Nov 6, 2023
2 parents d59b39c + 85d5322 commit 4a6e35c
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 1 deletion.
2 changes: 2 additions & 0 deletions modern/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SocketController from './SocketController';
import CachingController from './CachingController';
import { useEffectAsync } from './reactHelper';
import { sessionActions } from './store';
import UpdateController from './UpdateController';

const useStyles = makeStyles(() => ({
page: {
Expand Down Expand Up @@ -48,6 +49,7 @@ const App = () => {
<>
<SocketController />
<CachingController />
<UpdateController />
<div className={classes.page}>
<Outlet />
</div>
Expand Down
58 changes: 58 additions & 0 deletions modern/src/UpdateController.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Snackbar, IconButton } from '@mui/material';
import RefreshIcon from '@mui/icons-material/Refresh';
import React from 'react'
import { useSelector } from 'react-redux';
import { useTranslation } from './common/components/LocalizationProvider';
import { useRegisterSW } from 'virtual:pwa-register/react'

// Based on https://vite-pwa-org.netlify.app/frameworks/react.html
function UpdateController() {
const t = useTranslation();

const swUpdateInterval = useSelector((state) => state.session.server.attributes.serviceWorkerUpdateInterval || 3600000);

const {
needRefresh: [needRefresh],
updateServiceWorker,
} = useRegisterSW({
onRegisteredSW(swUrl, swRegistration) {
if (swUpdateInterval > 0 && swRegistration) {
setInterval(async () => {
if (!(!swRegistration.installing && navigator)) {
return;
}

if (('connection' in navigator) && !navigator.onLine) {
return;
}

const newSW = await fetch(swUrl, {
cache: 'no-store',
headers: {
'cache': 'no-store',
'cache-control': 'no-cache',
},
});

if (newSW?.status === 200) {
await swRegistration.update();
}
}, swUpdateInterval);
}
}
});

return (
<Snackbar
open={needRefresh}
message={t('settingsUpdateAvailable')}
action={(
<IconButton color="inherit" onClick={() => updateServiceWorker(true)}>
<RefreshIcon />
</IconButton>
)}
/>
);
}

export default UpdateController;
4 changes: 4 additions & 0 deletions modern/src/common/attributes/useServerAttributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export default (t) => useMemo(() => ({
name: t('settingsTotpForce'),
type: 'boolean',
},
serviceWorkerUpdateInterval: {
name: t('settingsServiceWorkerUpdateInterval'),
type: 'number',
},
'ui.disableLoginLanguage': {
name: t('attributeUiDisableLoginLanguage'),
type: 'boolean',
Expand Down
2 changes: 2 additions & 0 deletions modern/src/resources/l10n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@
"settingsDarkMode": "Dark Mode",
"settingsTotpEnable": "Enable One-time Password",
"settingsTotpForce": "Force One-time Password",
"settingsServiceWorkerUpdateInterval": "ServiceWorker Update Interval",
"settingsUpdateAvailable": "There is an update available.",
"reportTitle": "Reports",
"reportScheduled": "Scheduled Reports",
"reportDevice": "Device",
Expand Down
1 change: 0 additions & 1 deletion modern/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export default defineConfig(() => ({
svgr(),
react(),
VitePWA({
registerType: 'autoUpdate',
workbox: {
navigateFallbackDenylist: [/^\/api/],
},
Expand Down

0 comments on commit 4a6e35c

Please sign in to comment.