summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Theys <seb@odoo.com>2020-09-02 12:21:07 +0000
committerSébastien Theys <seb@odoo.com>2020-09-03 09:33:38 +0000
commit781bf9ec2eb5606d76ba3afa61cf06b5c3ac85fc (patch)
tree63e4553759b13830bf82a915a74353c02b081464
parent45ba62817d8a82129a2bae44cae9e3757529bdce (diff)
[FIX] mail: add open chat when clicking on author im status icon
task-2329538 closes odoo/odoo#57006 X-original-commit: bfb8d99baaadedb2d0492b6f378b13b3330d496a Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com> Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
-rw-r--r--addons/mail/static/src/components/chat_window/chat_window.js3
-rw-r--r--addons/mail/static/src/components/message/message.js5
-rw-r--r--addons/mail/static/src/components/message/message.xml1
-rw-r--r--addons/mail/static/src/components/message/message_tests.js124
-rw-r--r--addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.js25
-rw-r--r--addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.scss6
-rw-r--r--addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.xml2
-rw-r--r--addons/mail/static/src/components/thread_view/thread_view.xml2
8 files changed, 164 insertions, 4 deletions
diff --git a/addons/mail/static/src/components/chat_window/chat_window.js b/addons/mail/static/src/components/chat_window/chat_window.js
index 7f9b53d2670..43353c6086f 100644
--- a/addons/mail/static/src/components/chat_window/chat_window.js
+++ b/addons/mail/static/src/components/chat_window/chat_window.js
@@ -226,6 +226,9 @@ class ChatWindow extends Component {
if (isEventHandled(ev, 'Message.authorOpenProfile')) {
return;
}
+ if (isEventHandled(ev, 'PartnerImStatusIcon.openChat')) {
+ return;
+ }
this.chatWindow.focus();
}
diff --git a/addons/mail/static/src/components/message/message.js b/addons/mail/static/src/components/message/message.js
index 499c462efe9..e63d35332ea 100644
--- a/addons/mail/static/src/components/message/message.js
+++ b/addons/mail/static/src/components/message/message.js
@@ -166,8 +166,9 @@ class Message extends Component {
return false;
}
if (
- this.message.originThread &&
- this.message.originThread.correspondent === this.message.author
+ this.threadView &&
+ this.threadView.thread &&
+ this.threadView.thread.correspondent === this.message.author
) {
return false;
}
diff --git a/addons/mail/static/src/components/message/message.xml b/addons/mail/static/src/components/message/message.xml
index b0a41947c88..d739cb1769f 100644
--- a/addons/mail/static/src/components/message/message.xml
+++ b/addons/mail/static/src/components/message/message.xml
@@ -27,6 +27,7 @@
'o-message-selected': props.isSelected,
'o_Message_partnerImStatusIcon-mobile': env.messaging.device.isMobile,
}"
+ hasOpenChat="hasAuthorOpenChat"
partnerLocalId="message.author.localId"
/>
</t>
diff --git a/addons/mail/static/src/components/message/message_tests.js b/addons/mail/static/src/components/message/message_tests.js
index 3d7bf1da396..df964458fea 100644
--- a/addons/mail/static/src/components/message/message_tests.js
+++ b/addons/mail/static/src/components/message/message_tests.js
@@ -9,6 +9,7 @@ const {
afterNextRender,
beforeEach,
createRootComponent,
+ nextAnimationFrame,
start,
} = require('mail/static/src/utils/test_utils.js');
@@ -829,6 +830,129 @@ QUnit.test('data-oe-id & data-oe-model link redirection on click', async functio
);
});
+QUnit.test('chat with author should be opened after clicking on his avatar', async function (assert) {
+ assert.expect(4);
+
+ this.data['res.partner'].records.push({ id: 10 });
+ this.data['res.users'].records.push({ partner_id: 10 });
+ await this.start({
+ hasChatWindow: true,
+ });
+ const message = this.env.models['mail.message'].create({
+ author: [['insert', { id: 10 }]],
+ id: 10,
+ });
+ await this.createMessageComponent(message);
+ assert.containsOnce(
+ document.body,
+ '.o_Message_authorAvatar',
+ "message should have the author avatar"
+ );
+ assert.hasClass(
+ document.querySelector('.o_Message_authorAvatar'),
+ 'o_redirect',
+ "author avatar should have the redirect style"
+ );
+
+ await afterNextRender(() =>
+ document.querySelector('.o_Message_authorAvatar').click()
+ );
+ assert.containsOnce(
+ document.body,
+ '.o_ChatWindow_thread',
+ "chat window with thread should be opened after clicking on author avatar"
+ );
+ assert.strictEqual(
+ document.querySelector('.o_ChatWindow_thread').dataset.correspondentId,
+ message.author.id.toString(),
+ "chat with author should be opened after clicking on his avatar"
+ );
+});
+
+QUnit.test('chat with author should be opened after clicking on his im status icon', async function (assert) {
+ assert.expect(4);
+
+ this.data['res.partner'].records.push({ id: 10 });
+ this.data['res.users'].records.push({ partner_id: 10 });
+ await this.start({
+ hasChatWindow: true,
+ });
+ const message = this.env.models['mail.message'].create({
+ author: [['insert', { id: 10, im_status: 'online' }]],
+ id: 10,
+ });
+ await this.createMessageComponent(message);
+ assert.containsOnce(
+ document.body,
+ '.o_Message_partnerImStatusIcon',
+ "message should have the author im status icon"
+ );
+ assert.hasClass(
+ document.querySelector('.o_Message_partnerImStatusIcon'),
+ 'o-has-open-chat',
+ "author im status icon should have the open chat style"
+ );
+
+ await afterNextRender(() =>
+ document.querySelector('.o_Message_partnerImStatusIcon').click()
+ );
+ assert.containsOnce(
+ document.body,
+ '.o_ChatWindow_thread',
+ "chat window with thread should be opened after clicking on author im status icon"
+ );
+ assert.strictEqual(
+ document.querySelector('.o_ChatWindow_thread').dataset.correspondentId,
+ message.author.id.toString(),
+ "chat with author should be opened after clicking on his im status icon"
+ );
+});
+
+QUnit.test('open chat with author on avatar click should be disabled when currently chatting with the author', async function (assert) {
+ assert.expect(3);
+
+ this.data['mail.channel'].records.push({
+ channel_type: 'chat',
+ members: [this.data.currentPartnerId, 10],
+ public: 'private',
+ });
+ this.data['res.partner'].records.push({ id: 10 });
+ this.data['res.users'].records.push({ partner_id: 10 });
+ await this.start({
+ hasChatWindow: true,
+ });
+ const correspondent = this.env.models['mail.partner'].insert({ id: 10 });
+ const message = this.env.models['mail.message'].create({
+ author: [['link', correspondent]],
+ id: 10,
+ });
+ const thread = await correspondent.getChat();
+ const threadView = this.env.models['mail.thread_view'].create({
+ thread: [['link', thread]],
+ });
+ await this.createMessageComponent(message, {
+ threadViewLocalId: threadView.localId,
+ });
+ assert.containsOnce(
+ document.body,
+ '.o_Message_authorAvatar',
+ "message should have the author avatar"
+ );
+ assert.doesNotHaveClass(
+ document.querySelector('.o_Message_authorAvatar'),
+ 'o_redirect',
+ "author avatar should not have the redirect style"
+ );
+
+ document.querySelector('.o_Message_authorAvatar').click();
+ await nextAnimationFrame();
+ assert.containsNone(
+ document.body,
+ '.o_ChatWindow',
+ "should have no thread opened after clicking on author avatar when currently chatting with the author"
+ );
+});
+
});
});
});
diff --git a/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.js b/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.js
index 7150c2914a9..2a9af18f79a 100644
--- a/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.js
+++ b/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.js
@@ -2,6 +2,7 @@ odoo.define('mail/static/src/components/partner_im_status_icon/partner_im_status
'use strict';
const useStore = require('mail/static/src/component_hooks/use_store/use_store.js');
+const { markEventHandled } = require('mail/static/src/utils/utils.js');
const { Component } = owl;
@@ -34,15 +35,37 @@ class PartnerImStatusIcon extends Component {
return this.env.models['mail.partner'].get(this.props.partnerLocalId);
}
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onClick(ev) {
+ if (!this.props.hasOpenChat) {
+ return;
+ }
+ markEventHandled(ev, 'PartnerImStatusIcon.openChat');
+ this.partner.openChat();
+ }
+
}
Object.assign(PartnerImStatusIcon, {
defaultProps: {
- hasBackground: true
+ hasBackground: true,
+ hasOpenChat: false,
},
props: {
partnerLocalId: String,
hasBackground: Boolean,
+ /**
+ * Determines whether a click on `this` should open a chat with
+ * `this.partner`.
+ */
+ hasOpenChat: Boolean,
},
template: 'mail.PartnerImStatusIcon',
});
diff --git a/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.scss b/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.scss
index d5791c2f0c6..608c281aa0a 100644
--- a/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.scss
+++ b/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.scss
@@ -25,6 +25,12 @@
// Style
// ------------------------------------------------------------------
+.o_PartnerImStatusIcon {
+ &.o-has-open-chat {
+ cursor: pointer;
+ }
+}
+
.o_PartnerImStatusIcon_innerBackground {
color: white;
}
diff --git a/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.xml b/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.xml
index 23879cc6b39..ca20a547f2b 100644
--- a/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.xml
+++ b/addons/mail/static/src/components/partner_im_status_icon/partner_im_status_icon.xml
@@ -7,9 +7,11 @@
'o-away': partner and partner.im_status === 'away',
'o-background': !props.hasBackground,
'o-bot': partner and env.messaging.partnerRoot === partner,
+ 'o-has-open-chat': props.hasOpenChat,
'o-offline': partner and partner.im_status === 'offline',
'o-online': partner and partner.im_status === 'online',
}"
+ t-on-click="_onClick"
t-att-data-partner-local-id="partner ? partner.localId : undefined"
>
<t t-if="partner" name="rootCondition">
diff --git a/addons/mail/static/src/components/thread_view/thread_view.xml b/addons/mail/static/src/components/thread_view/thread_view.xml
index eead567fa1e..12352f67fe5 100644
--- a/addons/mail/static/src/components/thread_view/thread_view.xml
+++ b/addons/mail/static/src/components/thread_view/thread_view.xml
@@ -2,7 +2,7 @@
<templates xml:space="preserve">
<t t-name="mail.ThreadView" owl="1">
- <div class="o_ThreadView" t-att-data-thread-local-id="threadView and threadView.thread and threadView.thread.localId">
+ <div class="o_ThreadView" t-att-data-correspondent-id="threadView and threadView.thread and threadView.thread.correspondent and threadView.thread.correspondent.id" t-att-data-thread-local-id="threadView and threadView.thread and threadView.thread.localId">
<t t-if="threadView">
<t t-if="threadView.isShowingLoading" name="loadingCondition">
<div class="o_ThreadView_loading">