Commit c30c9dd9 authored by Romain Courteaud's avatar Romain Courteaud

erp5_web_renderjs_ui: automatically handle service worker update and page refresh

Ensure that user automatically uses the latest code without manually refreshing the page.
parent 9446ce64
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
var MAIN_SCOPE = "m", var MAIN_SCOPE = "m",
default_state_json_string = JSON.stringify({ default_state_json_string = JSON.stringify({
panel_visible: false, panel_visible: false,
service_worker_claimed: false,
setting_id: "setting/" + document.head.querySelector( setting_id: "setting/" + document.head.querySelector(
'script[data-renderjs-configuration="application_title"]' 'script[data-renderjs-configuration="application_title"]'
).textContent, ).textContent,
...@@ -420,13 +421,7 @@ ...@@ -420,13 +421,7 @@
if (setting.hasOwnProperty('service_worker_url') && if (setting.hasOwnProperty('service_worker_url') &&
(setting.service_worker_url !== '')) { (setting.service_worker_url !== '')) {
if (navigator.serviceWorker !== undefined) { gadget.registerServiceWorker(setting.service_worker_url);
// Check if a ServiceWorker already controls the site on load
if (!navigator.serviceWorker.controller) {
// Register the ServiceWorker
navigator.serviceWorker.register(setting.service_worker_url);
}
}
} }
return setting_gadget.put(gadget.state.setting_id, setting); return setting_gadget.put(gadget.state.setting_id, setting);
...@@ -691,6 +686,16 @@ ...@@ -691,6 +686,16 @@
.allowPublicAcquisition("renderApplication", function renderApplication( .allowPublicAcquisition("renderApplication", function renderApplication(
param_list param_list
) { ) {
if (this.state.service_worker_claimed) {
// As a new service worker claimed the client,
// reload the page to ensure it uses the lastest gadget versions
return location.reload();
}
if (this.state.service_worker_registration) {
// Mimic service worker update rule
// when a navigation to an in-scope page
this.deferServiceWorkerUpdate(this.state.service_worker_registration);
}
return this.render.apply(this, param_list); return this.render.apply(this, param_list);
}) })
...@@ -923,7 +928,49 @@ ...@@ -923,7 +928,49 @@
wallpaper_url = null; wallpaper_url = null;
wallpaper_absolute_url = null; wallpaper_absolute_url = null;
} }
})
/////////////////////////////////////////////////////////////////
// Service worker handling
/////////////////////////////////////////////////////////////////
.declareJob('registerServiceWorker',
function registerServiceWorker(service_worker_url) {
var gadget = this;
if (navigator.serviceWorker !== undefined) {
return RSVP.all([
// Register the ServiceWorker
navigator.serviceWorker
.register(service_worker_url)
.then(function (registration) {
gadget.state.service_worker_registration = registration;
}),
// Check when a new worker has been activated from another tab
// XXX Not promise based, but we do not want to add a new dependency
navigator.serviceWorker
.addEventListener('message',
function handleMessage(event) {
if (event.data == 'claim') {
gadget.state.service_worker_claimed = true;
}
})
]);
}
})
.declareJob('deferServiceWorkerUpdate',
function deferServiceWorkerUpdate(registration) {
return new RSVP.Queue()
.push(function () {
// Delay service worker update, so that:
// * it does not slow down the current page rendering
// * it is not triggered too often if user click on multiple links
// * it is triggered only if the user browse the site
return RSVP.delay(60000);
})
.push(function () {
return registration.update();
});
}); });
}(window, document, RSVP, rJS, }(window, document, RSVP, rJS,
XMLHttpRequest, location, console, navigator, Event, URL)); XMLHttpRequest, location, console, navigator, Event, URL));
\ No newline at end of file
...@@ -234,7 +234,7 @@ ...@@ -234,7 +234,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>981.33505.56582.2560</string> </value> <value> <string>981.50747.28799.6519</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -252,7 +252,7 @@ ...@@ -252,7 +252,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1580400534.96</float> <float>1581434645.85</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -54,8 +54,6 @@ ...@@ -54,8 +54,6 @@
// Since we do not allow to override existing cache, if cache installation // Since we do not allow to override existing cache, if cache installation
// failed, we need to delete the cache completely. // failed, we need to delete the cache completely.
caches.delete(CACHE_NAME); caches.delete(CACHE_NAME);
// Explicitly unregister service worker else it may not be done.
self.registration.unregister();
throw error; throw error;
}) })
); );
...@@ -119,7 +117,19 @@ ...@@ -119,7 +117,19 @@
); );
}) })
.then(function () { .then(function () {
self.clients.claim(); return self.clients.claim();
})
.then(function () {
return self.clients.matchAll();
})
.then(function (client_list) {
// Notify all clients that they can reload the page
var i,
len = client_list.length;
for (i = 0; i < len; i += 1) {
client_list[i].postMessage('claim');
}
}) })
); );
}); });
......
...@@ -238,7 +238,7 @@ ...@@ -238,7 +238,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>981.49307.35014.63180</string> </value> <value> <string>981.50723.46947.51387</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -256,7 +256,7 @@ ...@@ -256,7 +256,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1581348269.23</float> <float>1581433826.93</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment