feat: Implement in-app service worker update notification

Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
2025-12-27 17:52:45 +00:00
parent a1ebcc6d80
commit 2757f701d0
2 changed files with 27 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ function App() {
const [theme, setTheme] = useState(localStorage.getItem('theme') || '');
const cache = useRef({});
const [isFullScreen, setIsFullScreen] = useState(!!document.fullscreenElement);
const [waitingWorker, setWaitingWorker] = useState(null);
const updateCache = useCallback((key, value) => {
cache.current[key] = value;
@@ -44,6 +45,14 @@ function App() {
localStorage.setItem('theme', 'red');
};
useEffect(() => {
const onSWUpdate = e => {
setWaitingWorker(e.detail.waiting);
};
window.addEventListener('swUpdate', onSWUpdate);
return () => window.removeEventListener('swUpdate', onSWUpdate);
}, []);
useEffect(() => {
if (Object.keys(cache.current).length === 0) {
localForage.iterate((value, key) => {
@@ -90,6 +99,19 @@ function App() {
return (
<div className={theme}>
{waitingWorker &&
<div style={{padding: 10, backgroundColor: '#ffffcc', color: '#000'}}>
A new version is available.{' '}
<button onClick={() => {
waitingWorker.postMessage({ type: 'SKIP_WAITING' });
navigator.serviceWorker.addEventListener('controllerchange', () => {
window.location.reload();
});
}}>
Refresh
</button>
</div>
}
<Router>
<div className='container menu'>
<p>

View File

@@ -8,4 +8,8 @@ ReactDOM.render(<App />, document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// // unregister() to register() below. Note this comes with some pitfalls.
// // Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
serviceWorker.register({
onUpdate: registration => {
window.dispatchEvent(new CustomEvent('swUpdate', { detail: registration }));
}
});