mirror of
https://github.com/OCA/web.git
synced 2025-02-22 13:21:25 +02:00
[IMP] web_pwa_oca: Port changes from 12.0
This commit is contained in:
committed by
sergio-teruel
parent
c1afeed3c1
commit
1194498f2e
@@ -1 +1,4 @@
|
||||
# Copyright 2020 Lorenzo Battistini @ TAKOBI
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
from . import main
|
||||
from . import service_worker
|
||||
|
||||
@@ -1,77 +1,119 @@
|
||||
# Copyright 2020 Lorenzo Battistini @ TAKOBI
|
||||
# Copyright 2020 Tecnativa - Alexandre D. Díaz
|
||||
# Copyright 2020 Tecnativa - João Marques
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
import json
|
||||
|
||||
from odoo.http import Controller, request, route
|
||||
|
||||
|
||||
class PWA(Controller):
|
||||
def get_asset_urls(self, asset_xml_id):
|
||||
qweb = request.env["ir.qweb"].sudo()
|
||||
assets = qweb._get_asset_nodes(asset_xml_id, {}, True, True)
|
||||
urls = []
|
||||
for asset in assets:
|
||||
if asset[0] == "link":
|
||||
urls.append(asset[1]["href"])
|
||||
if asset[0] == "script":
|
||||
urls.append(asset[1]["src"])
|
||||
return urls
|
||||
def _get_pwa_scripts(self):
|
||||
"""Scripts to be imported in the service worker (Order is important)"""
|
||||
return [
|
||||
"/web/static/lib/underscore/underscore.js",
|
||||
"/web_pwa_oca/static/src/js/worker/jquery-sw-compat.js",
|
||||
"/web/static/src/js/promise_extension.js",
|
||||
"/web/static/src/js/boot.js",
|
||||
"/web/static/src/js/core/class.js",
|
||||
"/web_pwa_oca/static/src/js/worker/pwa.js",
|
||||
]
|
||||
|
||||
@route("/service-worker.js", type="http", auth="public")
|
||||
def service_worker(self):
|
||||
qweb = request.env["ir.qweb"].sudo()
|
||||
urls = []
|
||||
urls.extend(self.get_asset_urls("web.assets_common"))
|
||||
urls.extend(self.get_asset_urls("web.assets_backend"))
|
||||
version_list = []
|
||||
for url in urls:
|
||||
version_list.append(url.split("/")[3])
|
||||
cache_version = "-".join(version_list)
|
||||
mimetype = "text/javascript;charset=utf-8"
|
||||
content = qweb.render(
|
||||
def render_service_worker(self):
|
||||
"""Route to register the service worker in the 'main' scope ('/')"""
|
||||
return request.render(
|
||||
"web_pwa_oca.service_worker",
|
||||
{"pwa_cache_name": cache_version, "pwa_files_to_cache": urls},
|
||||
{
|
||||
"pwa_scripts": self._get_pwa_scripts(),
|
||||
"pwa_params": self._get_pwa_params(),
|
||||
},
|
||||
headers=[("Content-Type", "text/javascript;charset=utf-8")],
|
||||
)
|
||||
return request.make_response(content, [("Content-Type", mimetype)])
|
||||
|
||||
@route("/web_pwa_oca/manifest.json", type="http", auth="public")
|
||||
def manifest(self):
|
||||
qweb = request.env["ir.qweb"].sudo()
|
||||
config_param = request.env["ir.config_parameter"].sudo()
|
||||
pwa_name = config_param.get_param("pwa.manifest.name", "Odoo PWA")
|
||||
pwa_short_name = config_param.get_param("pwa.manifest.short_name", "Odoo PWA")
|
||||
icon128x128 = config_param.get_param(
|
||||
"pwa.manifest.icon128x128", "/web_pwa_oca/static/img/icons/icon-128x128.png"
|
||||
def _get_pwa_params(self):
|
||||
"""Get javascript PWA class initialzation params"""
|
||||
return {}
|
||||
|
||||
def _get_pwa_manifest_icons(self, pwa_icon):
|
||||
icons = []
|
||||
if not pwa_icon:
|
||||
for size in [
|
||||
(128, 128),
|
||||
(144, 144),
|
||||
(152, 152),
|
||||
(192, 192),
|
||||
(256, 256),
|
||||
(512, 512),
|
||||
]:
|
||||
icons.append(
|
||||
{
|
||||
"src": "/web_pwa_oca/static/img/icons/icon-%sx%s.png"
|
||||
% (str(size[0]), str(size[1])),
|
||||
"sizes": "{}x{}".format(str(size[0]), str(size[1])),
|
||||
"type": "image/png",
|
||||
}
|
||||
)
|
||||
elif not pwa_icon.mimetype.startswith("image/svg"):
|
||||
all_icons = (
|
||||
request.env["ir.attachment"]
|
||||
.sudo()
|
||||
.search(
|
||||
[
|
||||
("url", "like", "/web_pwa_oca/icon"),
|
||||
(
|
||||
"url",
|
||||
"not like",
|
||||
"/web_pwa_oca/icon.",
|
||||
), # Get only resized icons
|
||||
]
|
||||
)
|
||||
)
|
||||
for icon in all_icons:
|
||||
icon_size_name = icon.url.split("/")[-1].lstrip("icon").split(".")[0]
|
||||
icons.append(
|
||||
{"src": icon.url, "sizes": icon_size_name, "type": icon.mimetype}
|
||||
)
|
||||
else:
|
||||
icons = [
|
||||
{
|
||||
"src": pwa_icon.url,
|
||||
"sizes": "128x128 144x144 152x152 192x192 256x256 512x512",
|
||||
"type": pwa_icon.mimetype,
|
||||
}
|
||||
]
|
||||
return icons
|
||||
|
||||
def _get_pwa_manifest(self):
|
||||
"""Webapp manifest"""
|
||||
config_param_sudo = request.env["ir.config_parameter"].sudo()
|
||||
pwa_name = config_param_sudo.get_param("pwa.manifest.name", "Odoo PWA")
|
||||
pwa_short_name = config_param_sudo.get_param(
|
||||
"pwa.manifest.short_name", "Odoo PWA"
|
||||
)
|
||||
icon144x144 = config_param.get_param(
|
||||
"pwa.manifest.icon144x144", "/web_pwa_oca/static/img/icons/icon-144x144.png"
|
||||
pwa_icon = (
|
||||
request.env["ir.attachment"]
|
||||
.sudo()
|
||||
.search([("url", "like", "/web_pwa_oca/icon.")])
|
||||
)
|
||||
icon152x152 = config_param.get_param(
|
||||
"pwa.manifest.icon152x152", "/web_pwa_oca/static/img/icons/icon-152x152.png"
|
||||
)
|
||||
icon192x192 = config_param.get_param(
|
||||
"pwa.manifest.icon192x192", "/web_pwa_oca/static/img/icons/icon-192x192.png"
|
||||
)
|
||||
icon256x256 = config_param.get_param(
|
||||
"pwa.manifest.icon256x256", "/web_pwa_oca/static/img/icons/icon-256x256.png"
|
||||
)
|
||||
icon512x512 = config_param.get_param(
|
||||
"pwa.manifest.icon512x512", "/web_pwa_oca/static/img/icons/icon-512x512.png"
|
||||
)
|
||||
background_color = config_param.get_param(
|
||||
background_color = config_param_sudo.get_param(
|
||||
"pwa.manifest.background_color", "#2E69B5"
|
||||
)
|
||||
theme_color = config_param.get_param("pwa.manifest.theme_color", "#2E69B5")
|
||||
mimetype = "application/json;charset=utf-8"
|
||||
content = qweb.render(
|
||||
"web_pwa_oca.manifest",
|
||||
{
|
||||
"pwa_name": pwa_name,
|
||||
"pwa_short_name": pwa_short_name,
|
||||
"icon128x128": icon128x128,
|
||||
"icon144x144": icon144x144,
|
||||
"icon152x152": icon152x152,
|
||||
"icon192x192": icon192x192,
|
||||
"icon256x256": icon256x256,
|
||||
"icon512x512": icon512x512,
|
||||
"background_color": background_color,
|
||||
"theme_color": theme_color,
|
||||
},
|
||||
theme_color = config_param_sudo.get_param("pwa.manifest.theme_color", "#2E69B5")
|
||||
return {
|
||||
"name": pwa_name,
|
||||
"short_name": pwa_short_name,
|
||||
"icons": self._get_pwa_manifest_icons(pwa_icon),
|
||||
"start_url": "/web",
|
||||
"display": "standalone",
|
||||
"background_color": background_color,
|
||||
"theme_color": theme_color,
|
||||
}
|
||||
|
||||
@route("/web_pwa_oca/manifest.webmanifest", type="http", auth="public")
|
||||
def pwa_manifest(self):
|
||||
"""Returns the manifest used to install the page as app"""
|
||||
return request.make_response(
|
||||
json.dumps(self._get_pwa_manifest()),
|
||||
headers=[("Content-Type", "application/json;charset=utf-8")],
|
||||
)
|
||||
return request.make_response(content, [("Content-Type", mimetype)])
|
||||
|
||||
98
web_pwa_oca/controllers/service_worker.py
Normal file
98
web_pwa_oca/controllers/service_worker.py
Normal file
@@ -0,0 +1,98 @@
|
||||
# Copyright 2021 Tecnativa - Alexandre D. Díaz
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
from odoo.http import request, route
|
||||
|
||||
from .main import PWA
|
||||
|
||||
|
||||
class ServiceWorker(PWA):
|
||||
|
||||
JS_PWA_CORE_EVENT_INSTALL = """
|
||||
self.addEventListener('install', evt => {{
|
||||
console.log('[ServiceWorker] Installing...');
|
||||
{}
|
||||
}});
|
||||
"""
|
||||
|
||||
JS_PWA_CORE_EVENT_FETCH = """
|
||||
self.addEventListener('fetch', evt => {{
|
||||
{}
|
||||
}});
|
||||
"""
|
||||
|
||||
JS_PWA_CORE_EVENT_ACTIVATE = """
|
||||
self.addEventListener('activate', evt => {{
|
||||
{}
|
||||
}});
|
||||
"""
|
||||
|
||||
JS_PWA_MAIN = """
|
||||
self.importScripts(...{pwa_scripts});
|
||||
|
||||
odoo.define("web_pwa_oca.ServiceWorker", function (require) {{
|
||||
"use strict";
|
||||
|
||||
{pwa_requires}
|
||||
|
||||
{pwa_init}
|
||||
{pwa_core_event_install}
|
||||
{pwa_core_event_activate}
|
||||
{pwa_core_event_fetch}
|
||||
}});
|
||||
"""
|
||||
|
||||
def _get_js_pwa_requires(self):
|
||||
return """
|
||||
const PWA = require('web_pwa_oca.PWA');
|
||||
"""
|
||||
|
||||
def _get_js_pwa_init(self):
|
||||
return """
|
||||
const oca_pwa = new PWA({});
|
||||
""".format(
|
||||
self._get_pwa_params()
|
||||
)
|
||||
|
||||
def _get_js_pwa_core_event_install_impl(self):
|
||||
return """
|
||||
evt.waitUntil(oca_pwa.installWorker());
|
||||
self.skipWaiting();
|
||||
"""
|
||||
|
||||
def _get_js_pwa_core_event_activate_impl(self):
|
||||
return """
|
||||
console.log('[ServiceWorker] Activating...');
|
||||
evt.waitUntil(oca_pwa.activateWorker());
|
||||
self.clients.claim();
|
||||
"""
|
||||
|
||||
def _get_js_pwa_core_event_fetch_impl(self):
|
||||
return ""
|
||||
|
||||
@route("/service-worker.js", type="http", auth="public")
|
||||
def render_service_worker(self):
|
||||
"""Route to register the service worker in the 'main' scope ('/')"""
|
||||
|
||||
sw_code = self.JS_PWA_MAIN.format(
|
||||
**{
|
||||
"pwa_scripts": self._get_pwa_scripts(),
|
||||
"pwa_requires": self._get_js_pwa_requires(),
|
||||
"pwa_init": self._get_js_pwa_init(),
|
||||
"pwa_core_event_install": self.JS_PWA_CORE_EVENT_INSTALL.format(
|
||||
self._get_js_pwa_core_event_install_impl()
|
||||
),
|
||||
"pwa_core_event_activate": self.JS_PWA_CORE_EVENT_ACTIVATE.format(
|
||||
self._get_js_pwa_core_event_activate_impl()
|
||||
),
|
||||
"pwa_core_event_fetch": self.JS_PWA_CORE_EVENT_FETCH.format(
|
||||
self._get_js_pwa_core_event_fetch_impl()
|
||||
),
|
||||
}
|
||||
)
|
||||
return request.make_response(
|
||||
sw_code,
|
||||
[
|
||||
("Content-Type", "text/javascript;charset=utf-8"),
|
||||
("Content-Length", len(sw_code)),
|
||||
],
|
||||
)
|
||||
Reference in New Issue
Block a user