From f372ac541f6a90a741253acdfd35cf5f2cc97696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Wed, 5 Dec 2018 14:35:19 +0000 Subject: [PATCH] [IMP] mail: rename DM conversation This commit adds the possibility to customize the name of a DM conversation. To do so, click on the gear icon when hovering on a DM in the discuss sidebar. This feature intentionally removes the access to the settings of a DM, because the settings view only makes sense for non-DM conversations. Task-ID 1881001 --- addons/mail/models/mail_channel.py | 10 ++ addons/mail/static/src/js/discuss.js | 74 ++++++++++++- .../static/src/js/models/threads/dm_chat.js | 4 +- .../src/js/models/threads/document_thread.js | 11 -- .../static/src/js/models/threads/thread.js | 8 ++ addons/mail/static/src/xml/discuss.xml | 5 + addons/mail/static/tests/discuss_tests.js | 101 ++++++++++++++++++ 7 files changed, 200 insertions(+), 13 deletions(-) diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py index 778ee09d4c4..e17b134c38a 100644 --- a/addons/mail/models/mail_channel.py +++ b/addons/mail/models/mail_channel.py @@ -24,6 +24,7 @@ class ChannelPartner(models.Model): _table = 'mail_channel_partner' _rec_name = 'partner_id' + custom_channel_name = fields.Char('Custom channel name') partner_id = fields.Many2one('res.partner', string='Recipient', ondelete='cascade') partner_email = fields.Char('Email', related='partner_id.email', readonly=False) channel_id = fields.Many2one('mail.channel', string='Channel', ondelete='cascade') @@ -593,6 +594,7 @@ class Channel(models.Model): info['state'] = partner_channel.fold_state or 'open' info['is_minimized'] = partner_channel.is_minimized info['seen_message_id'] = partner_channel.seen_message_id.id + info['custom_channel_name'] = partner_channel.custom_channel_name # add members infos partner_ids = channel_partners.mapped('partner_id').ids @@ -743,6 +745,14 @@ class Channel(models.Model): # broadcast the channel header to the added partner self._broadcast(partner_ids) + @api.model + def channel_set_custom_name(self, channel_id, name=False): + domain = [('partner_id', '=', self.env.user.partner_id.id), ('channel_id.id', '=', channel_id)] + channel_partners = self.env['mail.channel.partner'].search(domain, limit=1) + channel_partners.write({ + 'custom_channel_name': name, + }) + @api.multi def notify_typing(self, is_typing, is_website_user=False): """ Broadcast the typing notification to channel members diff --git a/addons/mail/static/src/js/discuss.js b/addons/mail/static/src/js/discuss.js index a3dd72b4923..5a5bc9e106e 100644 --- a/addons/mail/static/src/js/discuss.js +++ b/addons/mail/static/src/js/discuss.js @@ -111,6 +111,72 @@ var PartnerInviteDialog = Dialog.extend({ }, }); +/** + * Widget : Rename Conversation Dialog + */ +var RenameConversationDialog = Dialog.extend({ + dialog_title: _t("Rename conversation"), + template: 'mail.RenameConversationDialog', + /** + * @override + * @param {integer|string} channelID id of the channel + * @param {function} callback to call when successfully renaming + * conversation. + */ + init: function (parent, channelID, callback) { + this._channelID = channelID; + this._callback = callback; + + this._super(parent, { + title: 'Rename conversation', + size: 'medium', + buttons: [{ + text: _t("Rename"), + close: true, + classes: 'btn-primary o_mail_conversation_rename', + click: this._rename.bind(this), + }, { + text: _t("Discard"), + close: true, + }], + }); + }, + /** + * @override + * @returns {$.Promise} + */ + start: function () { + var channel = this.call('mail_service', 'getChannel', this._channelID); + this.$('input').val(channel.getName()); + return this._super.apply(this, arguments); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @returns {$.Promise} + */ + _rename: function () { + var self = this; + var name = this.$('input').val(); + return this._rpc({ + model: 'mail.channel', + method: 'channel_set_custom_name', + args: [this._channelID], + kwargs: { + name: name, + } + }).then(function (updatedName) { + var channel = self.call('mail_service', 'getThread', self._channelID); + channel.setName(updatedName); + self._callback(); + }); + }, +}); + /** * Widget : Moderator reject message dialog * @@ -1223,7 +1289,13 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, { * @param {MouseEvent} ev */ _onChannelSettingsClicked: function (ev) { - var threadID = $(ev.target).data('thread-id'); + ev.stopPropagation(); + var threadID = $(ev.currentTarget).data('thread-id'); + var thread = this.call('mail_service', 'getThread', threadID); + if (thread.getType() === 'dm_chat') { + new RenameConversationDialog(this, threadID, this._updateThreads.bind(this)).open(); + return; + } this.do_action({ type: 'ir.actions.act_window', res_model: 'mail.channel', diff --git a/addons/mail/static/src/js/models/threads/dm_chat.js b/addons/mail/static/src/js/models/threads/dm_chat.js index 767a6e32edd..5e69dbeff8c 100644 --- a/addons/mail/static/src/js/models/threads/dm_chat.js +++ b/addons/mail/static/src/js/models/threads/dm_chat.js @@ -12,6 +12,8 @@ var DMChat = TwoUserChannel.extend({ * @override * @param {Object} params * @param {Object} params.data + * @param {string|undefined} [params.custom_channel_name] if set, use this + * custom name for this DM * @param {Object[]} params.data.direct_partner * @param {integer} params.data.direct_partner[0].id * @param {string} params.data.direct_partner[0].im_status @@ -23,7 +25,7 @@ var DMChat = TwoUserChannel.extend({ var data = params.data; this._directPartnerID = data.direct_partner[0].id; - this._name = data.direct_partner[0].name; + this._name = data.custom_channel_name || data.direct_partner[0].name; this._status = data.direct_partner[0].im_status; this._type = 'dm_chat'; }, diff --git a/addons/mail/static/src/js/models/threads/document_thread.js b/addons/mail/static/src/js/models/threads/document_thread.js index f90da991960..d902d69765c 100644 --- a/addons/mail/static/src/js/models/threads/document_thread.js +++ b/addons/mail/static/src/js/models/threads/document_thread.js @@ -168,17 +168,6 @@ var DocumentThread = Thread.extend({ this._mustFetchMessageIDs = false; this._messageIDs = messageIDs; }, - /** - * Set the name of this document thread - * - * This is useful if the name of the document related to the document thread - * has changed - * - * @param {string} newName - */ - setName: function (newName) { - this._name = newName; - }, //-------------------------------------------------------------------------- // Private diff --git a/addons/mail/static/src/js/models/threads/thread.js b/addons/mail/static/src/js/models/threads/thread.js index 8c2beb8bbfa..068e69b9c32 100644 --- a/addons/mail/static/src/js/models/threads/thread.js +++ b/addons/mail/static/src/js/models/threads/thread.js @@ -271,6 +271,14 @@ var Thread = AbstractThread.extend(ServicesMixin, { markAsPreviewed: function () { this._previewed = true; }, + /** + * Set the name of this thread + * + * @param {string} newName + */ + setName: function (newName) { + this._name = newName; + }, //-------------------------------------------------------------------------- // Private diff --git a/addons/mail/static/src/xml/discuss.xml b/addons/mail/static/src/xml/discuss.xml index 90084a886bd..98430c81ce1 100644 --- a/addons/mail/static/src/xml/discuss.xml +++ b/addons/mail/static/src/xml/discuss.xml @@ -218,6 +218,11 @@ + +
+ +
+
diff --git a/addons/mail/static/tests/discuss_tests.js b/addons/mail/static/tests/discuss_tests.js index c8de7ae5450..993cc1581d2 100644 --- a/addons/mail/static/tests/discuss_tests.js +++ b/addons/mail/static/tests/discuss_tests.js @@ -1398,5 +1398,106 @@ QUnit.test('select emoji replaces cursor position', function (assert) { }); }); +QUnit.test('rename DM conversation', function (assert) { + assert.expect(11); + var done = assert.async(); + + this.data.initMessaging = { + channel_slots: { + channel_direct_message: [{ + id: 1, + channel_type: "chat", + create_uid: 3, + direct_partner: [{ + id: 7, + im_status: 'online', + name: 'Demo User', + }], + }], + }, + }; + + createDiscuss({ + id: 1, + context: {}, + params: {}, + data: this.data, + services: this.services, + session: { partner_id: 3 }, + mockRPC: function (route, args) { + if (args.method === 'channel_set_custom_name') { + assert.step(args.method); + assert.strictEqual(args.args[0], 1); + assert.strictEqual(args.kwargs.name, "Demo"); + return $.when("Demo"); + } + return this._super.apply(this, arguments); + }, + }) + .then(function (discuss) { + var $dm = discuss.$('.o_mail_discuss_item[data-thread-id=1]'); + assert.isVisible($dm, "should display DM in the discuss sidebar"); + assert.strictEqual($dm.find('.o_thread_name').text().trim(), "Demo User"); + + // The settings icon is only shown when hovering on sidebar item. + // helpter dom.click needs the element to be visible, hence the + // hack on display of this icon. + discuss.$('.o_mail_channel_settings').css('display', 'block'); + testUtils.dom.click(discuss.$('.o_mail_channel_settings')); + + assert.isVisible($('.modal-dialog')); + assert.strictEqual($('.modal-title').text(), "Rename conversation"); + assert.isVisible($('.o_mail_discuss_rename_channel_input')); + assert.strictEqual($('.o_mail_discuss_rename_channel_input').val(), "Demo User"); + + testUtils.fields.editInput($('.o_mail_discuss_rename_channel_input'), "Demo"); + testUtils.dom.click($('.o_mail_conversation_rename')); + $dm = discuss.$('.o_mail_discuss_item[data-thread-id=1]'); + assert.verifySteps(['channel_set_custom_name']); + assert.strictEqual($dm.find('.o_thread_name').text().trim(), "Demo"); + + discuss.destroy(); + done(); + }); +}); + +QUnit.test('custom-named DM conversation', function (assert) { + assert.expect(2); + var done = assert.async(); + + this.data.initMessaging = { + channel_slots: { + channel_direct_message: [{ + id: 1, + channel_type: "chat", + create_uid: 3, + direct_partner: [{ + id: 7, + im_status: 'online', + name: 'Demo User', + }], + custom_channel_name: 'My Buddy', + }], + }, + }; + + createDiscuss({ + id: 1, + context: {}, + params: {}, + data: this.data, + services: this.services, + session: { partner_id: 3 }, + }) + .then(function (discuss) { + var $dm = discuss.$('.o_mail_discuss_item[data-thread-id=1]'); + assert.isVisible($dm, "should display DM in the discuss sidebar"); + assert.strictEqual($dm.find('.o_thread_name').text().trim(), "My Buddy"); + + discuss.destroy(); + done(); + }); +}); + }); });