summaryrefslogtreecommitdiff
path: root/addons/bus/static/src/js/services
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/bus/static/src/js/services
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/bus/static/src/js/services')
-rw-r--r--addons/bus/static/src/js/services/bus_service.js154
1 files changed, 154 insertions, 0 deletions
diff --git a/addons/bus/static/src/js/services/bus_service.js b/addons/bus/static/src/js/services/bus_service.js
new file mode 100644
index 00000000..39b61da5
--- /dev/null
+++ b/addons/bus/static/src/js/services/bus_service.js
@@ -0,0 +1,154 @@
+odoo.define('bus.BusService', function (require) {
+"use strict";
+
+var CrossTab = require('bus.CrossTab');
+var core = require('web.core');
+var ServicesMixin = require('web.ServicesMixin');
+const session = require('web.session');
+
+var BusService = CrossTab.extend(ServicesMixin, {
+ dependencies : ['local_storage'],
+
+ // properties
+ _audio: null,
+
+ /**
+ * As the BusService doesn't extend AbstractService, we have to replicate
+ * here what is done in AbstractService
+ *
+ * @param {Object} env
+ */
+ init: function (env) {
+ this.env = env;
+ this._super();
+ },
+
+ /**
+ * Replicate the behavior of AbstractService:
+ *
+ * Directly calls the requested service, instead of triggering a
+ * 'call_service' event up, which wouldn't work as services have no parent.
+ *
+ * @param {OdooEvent} ev
+ */
+ _trigger_up: function (ev) {
+ if (ev.name === 'call_service') {
+ const payload = ev.data;
+ let args = payload.args || [];
+ if (payload.service === 'ajax' && payload.method === 'rpc') {
+ // ajax service uses an extra 'target' argument for rpc
+ args = args.concat(ev.target);
+ }
+ const service = this.env.services[payload.service];
+ const result = service[payload.method].apply(service, args);
+ payload.callback(result);
+ }
+ },
+ /**
+ * This method is necessary in order for this Class to be used to instantiate services
+ *
+ * @abstract
+ */
+ start: function () {},
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * Send a notification, and notify once per browser's tab
+ *
+ * @param {string} title
+ * @param {string} content
+ * @param {function} [callback] if given callback will be called when user clicks on notification
+ */
+ sendNotification: function (title, content, callback) {
+ if (window.Notification && Notification.permission === "granted") {
+ if (this.isMasterTab()) {
+ try {
+ this._sendNativeNotification(title, content, callback);
+ } catch (error) {
+ // Notification without Serviceworker in Chrome Android doesn't works anymore
+ // So we fallback to do_notify() in this case
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=481856
+ if (error.message.indexOf('ServiceWorkerRegistration') > -1) {
+ this.do_notify(title, content);
+ this._beep();
+ } else {
+ throw error;
+ }
+ }
+ }
+ } else {
+ this.do_notify(title, content);
+ if (this.isMasterTab()) {
+ this._beep();
+ }
+ }
+ },
+ /**
+ * Register listeners on notifications received on this bus service
+ *
+ * @param {Object} receiver
+ * @param {function} func
+ */
+ onNotification: function () {
+ this.on.apply(this, ["notification"].concat(Array.prototype.slice.call(arguments)));
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Lazily play the 'beep' audio on sent notification
+ *
+ * @private
+ */
+ _beep: function () {
+ if (typeof(Audio) !== "undefined") {
+ if (!this._audio) {
+ this._audio = new Audio();
+ var ext = this._audio.canPlayType("audio/ogg; codecs=vorbis") ? ".ogg" : ".mp3";
+ this._audio.src = session.url("/mail/static/src/audio/ting" + ext);
+ }
+ Promise.resolve(this._audio.play()).catch(_.noop);
+ }
+ },
+ /**
+ * Show a browser notification
+ *
+ * @private
+ * @param {string} title
+ * @param {string} content
+ * @param {function} [callback] if given callback will be called when user clicks on notification
+ */
+ _sendNativeNotification: function (title, content, callback) {
+ var notification = new Notification(
+ // The native Notification API works with plain text and not HTML
+ // unescaping is safe because done only at the **last** step
+ _.unescape(title),
+ {
+ body: _.unescape(content),
+ icon: "/mail/static/src/img/odoobot_transparent.png"
+ });
+ notification.onclick = function () {
+ window.focus();
+ if (this.cancel) {
+ this.cancel();
+ } else if (this.close) {
+ this.close();
+ }
+ if (callback) {
+ callback();
+ }
+ };
+ },
+
+});
+
+core.serviceRegistry.add('bus_service', BusService);
+
+return BusService;
+
+});