示例#1
0
 def.then(function (value) {
     if (value === 'denied') {
         utils.send_notification(_t('Permission denied'), _t('Odoo will not have the permission to send native notifications on this device.'));
     } else {
         utils.send_notification(_t('Permission granted'), _t('Odoo has now the permission to send you native notifications on this device.'));
     }
 });
示例#2
0
 _.each(this._activities, function (activity) {
     var note = mailUtils.parseAndTransform(activity.note || '', mailUtils.inline);
     var is_blank = (/^\s*$/).test(note);
     if (!is_blank) {
         activity.note = mailUtils.parseAndTransform(activity.note, mailUtils.addLink);
     } else {
         activity.note = '';
     }
 });
示例#3
0
                    var prom = new Promise(function(innerResolve, innerReject) {
                        var partnerName = partnerInfo.full_name;
                        var partnerID = partnerInfo.partner_id;
                        var parsedEmail = mailUtils.parseEmail(partnerName);

                        var dialog = new viewDialogs.FormViewDialog(self, {
                            res_model: 'res.partner',
                            res_id: partnerID,
                            context: {
                                active_model: self._model,
                                active_id: self.context.default_res_id,
                                force_email: true,
                                ref: 'compound_context',
                                default_name: parsedEmail[0],
                                default_email: parsedEmail[1],
                            },
                            title: _t("Please complete customer's informations"),
                            disable_multiple_selection: true,
                        }).open();
                        dialog.on('closed', self, function () {
                            innerResolve();
                        });
                        dialog.opened().then(function () {
                            dialog.form_view.on('on_button_cancel', self, function () {
                                namesToRemove.push(partnerName);
                                if (partnerID) {
                                    recipientIDsToRemove.push(partnerID);
                                }
                            });
                        });
                    });
示例#4
0
 search_partner: function (search_val, limit) {
     var def = $.Deferred();
     var values = [];
     // search among prefetched partners
     var search_regexp = new RegExp(_.str.escapeRegExp(utils.unaccent(search_val)), 'i');
     _.each(mention_partner_suggestions, function (partners) {
         if (values.length < limit) {
             values = values.concat(_.filter(partners, function (partner) {
                 return session.partner_id !== partner.id && search_regexp.test(partner.name);
             })).splice(0, limit);
         }
     });
     if (!values.length) {
         // extend the research to all users
         def = this._rpc({
                 model: 'res.partner',
                 method: 'im_search',
                 args: [search_val, limit || 20],
             }, {
                 shadow: true,
             });
     } else {
         def = $.when(values);
     }
     return def.then(function (values) {
         var autocomplete_data = _.map(values, function (value) {
             return { id: value.id, value: value.name, label: value.name };
         });
         return _.sortBy(autocomplete_data, 'label');
     });
 },
示例#5
0
    _notifyIncomingMessage: function (message) {
        if (this.call('bus_service', 'isOdooFocused')) {
            // no need to notify
            return;
        }
        var title = _t("New message");
        if (message.hasAuthor()) {
            title = _.escape(message.getAuthorName());
        }
        var content = mailUtils.parseAndTransform(message.getBody(), mailUtils.stripHTML)
            .substr(0, PREVIEW_MSG_MAX_SIZE);

        if (!this.call('bus_service', 'isOdooFocused')) {
            this._outOfFocusUnreadMessageCounter++;
            var tabTitle = _.str.sprintf(
                _t("%d Messages"),
                this._outOfFocusUnreadMessageCounter
            );
            this.trigger_up('set_title_part', {
                part: '_chat',
                title: tabTitle
            });
        }

        this.call('bus_service', 'sendNotification', title, content);
    },
示例#6
0
            _.each(recipient_popups, function (partner_info) {
                var deferred = $.Deferred();
                emails_deferred.push(deferred);

                var partner_name = partner_info.full_name;
                var partner_id = partner_info.partner_id;
                var parsed_email = utils.parse_email(partner_name);

                var dialog = new form_common.FormViewDialog(self, {
                    res_model: 'res.partner',
                    res_id: partner_id,
                    context: {
                        force_email: true,
                        ref: "compound_context",
                        default_name: parsed_email[0],
                        default_email: parsed_email[1],
                    },
                    title: _t("Please complete partner's informations"),
                    disable_multiple_selection: true,
                }).open();
                dialog.on('closed', self, function () {
                    deferred.resolve();
                });
                dialog.opened().then(function () {
                    dialog.view_form.on('on_button_cancel', self, function () {
                        names_to_remove.push(partner_name);
                        if (partner_id) {
                            recipient_ids_to_remove.push(partner_id);
                        }
                    });
                });
            });
示例#7
0
        recipient_done.then(function (partner_ids) {
            var context = {
                default_parent_id: self.id,
                default_body: utils.get_text2html(self.$input.val()),
                default_attachment_ids: _.pluck(self.get('attachment_ids'), 'id'),
                default_partner_ids: partner_ids,
                default_is_log: self.options.is_log,
                mail_post_autofollow: true,
            };

            if (self.context.default_model && self.context.default_res_id) {
                context.default_model = self.context.default_model;
                context.default_res_id = self.context.default_res_id;
            }

            self.do_action({
                type: 'ir.actions.act_window',
                res_model: 'mail.compose.message',
                view_mode: 'form',
                view_type: 'form',
                views: [[false, 'form']],
                target: 'new',
                context: context,
            }, {
                on_close: function() {
                    self.trigger('need_refresh');
                    var parent = self.getParent();
                    chat_manager.get_messages({model: parent.model, res_id: parent.res_id});
                },
            }).then(self.trigger.bind(self, 'close_composer'));
        });
示例#8
0
 return $.when(this.mention_prefetched_partners).then(function (prefetched_partners) {
     // filter prefetched partners with the given search string
     var suggestions = [];
     var limit = self.options.mention_fetch_limit;
     var search_regexp = new RegExp(_.str.escapeRegExp(utils.unaccent(search)), 'i');
     _.each(prefetched_partners, function (partners) {
         if (limit > 0) {
             var filtered_partners = _.filter(partners, function (partner) {
                 return partner.email && search_regexp.test(partner.email) ||
                        partner.name && search_regexp.test(utils.unaccent(partner.name));
             });
             if (filtered_partners.length) {
                 suggestions.push(filtered_partners.slice(0, limit));
                 limit -= filtered_partners.length;
             }
         }
     });
     if (!suggestions.length && !self.options.mention_partners_restricted) {
         // no result found among prefetched partners, fetch other suggestions
         suggestions = self.mention_fetch_throttled('res.partner', 'get_mention_suggestions', {
             limit: limit,
             search: search,
         });
     }
     return suggestions;
 });
示例#9
0
 _postMessage: function (data) {
     // This message will be received from the mail composer as html content
     // subtype but the urls will not be linkified. If the mail composer
     // takes the responsibility to linkify the urls we end up with double
     // linkification a bit everywhere. Ideally we want to keep the content
     // as text internally and only make html enrichment at display time but
     // the current design makes this quite hard to do.
     var body = mailUtils.parseAndTransform(_.str.trim(data.content), mailUtils.addLink);
     body = this._generateEmojis(body);
     var messageData = {
         partner_ids: data.partner_ids,
         channel_ids: _.map(data.channel_ids, function (channelID) {
            return [4, channelID, false];
         }),
         body: body,
         attachment_ids: data.attachment_ids,
         canned_response_ids: data.canned_response_ids,
     };
     if ('subject' in data) {
         messageData.subject = data.subject;
     }
     return this._super.apply(this, arguments).then(function () {
         return messageData;
     });
 },
示例#10
0
        recipientDoneDef.then(function (partnerIDs) {
            var context = {
                default_parent_id: self.id,
                default_body: mailUtils.getTextToHTML(self.$input.val()),
                default_attachment_ids: _.pluck(self.get('attachment_ids'), 'id'),
                default_partner_ids: partnerIDs,
                default_is_log: self.options.isLog,
                mail_post_autofollow: true,
            };

            if (self.context.default_model && self.context.default_res_id) {
                context.default_model = self.context.default_model;
                context.default_res_id = self.context.default_res_id;
            }

            var action = {
                type: 'ir.actions.act_window',
                res_model: 'mail.compose.message',
                view_mode: 'form',
                view_type: 'form',
                views: [[false, 'form']],
                target: 'new',
                context: context,
            };
            self.do_action(action, {
                on_close: self.trigger.bind(self, 'need_refresh'),
            }).then(self.trigger.bind(self, 'close_composer'));
        });
示例#11
0
 this.canned_timeout = setTimeout(function() {
     var canned_responses = self._getCannedResponses();
     var matches = fuzzy.filter(utils.unaccent(search), _.pluck(canned_responses, 'source'));
     var indexes = _.pluck(matches.slice(0, self.options.mention_fetch_limit), 'index');
     def.resolve(_.map(indexes, function (i) {
         return canned_responses[i];
     }));
 }, 500);
示例#12
0
 this._cannedTimeout = setTimeout(function () {
     var cannedResponses = self.call('mail_service', 'getCannedResponses');
     var matches = fuzzy.filter(mailUtils.unaccent(search), _.pluck(cannedResponses, 'source'));
     var indexes = _.pluck(matches.slice(0, self.options.mentionFetchLimit), 'index');
     def.resolve(_.map(indexes, function (index) {
         return cannedResponses[index];
     }));
 }, 500);
示例#13
0
 mention_get_canned_responses: function (search) {
     var canned_responses = chat_manager.get_canned_responses();
     var matches = fuzzy.filter(utils.unaccent(search), _.pluck(canned_responses, 'source'));
     var indexes = _.pluck(matches.slice(0, this.options.mention_fetch_limit), 'index');
     return _.map(indexes, function (i) {
         return canned_responses[i];
     });
 },
示例#14
0
function notify_incoming_message (msg, options) {
    if (bus.is_odoo_focused() && options.is_displayed) {
        // no need to notify
        return;
    }
    var title = _t('New message');
    if (msg.author_id[1]) {
        title = _.escape(msg.author_id[1]);
    }
    var content = utils.parse_and_transform(msg.body, utils.strip_html).substr(0, preview_msg_max_size);

    if (!bus.is_odoo_focused()) {
        global_unread_counter++;
        var tab_title = _.str.sprintf(_t("%d Messages"), global_unread_counter);
        web_client.set_title_part("_chat", tab_title);
    }

    utils.send_notification(title, content);
}
示例#15
0
文件: chatter.js 项目: astirpe/odoo
 _.each(thread_recipients, function (recipient) {
     var parsed_email = recipient[1] && mailUtils.parseEmail(recipient[1]);
     suggested_partners.push({
         checked: true,
         partner_id: recipient[0],
         full_name: recipient[1],
         name: parsed_email[0],
         email_address: parsed_email[1],
         reason: recipient[2],
     });
 });
示例#16
0
文件: channel.js 项目: bud-e/odoo
 getPreview: function () {
     var result = this._super.apply(this, arguments);
     if (!this.isTwoUserThread()) {
         result.imageSRC = '/web/image/mail.channel/' + this.getID() + '/image_small';
     }
     var lastMessage = this.getLastMessage();
     return _.extend(result, {
         author: lastMessage ? lastMessage.getDisplayedAuthor() : '',
         body: lastMessage ? mailUtils.parseAndTransform(lastMessage.getBody(), mailUtils.inline) : '',
         date: lastMessage ? lastMessage.getDate() : moment(),
         isMyselfAuthor: this.hasMessages() && this.getLastMessage().isMyselfAuthor(),
     });
 },
示例#17
0
 _searchPartnerPrefetch: function (searchVal, limit) {
     var values = [];
     var searchRegexp = new RegExp(_.str.escapeRegExp(mailUtils.unaccent(searchVal)), 'i');
     _.each(this._mentionPartnerSuggestions, function (partners) {
         if (values.length < limit) {
             values = values.concat(_.filter(partners, function (partner) {
                 return (session.partner_id !== partner.id) &&
                         searchRegexp.test(partner.name);
             })).splice(0, limit);
         }
     });
     return values;
 },
示例#18
0
 _.each(thread_recipients, function (recipient) {
     var parsed_email = utils.parse_email(recipient[1]);
     if (_.indexOf(email_addresses, parsed_email[1]) === -1) {
         self.suggested_partners.push({
             checked: true,
             partner_id: recipient[0],
             full_name: recipient[1],
             name: parsed_email[0],
             email_address: parsed_email[1],
             reason: recipient[2],
         });
     }
 });
示例#19
0
    post_message: function (data, options) {
        options = options || {};

        // This message will be received from the mail composer as html content subtype
        // but the urls will not be linkified. If the mail composer takes the responsibility
        // to linkify the urls we end up with double linkification a bit everywhere.
        // Ideally we want to keep the content as text internally and only make html
        // enrichment at display time but the current design makes this quite hard to do.
        var body = utils.parse_and_transform(_.str.trim(data.content), utils.add_link);

        var msg = {
            partner_ids: data.partner_ids,
            body: body,
            attachment_ids: data.attachment_ids,
        };
        if ('subject' in data) {
            msg.subject = data.subject;
        }
        if ('channel_id' in options) {
            // post a message in a channel or execute a command
            return ChannelModel.call(data.command ? 'execute_command' : 'message_post', [options.channel_id], _.extend(msg, {
                message_type: 'comment',
                content_subtype: 'html',
                subtype: 'mail.mt_comment',
                command: data.command,
            }));
        }
        if ('model' in options && 'res_id' in options) {
            // post a message in a chatter
            _.extend(msg, {
                content_subtype: data.content_subtype,
                context: data.context,
                message_type: data.message_type,
                subtype: data.subtype,
                subtype_id: data.subtype_id,
            });

            var model = new Model(options.model);
            return model.call('message_post', [options.res_id], msg).then(function (msg_id) {
                return MessageModel.call('message_format', [msg_id]).then(function (msgs) {
                    msgs[0].model = options.model;
                    msgs[0].res_id = options.res_id;
                    add_message(msgs[0]);
                });
            });
        }
    },
示例#20
0
 getPreview: function () {
     var id, title;
     if (this.isLinkedToDocumentThread()) {
         id = this.getDocumentModel() + '_' + this.getDocumentID();
         title = this.getDocumentName();
     } else {
         id = 'mailbox_inbox';
         title = this.hasSubject() ? this.getSubject() : this.getDisplayedAuthor();
     }
     return {
         author: this.getDisplayedAuthor(),
         body: mailUtils.parseAndTransform(this.getBody(), mailUtils.inline),
         date: this.getDate(),
         documentModel: this.getDocumentModel(),
         documentID: this.getDocumentID(),
         id: id,
         imageSRC: this._getModuleIcon() || this.getAvatarSource(),
         status: this.status,
         title: title,
     };
 },
示例#21
0
    _processBody: function () {
        var self = this;

        _.each(emojis, function (emoji) {
            var unicode = emoji.unicode;
            var regexp = new RegExp("(?:^|\\s|<[a-z]*>)(" + unicode + ")(?=\\s|$|</[a-z]*>)", 'g');
            var originalBody = self.body;
            self._body = self._body.replace(regexp,
                ' <span class="o_mail_emoji">' + unicode + '</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(self._body, 'o_mail_emoji') > 200) {
                self._body = originalBody;
            }
        });

        // add anchor tags to urls
        self._body = mailUtils.parseAndTransform(self._body, mailUtils.addLink);
    },
示例#22
0
 var filtered_partners = _.filter(partners, function (partner) {
     return partner.email && search_regexp.test(partner.email) ||
            partner.name && search_regexp.test(utils.unaccent(partner.name));
 });
示例#23
0
文件: activity.js 项目: CRITEAN/Odoo
 _.each(self.activities, function (activity) {
     if (activity.note) {
         activity.note = utils.parse_and_transform(activity.note, utils.add_link);
     }
 });
示例#24
0
 this.$('.o_mail_timestamp').each(function () {
     var date = $(this).data('date');
     $(this).html(mailUtils.timeFromNow(date));
 });
示例#25
0
 def.then(function () {
     utils.send_notification('Permission granted', 'Odoo has now the permission to send you native notifications on this device.');
 });
示例#26
0
 _mentionGetCommands: function (search) {
     var searchRegexp = new RegExp(_.str.escapeRegExp(mailUtils.unaccent(search)), 'i');
     return _.filter(this._mentionCommands, function (command) {
         return searchRegexp.test(command.name);
     }).slice(0, this.options.mentionFetchLimit);
 },
示例#27
0
 get_message_body_preview: function (message_body) {
     return utils.parse_and_transform(message_body, utils.inline);
 },
示例#28
0
 mention_get_commands: function (search) {
     var search_regexp = new RegExp(_.str.escapeRegExp(utils.unaccent(search)), 'i');
     return _.filter(this.mention_commands, function (command) {
         return search_regexp.test(command.name);
     }).slice(0, this.options.mention_fetch_limit);
 },
示例#29
0
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',
        attachment_ids: data.attachment_ids,
        subject: data.subject,
        email_from: data.email_from,
        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),
    };

    _.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");
        msg.body = msg.body.replace(regexp, ' <span class="o_mail_emoji">'+emoji_substitutions[key]+'</span> ');
    });

    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 && msg.author_id[1] ||
                               msg.email_from || _t('Anonymous');
    }

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

    // Compute the avatar_url
    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';
    });

    return msg;
}