Skip to content

Commit

Permalink
Extracted ui callback into reusable demo class.
Browse files Browse the repository at this point in the history
  • Loading branch information
daffinm committed Apr 4, 2020
1 parent 3686a84 commit 42c6187
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 39 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ feel confident that my apps will work well and I can stop thinking about it.
The simple use case here (which I suspect is the main one) is:

1. Publish update to PWA.
1. User is notified next time they: reload/restart the app, or press a 'check for updates' button somewhere in the UI, or the update
1. User is notified next time they: reload/restart the simpleUI, or press a 'check for updates' button somewhere in the UI, or the update
is discovered because of some kind of periodic background check (I think that's it).
1. User is given the option to use the update now or later.
* Updates cannot be rejected indefinitely in PWA land.
* By the time the user hears of the update it has already been installed and is waiting to become active.
1. If the user accepts the update the new service worker version is activated and, once this happens, the app reloads to get
1. If the user accepts the update the new service worker version is activated and, once this happens, the simpleUI reloads to get
itself in sync with the new back end.
1. If the user rejects the update they carry on using the old version of the service worker and UI until next time one of the
three things mentioned in step 2 happens again.
1. At this point they will get the option, again, to accept or reject the update for the time being.
* The fact that they may have rejected an update before should not stop them changing their mind later.
1. The only exception to this is when the app is first accessed and the first version of the service worker is installed
1. The only exception to this is when the simpleUI is first accessed and the first version of the service worker is installed
on the user's machine (browser).
* At this point the page ('client') will not be controlled, so any update will activate
automatically.
Expand All @@ -38,7 +38,7 @@ The code here attempt so do all of this as simply as possible.

Have I missed anything, or misunderstood, or made it too complicated?

## Running and playing with the app
## Running and playing with the simpleUI

1. Run project using `npm start` and goto http://localhost:5001 in Chrome.
1. Open the dev tools console asap and check the console messages to see what's happening.
Expand Down
34 changes: 2 additions & 32 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,38 +70,8 @@ <h1>Service Worker Test</h1>
let message = (underControl ? 'This page IS controlled by a Service Worker' : 'This page is NOT controlled by a Service Worker');
$messages.className = className;
$messages.innerHTML = message;
// The callback object - implements an interface (I wish) that enables us to decouple the service worker client from
// the app that's using it.
const app = {
noUpdateFound() {
alert(`No update found\n\nYou are already on the latest version.`);
},
updateError(err) {
alert(`Error\n\nCannot check for updates.\n\nAre you offline?`);
},
updateFoundReloadNeeded() {
// Called when an update is found but the client is not controlled by the service worker. This means that
// the update will activate automatically. So the client will need to play catch up with the service worker:
// to reload so that it becomes controlled by it.
// Inform the user with OK dialog and reload when this returns (to give some sense of control).
alert('Update found!\n\nApp will reload when you press OK.');
app.reload();
},
confirmUpdateWithUser(callback) {
if (confirm(`Update available!\n\nAn update is available for this app.\n\nUse it now?`)) {
callback(true);
}
else {
callback(false);
}
},
reload() {
debug.warn('Reloading app...');
document.body.style = 'color:red;';
setTimeout(() => window.location.reload(), 1000);
}
};
const swc = new ServiceWorkerClient('sw.js', debug, app);

const swc = new ServiceWorkerClient('sw.js', debug, new SimpleUI(debug));
swc.register();
// The update button
const updateButton = document.getElementById('check-for-updates');
Expand Down
33 changes: 33 additions & 0 deletions js/sw-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,36 @@ function ServiceWorkerClient(url, debug, ui) {
}
}
}

// Demo ui callback object - implements an interface (I wish) that enables us to decouple the service worker
// client from the app that's using it.
function SimpleUI(debug) {
this.noUpdateFound = function () {
alert(`No update found\n\nYou are already on the latest version.`);
};
this.updateError = function (err) {
alert(`Error\n\nCannot check for updates.\n\nAre you offline?`);
};
this.updateFoundReloadNeeded = function () {
// Called when an update is found but the client is not controlled by the service worker. This means that
// the update will activate automatically. So the client will need to play catch up with the service worker:
// to reload so that it becomes controlled by it.
// Inform the user with OK dialog and reload when this returns (to give some sense of control).
alert('Update found!\n\nApp will reload when you press OK.');
this.reload();
};
this.confirmUpdateWithUser = function (callback) {
if (confirm(`Update available!\n\nAn update is available for this simpleUI.\n\nUse it now?`)) {
callback(true);
}
else {
callback(false);
}
};
this.reload = function () {
debug.warn('Reloading app...');
document.body.style = 'color:red;';
setTimeout(() => window.location.reload(), 1000);
};
}

8 changes: 5 additions & 3 deletions sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ self.addEventListener('activate', function(event) {
});

// Note: does not matter if you stick the index.html in precache or runtime cache. Does not matter which cache stragegy
// you use. First time the app runs it runs it will not be controlled by a service worker. Because the page loads, then
// you use. First time the simpleUI runs it runs it will not be controlled by a service worker. Because the page loads, then
// registers the service worker for the first time, which then installs and activates and starts handling fetches from the
// app clients.
// simpleUI clients.
// ---
// workbox.precaching.precacheAndRoute([
// {"revision":"001","url":"index.html"},
Expand All @@ -86,4 +86,6 @@ workbox.routing.registerRoute(
ignoreVary: true,
}
})
);
);


0 comments on commit 42c6187

Please sign in to comment.