From 292546893af22f0e7652132630f1e0710765c153 Mon Sep 17 00:00:00 2001
From: Kristóf Marussy <kristof@marussy.com>
Date: Fri, 19 Aug 2022 19:54:55 +0200
Subject: feat(frontend): add PWA manifest

---
 subprojects/frontend/src/RegisterServiceWorker.tsx | 85 ++++++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 subprojects/frontend/src/RegisterServiceWorker.tsx

(limited to 'subprojects/frontend/src/RegisterServiceWorker.tsx')

diff --git a/subprojects/frontend/src/RegisterServiceWorker.tsx b/subprojects/frontend/src/RegisterServiceWorker.tsx
new file mode 100644
index 00000000..c9b2e353
--- /dev/null
+++ b/subprojects/frontend/src/RegisterServiceWorker.tsx
@@ -0,0 +1,85 @@
+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 (import.meta.env.DEV) {
+      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;
+}
-- 
cgit v1.2.3-70-g09d2

