diff --git a/web/public/sw.js b/web/public/sw.js index d3967441..33154628 100644 --- a/web/public/sw.js +++ b/web/public/sw.js @@ -2,6 +2,7 @@ import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from "workbox-precaching"; import { NavigationRoute, registerRoute } from "workbox-routing"; import { NetworkFirst } from "workbox-strategies"; +import { clientsClaim } from "workbox-core"; import { dbAsync } from "../src/app/db"; @@ -224,6 +225,8 @@ precacheAndRoute( self.__WB_MANIFEST ); +// Claim all open windows +clientsClaim(); // Delete any cached old dist files from previous service worker versions cleanupOutdatedCaches(); diff --git a/web/src/components/App.jsx b/web/src/components/App.jsx index 2951a2bc..2ad7f419 100644 --- a/web/src/components/App.jsx +++ b/web/src/components/App.jsx @@ -1,7 +1,6 @@ import * as React from "react"; import { createContext, Suspense, useContext, useEffect, useState, useMemo } from "react"; -import { Box, Toolbar, CssBaseline, Backdrop, CircularProgress, useMediaQuery } from "@mui/material"; -import { ThemeProvider, createTheme } from "@mui/material/styles"; +import { Box, Toolbar, CssBaseline, Backdrop, CircularProgress, useMediaQuery, ThemeProvider, createTheme } from "@mui/material"; import { useLiveQuery } from "dexie-react-hooks"; import { BrowserRouter, Outlet, Route, Routes, useParams } from "react-router-dom"; import { AllSubscriptions, SingleSubscription } from "./Notifications"; @@ -133,7 +132,7 @@ const Main = (props) => ( display: "flex", flexGrow: 1, flexDirection: "column", - padding: 3, + padding: { xs: 0, md: 3 }, width: { sm: `calc(100% - ${Navigation.width}px)` }, height: "100dvh", overflow: "auto", diff --git a/web/src/components/Notifications.jsx b/web/src/components/Notifications.jsx index fe9fcc48..85ced743 100644 --- a/web/src/components/Notifications.jsx +++ b/web/src/components/Notifications.jsx @@ -184,7 +184,7 @@ const NotificationItem = (props) => { const hasUserActions = notification.actions && notification.actions.length > 0; const showActions = hasAttachmentActions || hasClickAction || hasUserActions; return ( - + diff --git a/web/src/components/theme.js b/web/src/components/theme.js index 64217eee..9cf6649f 100644 --- a/web/src/components/theme.js +++ b/web/src/components/theme.js @@ -55,6 +55,14 @@ export const darkTheme = { }, }, }, + MuiPaper: { + styleOverrides: { + root: { + // for the sidebar on narrow (xs) screens + backgroundImage: "none", + }, + }, + }, }, palette: { mode: "dark", diff --git a/web/src/index.jsx b/web/src/index.jsx index d60c05a4..1a123a8a 100644 --- a/web/src/index.jsx +++ b/web/src/index.jsx @@ -1,6 +1,9 @@ import * as React from "react"; import { createRoot } from "react-dom/client"; import App from "./components/App"; +import registerSW from "./registerSW"; + +registerSW(); const root = createRoot(document.querySelector("#root")); root.render(); diff --git a/web/src/registerSW.js b/web/src/registerSW.js new file mode 100644 index 00000000..adef4746 --- /dev/null +++ b/web/src/registerSW.js @@ -0,0 +1,31 @@ +// eslint-disable-next-line import/no-unresolved +import { registerSW as viteRegisterSW } from "virtual:pwa-register"; + +// fetch new sw every hour, i.e. update app every hour while running +const intervalMS = 60 * 60 * 1000; + +// https://vite-pwa-org.netlify.app/guide/periodic-sw-updates.html +const registerSW = () => + viteRegisterSW({ + onRegisteredSW(swUrl, registration) { + if (!registration) { + return; + } + + setInterval(async () => { + if (registration.installing || navigator?.onLine === false) return; + + const resp = await fetch(swUrl, { + cache: "no-store", + headers: { + cache: "no-store", + "cache-control": "no-cache", + }, + }); + + if (resp?.status === 200) await registration.update(); + }, intervalMS); + }, + }); + +export default registerSW; diff --git a/web/vite.config.js b/web/vite.config.js index 22d17d9b..a4fd5a31 100644 --- a/web/vite.config.js +++ b/web/vite.config.js @@ -16,7 +16,8 @@ export default defineConfig(({ mode }) => ({ react(), VitePWA({ registerType: "autoUpdate", - injectRegister: "inline", + // see registerSW.js imported by index.jsx + injectRegister: null, strategies: "injectManifest", devOptions: { enabled: true, @@ -25,7 +26,7 @@ export default defineConfig(({ mode }) => ({ navigateFallback: "index.html", }, injectManifest: { - globPatterns: ["**/*.{js,css,html,mp3,ico,png,svg,json}"], + globPatterns: ["**/*.{js,css,html,ico,png,svg,json}"], globIgnores: ["config.js"], manifestTransforms: [ (entries) => ({