Added custom PWA reloading - 10 minutes of idle or when moved to the background or when loading initially or manually with the new button in settings
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import { type Component, createEffect, onCleanup } from 'solid-js';
|
||||
import { useRegisterSW } from 'virtual:pwa-register/solid';
|
||||
|
||||
// We export a function so other parts of the app can manually trigger an update
|
||||
let manualUpdateFn: (() => void) | undefined;
|
||||
|
||||
export const forceServiceWorkerUpdate = () => {
|
||||
if (manualUpdateFn) {
|
||||
manualUpdateFn();
|
||||
} else {
|
||||
console.warn("PWA Updater not initialized yet");
|
||||
}
|
||||
};
|
||||
|
||||
export const PwaUpdater: Component = () => {
|
||||
let registration: ServiceWorkerRegistration | undefined;
|
||||
|
||||
const {
|
||||
needRefresh: [needRefresh],
|
||||
updateServiceWorker,
|
||||
} = useRegisterSW({
|
||||
onRegistered(r: ServiceWorkerRegistration | undefined) {
|
||||
console.log('SW Registered:', r);
|
||||
registration = r;
|
||||
|
||||
// Periodically check for updates (every 1 hour)
|
||||
if (r) {
|
||||
setInterval(() => {
|
||||
console.log('Periodic SW update check...');
|
||||
r.update();
|
||||
}, 60 * 60 * 1000);
|
||||
}
|
||||
},
|
||||
onRegisterError(error: Error | any) {
|
||||
console.error('SW registration error', error);
|
||||
},
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
// Expose function globally
|
||||
manualUpdateFn = () => {
|
||||
if (needRefresh()) {
|
||||
console.log('User manually forced an update. Reloading now...');
|
||||
updateServiceWorker(true);
|
||||
} else if (registration) {
|
||||
console.log('User manually asked to check for updates...');
|
||||
registration.update();
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
// Check for updates when the app regains focus/visibility
|
||||
const handleVisibilityFocus = () => {
|
||||
if (document.visibilityState === 'visible' && registration) {
|
||||
console.log('App became visible, checking for SW updates...');
|
||||
registration.update();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('visibilitychange', handleVisibilityFocus);
|
||||
window.addEventListener('focus', handleVisibilityFocus);
|
||||
|
||||
onCleanup(() => {
|
||||
document.removeEventListener('visibilitychange', handleVisibilityFocus);
|
||||
window.removeEventListener('focus', handleVisibilityFocus);
|
||||
});
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
if (needRefresh()) {
|
||||
console.log('New PWA version available. Monitoring for idle/hidden state to update...');
|
||||
|
||||
let idleTimeout: number | undefined;
|
||||
|
||||
const triggerUpdate = () => {
|
||||
console.log('Triggering PWA update...');
|
||||
updateServiceWorker(true);
|
||||
};
|
||||
|
||||
const resetIdle = () => {
|
||||
if (idleTimeout) window.clearTimeout(idleTimeout);
|
||||
// 10 minutes idle
|
||||
idleTimeout = window.setTimeout(triggerUpdate, 10 * 60 * 1000);
|
||||
};
|
||||
|
||||
const handleVisibility = () => {
|
||||
if (document.visibilityState === 'hidden') {
|
||||
triggerUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
// Start idle timer
|
||||
resetIdle();
|
||||
|
||||
// Listen for user activity
|
||||
const events = ['mousedown', 'mousemove', 'keydown', 'scroll', 'touchstart'];
|
||||
events.forEach(e => window.addEventListener(e, resetIdle, { passive: true }));
|
||||
document.addEventListener('visibilitychange', handleVisibility);
|
||||
|
||||
onCleanup(() => {
|
||||
if (idleTimeout) window.clearTimeout(idleTimeout);
|
||||
events.forEach(e => window.removeEventListener(e, resetIdle));
|
||||
document.removeEventListener('visibilitychange', handleVisibility);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
};
|
||||
Reference in New Issue
Block a user