javascriptodooodoo-11

override javascript methods in mail/static/src/js/chat_manager.js of Odoo 11


I am trying to override 2 Javascript functions in the Odoo 11 under mail/static/src/js/chat_manager.js

  1. The first one is make_message
function make_message (data) {
    var msg = {
        id: data.id,
        author_id: data.author_id,
        body: data.body || "",
        date: moment(time.str_to_datetime(data.date)),
        message_type: data.message_type,
        subtype_description: data.subtype_description,
        is_author: data.author_id && data.author_id[0] === session.partner_id,
        is_note: data.is_note,
        is_system_notification: (data.message_type === 'notification' && data.model === 'mail.channel')
            || data.info === 'transient_message',
        attachment_ids: data.attachment_ids || [],
        subject: data.subject,
        email_from: data.email_from,
        customer_email_status: data.customer_email_status,
        customer_email_data: data.customer_email_data,
        record_name: data.record_name,
        tracking_value_ids: data.tracking_value_ids,
        channel_ids: data.channel_ids,
        model: data.model,
        res_id: data.res_id,
        url: session.url("/mail/view?message_id=" + data.id),
        module_icon:data.module_icon,
    };

    _.each(_.keys(emoji_substitutions), function (key) {
        var escaped_key = String(key).replace(/([.*+?=^!:${}()|[\]\/\\])/g, '\\$1');
        var regexp = new RegExp("(?:^|\\s|<[a-z]*>)(" + escaped_key + ")(?=\\s|$|</[a-z]*>)", "g");
        var msg_bak = msg.body;
        msg.body = msg.body.replace(regexp, ' <span class="o_mail_emoji">'+emoji_substitutions[key]+'</span> ');

        // Idiot-proof limit. If the user had the amazing idea of copy-pasting thousands of emojis,
        // the image rendering can lead to memory overflow errors on some browsers (e.g. Chrome).
        // Set an arbitrary limit to 200 from which we simply don't replace them (anyway, they are
        // already replaced by the unicode counterpart).
        if (_.str.count(msg.body, 'o_mail_emoji') > 200) {
            msg.body = msg_bak;
        }
    });

    function property_descr(channel) {
        return {
            enumerable: true,
            get: function () {
                return _.contains(msg.channel_ids, channel);
            },
            set: function (bool) {
                if (bool) {
                    add_channel_to_message(msg, channel);
                } else {
                    msg.channel_ids = _.without(msg.channel_ids, channel);
                }
            }
        };
    }

    Object.defineProperties(msg, {
        is_starred: property_descr("channel_starred"),
        is_needaction: property_descr("channel_inbox"),
    });

    if (_.contains(data.needaction_partner_ids, session.partner_id)) {
        msg.is_needaction = true;
    }
    if (_.contains(data.starred_partner_ids, session.partner_id)) {
        msg.is_starred = true;
    }
    if (msg.model === 'mail.channel') {
        var real_channels = _.without(msg.channel_ids, 'channel_inbox', 'channel_starred');
        var origin = real_channels.length === 1 ? real_channels[0] : undefined;
        var channel = origin && chat_manager.get_channel(origin);
        if (channel) {
            msg.origin_id = origin;
            msg.origin_name = channel.name;
        }
    }

    // Compute displayed author name or email
    if ((!msg.author_id || !msg.author_id[0]) && msg.email_from) {
        msg.mailto = msg.email_from;
    } else {
        msg.displayed_author = (msg.author_id === ODOOBOT_ID) && "OdooBot" ||
                               msg.author_id && msg.author_id[1] ||
                               msg.email_from || _t('Anonymous');
    }

    // Don't redirect on author clicked of self-posted or OdooBot messages
    msg.author_redirect = !msg.is_author && msg.author_id !== ODOOBOT_ID;

    // Compute the avatar_url
    if (msg.author_id === ODOOBOT_ID) {
        msg.avatar_src = "/mail/static/src/img/odoo_o.png";
    } else if (msg.author_id && msg.author_id[0]) {
        msg.avatar_src = "/web/image/res.partner/" + msg.author_id[0] + "/image_small";
    } else if (msg.message_type === 'email') {
        msg.avatar_src = "/mail/static/src/img/email_icon.png";
    } else {
        msg.avatar_src = "/mail/static/src/img/smiley/avatar.jpg";
    }

    // add anchor tags to urls
    msg.body = utils.parse_and_transform(msg.body, utils.add_link);

    // Compute url of attachments
    _.each(msg.attachment_ids, function(a) {
        a.url = '/web/content/' + a.id + '?download=true';
    });

    // format date to the local only once by message
    // can not be done in preprocess, since it alter the original value
    if (msg.tracking_value_ids && msg.tracking_value_ids.length) {
        _.each(msg.tracking_value_ids, function(f) {
            if (f.field_type === 'datetime') {
                var format = 'LLL';
                if (f.old_value) {
                    f.old_value = moment.utc(f.old_value).local().format(format);
                }
                if (f.new_value) {
                    f.new_value = moment.utc(f.new_value).local().format(format);
                }
            } else if (f.field_type === 'date') {
                var format = 'LL';
                if (f.old_value) {
                    f.old_value = moment(f.old_value).local().format(format);
                }
                if (f.new_value) {
                    f.new_value = moment(f.new_value).local().format(format);
                }
            }
        });
    }

    return msg;
}
  1. The second one is on_partner_notification
function on_partner_notification (data) {
    if (data.info === "unsubscribe") {
        var channel = chat_manager.get_channel(data.id);
        if (channel) {
            var msg;
            if (_.contains(['public', 'private'], channel.type)) {
                msg = _.str.sprintf(_t('You unsubscribed from <b>%s</b>.'), _.escape(channel.name));
            } else {
                msg = _.str.sprintf(_t('You unpinned your conversation with <b>%s</b>.'), _.escape(channel.name));
            }
            remove_channel(channel);
            chat_manager.bus.trigger("unsubscribe_from_channel", data.id);
            web_client.do_notify(_t("Unsubscribed"), msg);
        }
    } else if (data.type === 'toggle_star') {
        on_toggle_star_notification(data);
    } else if (data.type === 'mark_as_read') {
        on_mark_as_read_notification(data);
    } else if (data.type === 'mark_as_unread') {
        on_mark_as_unread_notification(data);
    } else if (data.info === 'channel_seen') {
        on_channel_seen_notification(data);
    } else if (data.info === 'transient_message') {
        on_transient_message_notification(data);
    } else if (data.type === 'activity_updated') {
        onActivityUpdateNodification(data);
    }else {
        on_chat_session_notification(data);
    }
}

But both functions do not belong to a Widget class, so I have no idea how to override them in my custom javascript module? Does anyone have an idea how to override them?

<odoo>

  <template id="assets_backend" name="my_custom_module assets" inherit_id="web.assets_backend">
    <xpath expr="." position="inside">
      <script type="text/javascript" src="/my_custom_module/static/src/js/custom_chat_manager.js" />
    </xpath>
  </template>

</odoo>
odoo.define("my_custom_module.chat_manager", function (require) {
    "use strict";

    var chatManager = require("mail.chat_manager");

    chatManager.on_partner_notification = function (data) {
        // custom code comes to here ...
    };

   
    chatManager.make_massage = function (data) {
        // custom code comes to here ...
    }
    
    
});

But they do not seem to work !!!!

Thank you in advance


Solution

  • You can see in the chat_manager class that there are two functions that are exposed for extensibility purposes, make_message and make_channel unlike on_partner_notification function

    You can't override the on_partner_notification function, you can only modify the module exports object.