diff --git a/src/components/page.tsx b/src/components/page.tsx index a08b5ef34..fc34b50c4 100644 --- a/src/components/page.tsx +++ b/src/components/page.tsx @@ -9,12 +9,14 @@ import { useIsMobile } from "../hooks/use-is-mobile"; import { ProfileButton } from "./profile-button"; import identity from "../services/identity"; import { FollowingList } from "./following-list"; +import { ReloadPrompt } from "./reload-prompt"; const MobileLayout = ({ children }: { children: React.ReactNode }) => { const navigate = useNavigate(); return ( + {children} @@ -42,28 +44,33 @@ const DesktopLayout = ({ children }: { children: React.ReactNode }) => { const navigate = useNavigate(); return ( - - - - - - - - - - {children} - - - Following - - - + <> + + + + + + + + + + + + {children} + + + Following + + + + + ); }; diff --git a/src/components/reload-prompt.tsx b/src/components/reload-prompt.tsx new file mode 100644 index 000000000..22baf2b7c --- /dev/null +++ b/src/components/reload-prompt.tsx @@ -0,0 +1,32 @@ +import { useRegisterSW } from "virtual:pwa-register/react"; +import { Alert, AlertIcon, AlertTitle, Button } from "@chakra-ui/react"; + +export const ReloadPrompt = () => { + const { + offlineReady: [offlineReady, setOfflineReady], + needRefresh: [needRefresh, setNeedRefresh], + updateServiceWorker, + } = useRegisterSW({ + onRegistered(r) { + console.log("SW Registered: " + r); + }, + onRegisterError(error) { + console.log("SW registration error", error); + }, + }); + + const close = () => { + setOfflineReady(false); + setNeedRefresh(false); + }; + + return offlineReady || needRefresh ? ( + + + New update ready! + + + ) : null; +}; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 11f02fe2a..a100af0ce 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1 +1,34 @@ /// +/// + +declare module "virtual:pwa-register/react" { + // @ts-expect-error ignore when react is not installed + import type { Dispatch, SetStateAction } from "react"; + + export interface RegisterSWOptions { + immediate?: boolean; + onNeedRefresh?: () => void; + onOfflineReady?: () => void; + /** + * Called only if `onRegisteredSW` is not provided. + * + * @deprecated Use `onRegisteredSW` instead. + * @param registration The service worker registration if available. + */ + onRegistered?: (registration: ServiceWorkerRegistration | undefined) => void; + /** + * Called once the service worker is registered (requires version `0.12.8+`). + * + * @param swScriptUrl The service worker script url. + * @param registration The service worker registration if available. + */ + onRegisteredSW?: (swScriptUrl: string, registration: ServiceWorkerRegistration | undefined) => void; + onRegisterError?: (error: any) => void; + } + + export function useRegisterSW(options?: RegisterSWOptions): { + needRefresh: [boolean, Dispatch>]; + offlineReady: [boolean, Dispatch>]; + updateServiceWorker: (reloadPage?: boolean) => Promise; + }; +}