aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/frontend/src/RegisterServiceWorker.tsx
blob: 5f46bc3d8f57b7f616b9cf2be9b0d1945b0e4aed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import Button from '@mui/material/Button';
import {
  type OptionsObject as SnackbarOptionsObject,
  useSnackbar,
} from 'notistack';
import React, { useEffect } from 'react';
// eslint-disable-next-line import/no-unresolved -- Importing virtual module.
import { registerSW } from 'virtual:pwa-register';

import { ContrastThemeProvider } from './theme/ThemeProvider';
import getLogger from './utils/getLogger';

const log = getLogger('RegisterServiceWorker');

function UpdateSnackbarActions({
  closeCurrentSnackbar,
  enqueueSnackbar,
  updateSW,
}: {
  closeCurrentSnackbar: () => void;
  enqueueSnackbar: (
    message: string,
    options?: SnackbarOptionsObject | undefined,
  ) => void;
  updateSW: (reloadPage: boolean) => Promise<void>;
}): JSX.Element {
  return (
    <ContrastThemeProvider>
      <Button
        color="primary"
        onClick={() => {
          closeCurrentSnackbar();
          updateSW(true).catch((error) => {
            log.error('Failed to update service worker', error);
            enqueueSnackbar('Failed to download update', {
              variant: 'error',
            });
          });
        }}
      >
        Reload
      </Button>
      <Button color="inherit" onClick={closeCurrentSnackbar}>
        Dismiss
      </Button>
    </ContrastThemeProvider>
  );
}

export default function RegisterServiceWorker(): null {
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();
  useEffect(() => {
    if (window.location.host === 'localhost') {
      // Do not register service worker during local development.
      return;
    }
    if (!('serviceWorker' in navigator)) {
      log.debug('No service worker support found');
      return;
    }
    const updateSW = registerSW({
      onNeedRefresh() {
        const key = enqueueSnackbar('An update for Refinery is available', {
          persist: true,
          action: (
            <UpdateSnackbarActions
              closeCurrentSnackbar={() => closeSnackbar(key)}
              enqueueSnackbar={enqueueSnackbar}
              updateSW={updateSW}
            />
          ),
        });
      },
      onOfflineReady() {
        log.debug('Service worker is ready for offline use');
      },
      onRegistered() {
        log.debug('Registered service worker');
      },
      onRegisterError(error) {
        log.error('Failed to register service worker', error);
      },
    });
  }, [enqueueSnackbar, closeSnackbar]);
  return null;
}