summaryrefslogtreecommitdiff
path: root/addons/bus/static/src/js/web_client_bus.js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/bus/static/src/js/web_client_bus.js')
-rw-r--r--addons/bus/static/src/js/web_client_bus.js109
1 files changed, 109 insertions, 0 deletions
diff --git a/addons/bus/static/src/js/web_client_bus.js b/addons/bus/static/src/js/web_client_bus.js
new file mode 100644
index 00000000..6683b565
--- /dev/null
+++ b/addons/bus/static/src/js/web_client_bus.js
@@ -0,0 +1,109 @@
+odoo.define('bus.WebClient', function (require) {
+ "use strict";
+
+ const core = require('web.core');
+ const WebClient = require('web.WebClient');
+
+ const _t = core._t;
+
+ WebClient.include({
+
+ //----------------------------------------------------------------------
+ // Public
+ //----------------------------------------------------------------------
+
+ /**
+ * Detects the presence of assets in DOM's HEAD
+ *
+ * @override
+ */
+ async start() {
+ this._assetsChangedNotificationId = null;
+ this._assets = {};
+ await this._super(...arguments);
+ },
+ /**
+ * Assigns handler to bus notification
+ *
+ * @override
+ */
+ show_application() {
+ const shown = this._super(...arguments);
+ document.querySelectorAll('*[data-asset-xmlid]').forEach(el => {
+ this._assets[el.getAttribute('data-asset-xmlid')] = el.getAttribute('data-asset-version');
+ });
+ this.call('bus_service', 'onNotification', this, this._onNotification);
+ this.call('bus_service', 'addChannel', 'bundle_changed');
+ return shown;
+ },
+
+ //----------------------------------------------------------------------
+ // Private
+ //----------------------------------------------------------------------
+
+ /**
+ * Displays one notification on user's screen when assets have changed
+ *
+ * @private
+ */
+ _displayBundleChangedNotification() {
+ if (!this._assetsChangedNotificationId) {
+ // Wrap the notification inside a delay.
+ // The server may be overwhelmed with recomputing assets
+ // We wait until things settle down
+ clearTimeout(this._bundleNotifTimerID);
+ this._bundleNotifTimerID = setTimeout(() => {
+ this._assetsChangedNotificationId = this.call('notification', 'notify', {
+ title: _t('Refresh'),
+ message: _t('The page appears to be out of date.'),
+ sticky: true,
+ onClose: () => {
+ this._assetsChangedNotificationId = null;
+ },
+ buttons: [{
+ text: _t('Refresh'),
+ primary: true,
+ click: () => {
+ window.location.reload(true);
+ }
+ }],
+ });
+ }, this._getBundleNotificationDelay());
+ }
+ },
+ /**
+ * Computes a random delay to avoid hammering the server
+ * when bundles change with all the users reloading
+ * at the same time
+ *
+ * @private
+ * @return {number} delay in milliseconds
+ */
+ _getBundleNotificationDelay() {
+ return 10000 + Math.floor(Math.random()*50) * 1000;
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Reacts to bus's notification
+ *
+ * @private
+ * @param {Array} notifications: list of received notifications
+ */
+ _onNotification(notifications) {
+ for (const notif of notifications) {
+ if (notif[0][1] === 'bundle_changed') {
+ const bundleXmlId = notif[1][0];
+ const bundleVersion = notif[1][1];
+ if (bundleXmlId in this._assets && bundleVersion !== this._assets[bundleXmlId]) {
+ this._displayBundleChangedNotification();
+ break;
+ }
+ }
+ }
+ }
+ });
+});