From 341fb5f2406f1f7e43cdb36e6b0c52348468a6a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Tue, 20 Nov 2018 09:58:07 +0000 Subject: [PATCH 1/3] [FIX] mail: no '#' prefix in DM name Before this commit, DMs had the prefix '#' in their displayed name (e.g. '#Demo User'). This commit fixes the issue by putting this prefix only on non-chat DMs. In particular, mailboxes, DMs and Livechats no longer show this prefix. This change is also visible in the breadcrumb of the discuss app. Task-ID 1911738 --- addons/mail/static/src/js/discuss.js | 2 +- addons/mail/static/src/js/models/threads/channel.js | 10 ---------- .../static/src/js/models/threads/multi_user_channel.js | 10 ++++++++++ .../tests/thread_window/blank_thread_window_tests.js | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/addons/mail/static/src/js/discuss.js b/addons/mail/static/src/js/discuss.js index 032ab1bddef..e93adeaae30 100644 --- a/addons/mail/static/src/js/discuss.js +++ b/addons/mail/static/src/js/discuss.js @@ -852,7 +852,7 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, { // Update control panel before focusing the composer, otherwise // focus is on the searchview - self.set("title", '#' + self._thread.getName()); + self.set("title", self._thread.getTitle()); self._updateControlPanel(); self._updateControlPanelButtons(self._thread); diff --git a/addons/mail/static/src/js/models/threads/channel.js b/addons/mail/static/src/js/models/threads/channel.js index 808e8b7fbca..7dc460ddc37 100644 --- a/addons/mail/static/src/js/models/threads/channel.js +++ b/addons/mail/static/src/js/models/threads/channel.js @@ -221,16 +221,6 @@ var Channel = SearchableThread.extend(ThreadTypingMixin, { isMyselfAuthor: this.hasMessages() && this.getLastMessage().isMyselfAuthor(), }); }, - /** - * Returns the title to display in thread window's headers. - * For channels, the title is prefixed with "#". - * - * @override - * @returns {string|Object} the name of the thread by default (see getName) - */ - getTitle: function () { - return "#" + this._super.apply(this, arguments); - }, /** * Get the UUID of the channel. * This is a string that uniquely links this channel to a server channel. diff --git a/addons/mail/static/src/js/models/threads/multi_user_channel.js b/addons/mail/static/src/js/models/threads/multi_user_channel.js index c1681744127..85d60fc1183 100644 --- a/addons/mail/static/src/js/models/threads/multi_user_channel.js +++ b/addons/mail/static/src/js/models/threads/multi_user_channel.js @@ -25,6 +25,16 @@ var MultiUserChannel = Channel.extend({ // Public //-------------------------------------------------------------------------- + /** + * Returns the title to display in thread window's headers. + * For channels, the title is prefixed with "#". + * + * @override + * @returns {string|Object} the name of the thread by default (see getName) + */ + getTitle: function () { + return "#" + this._super.apply(this, arguments); + }, /** * States whether this thread has the mass mailing setting active or not. * This is a server-side setting, that determine the type of composer that diff --git a/addons/mail/static/tests/thread_window/blank_thread_window_tests.js b/addons/mail/static/tests/thread_window/blank_thread_window_tests.js index 883494a4ec6..17654290c80 100644 --- a/addons/mail/static/tests/thread_window/blank_thread_window_tests.js +++ b/addons/mail/static/tests/thread_window/blank_thread_window_tests.js @@ -229,7 +229,7 @@ QUnit.test('open new DM chat from blank thread window', function (assert) { selectDef.then(function () { assert.strictEqual($('.o_thread_window').length, 1, "should be a single window"); - assert.strictEqual($('.o_thread_window_title').text().trim(), "#DemoUser1", + assert.strictEqual($('.o_thread_window_title').text().trim(), "DemoUser1", "should have thread window of the DM chat with 'DemoUser1'"); assert.strictEqual($('.o_composer_text_field').length, 1, "should have a composer in the DM chat window"); @@ -285,7 +285,7 @@ QUnit.test('open already detached DM chat from blank thread window', function (a assert.strictEqual($('.o_thread_window').length, 1, "should be a single window"); - assert.strictEqual($('.o_thread_window_title').text().trim(), "#DemoUser1", + assert.strictEqual($('.o_thread_window_title').text().trim(), "DemoUser1", "should have thread window of the DM chat with 'DemoUser1'"); assert.strictEqual($('.o_composer_text_field').length, 1, "should have a composer in the DM chat window"); @@ -304,7 +304,7 @@ QUnit.test('open already detached DM chat from blank thread window', function (a selectDef.then(function () { assert.strictEqual($('.o_thread_window').length, 1, "should now have a single thread window open"); - assert.strictEqual($('.o_thread_window_title').text().trim(), "#DemoUser1", + assert.strictEqual($('.o_thread_window_title').text().trim(), "DemoUser1", "the remaining thread window should be the DM chat with 'DemoUser1'"); self.unpatchAutocomplete(); From c22539fd8c7a838eb9d5ed3c4c78eac3dee720da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Mon, 12 Nov 2018 09:35:32 +0000 Subject: [PATCH 2/3] [ADD] mail:tests: add test for https://github.com/odoo/odoo/commit/6d5df714a7970f69a27296c157b08772ceac5b7d --- addons/mail/static/tests/discuss_tests.js | 79 +++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/addons/mail/static/tests/discuss_tests.js b/addons/mail/static/tests/discuss_tests.js index 31f479d50cc..e22d24f5002 100644 --- a/addons/mail/static/tests/discuss_tests.js +++ b/addons/mail/static/tests/discuss_tests.js @@ -513,6 +513,85 @@ QUnit.test('@ mention with special chars', function (assert) { }); }); +QUnit.test('@ mention in mailing channel', function (assert) { + assert.expect(8); + var done = assert.async(); + + var fetchListenersDef = $.Deferred(); + + this.data.initMessaging = { + channel_slots: { + channel_channel: [{ + id: 1, + channel_type: "channel", + name: "general", + mass_mailing: true, + }], + }, + }; + + createDiscuss({ + id: 1, + context: {}, + params: {}, + data: this.data, + services: this.services, + mockRPC: function (route, args) { + if (args.method === 'channel_fetch_listeners') { + fetchListenersDef.resolve(); + return $.when([ + {id: 1, name: 'Admin'}, + ]); + } + return this._super.apply(this, arguments); + }, + }) + .then(function (discuss) { + var $general = discuss.$('.o_mail_discuss_sidebar') + .find('.o_mail_discuss_item[data-thread-id=1]'); + + // click on general + $general.click(); + // 1st composer: basic composer (hidden), 2nd composer: extended (shown) + var $input = discuss.$('textarea.o_composer_text_field').eq(1); + assert.ok($input.length, "should display a composer input"); + + // Simulate '@' typed by user with mocked Window.getSelection + // Note: focus is needed in order to trigger rpc 'channel_fetch_listeners' + $input.focus(); + $input.val("@"); + $input.trigger('keyup'); + + fetchListenersDef + .then(concurrency.delay.bind(concurrency, 0)) + .then(function () { + assert.strictEqual(discuss.$('.dropup.o_composer_mention_dropdown.show').length, 1, + "dropup menu for partner mentions should be open"); + + var $mention = discuss.$('.o_mention_proposition'); + assert.strictEqual($mention.length, 1, + "should display 1 partner mention proposition"); + + // correct mention proposition + assert.ok($mention.hasClass('active'), + "partner mention should be active"); + assert.strictEqual($mention.data('id'), 1, + "partner mention should link to the correct partner id"); + assert.strictEqual($mention.find('.o_mention_name').text(), "Admin", + "partner mention should display the correct partner name"); + + // equivalent to $mentionPropositions.find('active').click(); + $input.trigger($.Event('keyup', {which: $.ui.keyCode.ENTER})); + + assert.ok($input.is(':focus'), "composer body should have focus"); + assert.notOk(discuss.$('.o_composer_subject').is(':focus')); + + discuss.destroy(); + done(); + }); + }); +}); + QUnit.test('no crash focusout emoji button', function (assert) { assert.expect(3); var done = assert.async(); From c45c5bb41167b61c4788f3369d3688b8791effc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandre=20K=C3=BChn?= Date: Thu, 22 Nov 2018 11:00:02 +0000 Subject: [PATCH 3/3] [FIX] mail: messaging menu show undated DM previews last This commit fixes two related issues: 1. Previews without any message should not be dated. Before this commit, when a channel or dm preview had no date, it was displaying the current date. This commit fixes the issue by not showing the date for those previews. 2. Dates previews should appear before undated previews. Before this commit, undated previews were considered similarly as dated previews in the ordering of previews in the messaging menu. Since DMs are shown before Channels, any pinned DM without any message were displayed on top of messages with some message. This commit fixes the issue by putting undated previews after dated ones. This rule is applied before considering type of the thread (i.e. DMs before channels). Task-ID 1912001 --- .../static/src/js/models/threads/channel.js | 2 +- .../static/src/js/services/mail_manager.js | 14 ++-- .../systray/systray_messaging_menu_tests.js | 65 +++++++++++++++++++ 3 files changed, 72 insertions(+), 9 deletions(-) diff --git a/addons/mail/static/src/js/models/threads/channel.js b/addons/mail/static/src/js/models/threads/channel.js index 7dc460ddc37..ff90ca8edfb 100644 --- a/addons/mail/static/src/js/models/threads/channel.js +++ b/addons/mail/static/src/js/models/threads/channel.js @@ -217,7 +217,7 @@ var Channel = SearchableThread.extend(ThreadTypingMixin, { return _.extend(result, { author: lastMessage ? lastMessage.getDisplayedAuthor() : '', body: lastMessage ? mailUtils.parseAndTransform(lastMessage.getBody(), mailUtils.inline) : '', - date: lastMessage ? lastMessage.getDate() : moment(), + date: lastMessage ? lastMessage.getDate() : undefined, isMyselfAuthor: this.hasMessages() && this.getLastMessage().isMyselfAuthor(), }); }, diff --git a/addons/mail/static/src/js/services/mail_manager.js b/addons/mail/static/src/js/services/mail_manager.js index c21089b7095..6a49cdf0183 100644 --- a/addons/mail/static/src/js/services/mail_manager.js +++ b/addons/mail/static/src/js/services/mail_manager.js @@ -1108,8 +1108,9 @@ var MailManager = AbstractService.extend({ * Sort previews * * 1. unread, - * 2. two-user thread, - * 3. date, + * 2. dated previews + * 3. two-user thread, + * 4. date, * * @private * @param {Object[]} previews @@ -1118,13 +1119,10 @@ var MailManager = AbstractService.extend({ _sortPreviews: function (previews) { var res = previews.sort(function (p1, p2) { var unreadDiff = Math.min(1, p2.unreadCounter) - Math.min(1, p1.unreadCounter); + var datedDiff = !!p2.date - !!p1.date; var isTwoUserThreadDiff = p2.isTwoUserThread - p1.isTwoUserThread; - var dateDiff = (!!p2.date - !!p1.date) || - ( - p2.date && - p2.date.diff(p1.date) - ); - return unreadDiff || isTwoUserThreadDiff || dateDiff; + var dateDiff = p2.date && p2.date.diff(p1.date); + return unreadDiff || datedDiff || isTwoUserThreadDiff || dateDiff; }); return res; }, diff --git a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js index 2df0f7ac522..f67703c4679 100644 --- a/addons/mail/static/tests/systray/systray_messaging_menu_tests.js +++ b/addons/mail/static/tests/systray/systray_messaging_menu_tests.js @@ -625,5 +625,70 @@ QUnit.test("messaging menu widget: channel seen notification", function ( assert messagingMenu.destroy(); }); +QUnit.test("messaging menu widget: preview with no message should be undated", function ( assert ) { + assert.expect(2); + + // remove any message on the channel + this.data['mail.channel'].records[0].channel_message_ids = []; + this.data['mail.message'].records[0].channel_ids = []; + + var messagingMenu = new MessagingMenu(); + testUtils.addMockEnvironment(messagingMenu, { + services: this.services, + data: this.data, + }); + + messagingMenu.appendTo($('#qunit-fixture')); + + messagingMenu.$('.dropdown-toggle').click(); + + assert.strictEqual(messagingMenu.$('.o_mail_preview').length, 1, + "should have two previews in messaging menu"); + + assert.ok(_.isEmpty(messagingMenu.$('.o_mail_preview .o_last_message_date').text().trim()), + "should have preview as undated"); + + messagingMenu.destroy(); +}); + +QUnit.test("messaging menu widget: sort dated previews before undated previews", function ( assert ) { + assert.expect(5); + + var dm = { + id: 2, + name: "DM", + channel_type: "chat", + }; + + this.data['mail.channel'].records.push(dm); + this.data.initMessaging.channel_slots.direct_message = [dm]; + + var messagingMenu = new MessagingMenu(); + testUtils.addMockEnvironment(messagingMenu, { + services: this.services, + data: this.data, + }); + + messagingMenu.appendTo($('#qunit-fixture')); + messagingMenu.$('.dropdown-toggle').click(); + + assert.strictEqual(messagingMenu.$('.o_mail_preview').length, 2, + "should have two previews in messaging menu"); + + var $preview1 = messagingMenu.$('.o_mail_preview').eq(0); + var $preview2 = messagingMenu.$('.o_mail_preview').eq(1); + + assert.strictEqual($preview1.data('preview-id'), 1, + "should have channel preview as the 1st preview (dated preview)"); + assert.notOk(_.isEmpty($preview1.find('.o_last_message_date').text().trim()), + "should have channel preview as dated"); + assert.strictEqual($preview2.data('preview-id'), 2, + "should have DM preview as the 1st preview (non-dated preview)"); + assert.ok(_.isEmpty($preview2.find('.o_last_message_date').text().trim()), + "should have DM preview as undated"); + + messagingMenu.destroy(); +}); + }); });