diff options
| author | Romain Estievenart <res@odoo.com> | 2020-08-14 09:51:53 +0000 |
|---|---|---|
| committer | Adrien Dieudonne <adr@odoo.com> | 2020-08-25 19:32:45 +0000 |
| commit | ad386bc71e7432b0e058a7c846962c383344f6a4 (patch) | |
| tree | 4909b6a43da3c64d7fa79a9b48937619d42311fe | |
| parent | 22613d71b7ebf860003f6c9499de65ecb2b75aaf (diff) | |
[IMP] website_event_track_online: PWA's custom offline page
This page will be used in case of lost connection. The web page will be
automatically fetched when you are back online.
We also use this page when it's not possible to use the cache due to a
redirection.
closes odoo/odoo#56476
X-original-commit: a7c5cadc7467bd2c2423cd3e803cad3677961521
Signed-off-by: Pierre Paridans <pparidans@users.noreply.github.com>
Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
4 files changed, 80 insertions, 4 deletions
diff --git a/addons/website_event_track/controllers/webmanifest.py b/addons/website_event_track/controllers/webmanifest.py index a777ff10303..424f2a328f0 100644 --- a/addons/website_event_track/controllers/webmanifest.py +++ b/addons/website_event_track/controllers/webmanifest.py @@ -56,3 +56,9 @@ class TrackManifest(http.Controller): ('Service-Worker-Allowed', url_for('/event')), ]) return response + + @http.route('/event/offline', type='http', auth='public', methods=['GET'], website=True, sitemap=False) + def offline(self): + """ Returns the offline page used by the 'website_event' PWA + """ + return request.render('website_event_track.pwa_offline') diff --git a/addons/website_event_track/static/src/js/service_worker.js b/addons/website_event_track/static/src/js/service_worker.js index a994c2123c4..aec317435ef 100644 --- a/addons/website_event_track/static/src/js/service_worker.js +++ b/addons/website_event_track/static/src/js/service_worker.js @@ -9,6 +9,7 @@ const pendingRequestsQueueName = `${PREFIX}-pending-requests`; const cacheName = `${PREFIX}-cache`; const syncStore = new Store(`${PREFIX}-sync-db`, `${PREFIX}-sync-store`); const cacheStore = new Store(`${PREFIX}-cache-db`, `${PREFIX}-cache-store`); +const offlineRoute = `${self.registration.scope}/offline`; /** * @@ -45,6 +46,12 @@ const isCachableURL = canHandleRoutes(CACHABLE_ROUTES); /** * + * @return {Promise} + */ +const fetchToCacheOfflinePage = () => caches.open(cacheName).then((cache) => cache.add(offlineRoute)); + +/** + * * @param {Request} req * @returns {Promise<Object>} */ @@ -145,6 +152,19 @@ const isCachableRequest = (request) => isGET(request) || isCachableURL(request.u /** * + * @param request + * @param requestError + * @return {boolean} + */ +const isOfflineDocumentRequest = (request, requestError) => + request && requestError && requestError.message === 'Failed to fetch' && ( + (isGET(request) && request.mode === 'navigate' && request.destination === 'document') || + // request.mode = navigate isn't supported in all browsers => check for http header accept:text/html + (request.method === 'GET' && request.headers.get('accept').includes('text/html')) + ); + +/** + * * @param {Request} request * @returns {Promise<Response|null>} */ @@ -179,7 +199,11 @@ const processFetchEvent = async ({ request }) => { await cacheRequest(request, response); } catch (requestError) { if (isCachableRequest(requestCopy)) { - response = await matchCache(requestCopy); + try { + response = await matchCache(requestCopy); + } catch (err) { + console.warn("An error occurs when reading the cache request", err); + } } else if (isSyncableURL(requestCopy.url)) { const pendingRequests = (await get(pendingRequestsQueueName, syncStore)) || []; const serializedRequest = await serializeRequest(requestCopy); @@ -196,6 +220,10 @@ const processFetchEvent = async ({ request }) => { } if (!response) { + if (isOfflineDocumentRequest(request, requestError)) { + const cache = await caches.open(cacheName); + return await cache.match(offlineRoute); + } throw requestError; } } @@ -278,3 +306,8 @@ self.addEventListener("sync", (event) => { self.addEventListener("message", (event) => { event.waitUntil(processMessage(event.data)); }); + +// Precache static resources here. Like offline page +self.addEventListener('install', (event) => { + event.waitUntil(fetchToCacheOfflinePage()); +}); diff --git a/addons/website_event_track/static/src/js/website_event_pwa_widget.js b/addons/website_event_track/static/src/js/website_event_pwa_widget.js index 00c2a8ede33..1eb93a9cc22 100644 --- a/addons/website_event_track/static/src/js/website_event_pwa_widget.js +++ b/addons/website_event_track/static/src/js/website_event_pwa_widget.js @@ -68,14 +68,20 @@ odoo.define("website_event_track.website_event_pwa_widget", function (require) { //-------------------------------------------------------------------------- /** - * Returns the website's language + * Returns the website's language from the URL + * + * Note: this method performs a matching against both the simple (eg. "en") and complete (eg. "en_US") + * language formatting in the url. This is required as the cookie always returns the complete + * form but the URL can use both, depending on the language (eg. "en_US" => "en" but "en_UK" => "en_UK"). * @private * @return {String} */ _getLangPrefix: function () { var lang = utils.get_cookie("frontend_lang"); - if (lang !== undefined && window.location.href.indexOf("/" + lang + "/") >= 0) { - return "/" + lang; + var path = window.location.pathname; + var matches = path.match(new RegExp("^\/?(" + lang + "|" + lang.slice(0, 2) + ")\/")); + if (lang && matches && matches[1]) { + return "/" + matches[1]; } return ""; }, diff --git a/addons/website_event_track/views/event_templates.xml b/addons/website_event_track/views/event_templates.xml index 891c374de1a..caf1b7e41c5 100644 --- a/addons/website_event_track/views/event_templates.xml +++ b/addons/website_event_track/views/event_templates.xml @@ -41,4 +41,35 @@ <meta name="theme-color" content="#875A7B"/> </template> +<template id="pwa_offline" inherit_id="website_event.index" primary="True"> + <xpath expr='//div[@id="wrap"]' position="replace"> + <div id="wrap" class="o_wevent_index"> + <div class="container"> + <div class="row"> + <div class="col-12 card-body"> + <div class="h2 mb-3">You're offline!</div> + <div class="alert alert-info text-center"> + <span class="fa-stack fa-4x"> + <i class="fa fa-wifi fa-stack-1x"></i> + <i class="fa fa-ban fa-stack-2x text-muted"></i> + </span> + <p>This page hasn't been saved for offline reading yet.<br/>Please check your network connection.</p> + <p> + <a t-att-href="url_for('/event')" class="btn btn-primary btn-block">Home page</a> + <button onclick="history.back();" class="btn btn-secondary btn-block">Previous page</button> + </p> + </div> + </div> + </div> + </div> + </div> + <script type="text/javascript"> + window.addEventListener('online', function(e) { + console.log('Go back online'); + location.reload(); + }); + </script> + </xpath> +</template> + </odoo> |
