Files
clarity-helper/components/ReloadPrompt.tsx
T
2026-03-06 08:49:42 -05:00

108 lines
3.9 KiB
TypeScript

import React, { useEffect } from 'react';
import { useRegisterSW } from 'virtual:pwa-register/react';
import { Button } from './ui/button';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle
} from './ui/dialog';
export const ReloadPrompt: React.FC = () => {
// Skip SW in dev mode
if (import.meta.env.DEV) {
useEffect(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then((registrations) => {
registrations.forEach((registration) => registration.unregister());
});
}
// Clear workbox caches
if (typeof caches !== 'undefined') {
caches.keys().then((keys) => {
keys.forEach((key) => {
if (key.toLowerCase().includes('workbox') || key.toLowerCase().includes('cognitive-clarity')) {
caches.delete(key);
}
});
});
}
}, []);
return null;
}
const {
offlineReady: [offlineReady, setOfflineReady],
needRefresh: [needRefresh, setNeedRefresh],
updateServiceWorker,
} = useRegisterSW({
onRegisteredSW(swUrl, r) {
if (r) {
// Check for updates every 60 minutes
setInterval(() => {
console.log('[PWA] Periodic update check...');
r.update();
}, 60 * 60 * 1000);
// Check for updates when coming back online
const handleOnline = () => {
console.log('[PWA] Back online, checking for updates...');
r.update();
};
window.addEventListener('online', handleOnline);
}
// Auto-reload when a new service worker takes control
if ('serviceWorker' in navigator) {
navigator.serviceWorker.addEventListener('controllerchange', () => {
console.log('[PWA] Controller changed, reloading...');
window.location.reload();
});
}
},
});
const close = () => {
setOfflineReady(false);
setNeedRefresh(false);
};
return (
<Dialog open={needRefresh || offlineReady} onOpenChange={close}>
<DialogContent className="sm:max-w-md bg-slate-900 border-slate-800 text-slate-100">
<DialogHeader>
<DialogTitle>
{needRefresh ? 'Update Available' : 'Offline Ready'}
</DialogTitle>
<DialogDescription className="text-slate-400">
{needRefresh
? 'A new version of Cognitive Clarity is available. Click reload to update immediately.'
: 'The application is ready to work offline.'}
</DialogDescription>
</DialogHeader>
<DialogFooter className="sm:justify-start gap-2">
{needRefresh && (
<Button
type="button"
onClick={() => updateServiceWorker(true)}
className="bg-blue-600 hover:bg-blue-500 text-white"
>
Reload and Update
</Button>
)}
<Button
type="button"
variant="secondary"
onClick={close}
className="bg-slate-800 hover:bg-slate-700 text-slate-300 border-none"
>
Close
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};