[IMP] mail, *: convert ThreadPreview to use Channel instead of Thread
* = im_livechat, rating, test_mail_full Part of task-2948676. closes odoo/odoo#99342 Related: odoo/enterprise#30921 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { ThreadPreview } from '@mail/components/channel_preview_view/channel_preview_view';
|
||||
|
||||
import { patch } from 'web.utils';
|
||||
|
||||
const components = { ThreadPreview };
|
||||
|
||||
patch(components.ThreadPreview.prototype, 'im_livechat/static/src/components/channel_preview_view/channel_preview_view.js', {
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
image(...args) {
|
||||
if (this.threadPreviewView.thread.channel.channel_type === 'livechat') {
|
||||
return '/mail/static/src/img/smiley/avatar.jpg';
|
||||
}
|
||||
return this._super(...args);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { patchRecordMethods } from '@mail/model/model_core';
|
||||
// ensure that the model definition is loaded before the patch
|
||||
import '@mail/models/channel_preview_view';
|
||||
|
||||
patchRecordMethods('ChannelPreviewView', {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_computeImageUrl() {
|
||||
if (this.channel.channel_type === 'livechat') {
|
||||
return '/mail/static/src/img/smiley/avatar.jpg';
|
||||
}
|
||||
return this._super();
|
||||
},
|
||||
});
|
||||
@@ -7,12 +7,11 @@ patchRecordMethods('NotificationListView', {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_computeFilteredThreads() {
|
||||
_computeFilteredChannels() {
|
||||
if (this.filter === 'livechat') {
|
||||
return this.messaging.models['Thread'].all(thread =>
|
||||
thread.channel &&
|
||||
thread.channel.channel_type === 'livechat' &&
|
||||
thread.isPinned
|
||||
return this.messaging.models['Channel'].all(channel =>
|
||||
channel.channel_type === 'livechat' &&
|
||||
channel.thread.isPinned
|
||||
);
|
||||
}
|
||||
return this._super();
|
||||
|
||||
+2
-2
@@ -48,7 +48,7 @@ QUnit.test('livechats should be in "chat" filter', async function (assert) {
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
`.o_ThreadPreview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]`,
|
||||
`.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]`,
|
||||
"livechat should be listed in 'all' tab/filter of messaging menu"
|
||||
);
|
||||
|
||||
@@ -62,7 +62,7 @@ QUnit.test('livechats should be in "chat" filter', async function (assert) {
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
`.o_ThreadPreview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]`,
|
||||
`.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]`,
|
||||
"livechat should be listed in 'chat' tab/filter of messaging menu"
|
||||
);
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import { registerMessagingComponent } from '@mail/utils/messaging_component';
|
||||
|
||||
const { Component } = owl;
|
||||
|
||||
export class ThreadPreview extends Component {
|
||||
export class ChannelPreviewView extends Component {
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -15,37 +15,18 @@ export class ThreadPreview extends Component {
|
||||
useRefToModel({ fieldName: 'markAsReadRef', refName: 'markAsRead' });
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the image route of the thread.
|
||||
*
|
||||
* @returns {string}
|
||||
* @returns {ChannelPreviewView}
|
||||
*/
|
||||
image() {
|
||||
if (!this.threadPreviewView.thread.channel) {
|
||||
return '/mail/static/src/img/smiley/avatar.jpg';
|
||||
}
|
||||
if (this.threadPreviewView.thread.channel.correspondent) {
|
||||
return this.threadPreviewView.thread.channel.correspondent.avatarUrl;
|
||||
}
|
||||
return `/web/image/mail.channel/${this.threadPreviewView.thread.id}/avatar_128?unique=${this.threadPreviewView.thread.channel.avatarCacheKey}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {ThreadPreviewView}
|
||||
*/
|
||||
get threadPreviewView() {
|
||||
get channelPreviewView() {
|
||||
return this.props.record;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object.assign(ThreadPreview, {
|
||||
Object.assign(ChannelPreviewView, {
|
||||
props: { record: Object },
|
||||
template: 'mail.ThreadPreview',
|
||||
template: 'mail.ChannelPreviewView',
|
||||
});
|
||||
|
||||
registerMessagingComponent(ThreadPreview);
|
||||
registerMessagingComponent(ChannelPreviewView);
|
||||
|
||||
@@ -1,71 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="mail.ThreadPreview" owl="1">
|
||||
<t t-if="threadPreviewView">
|
||||
<t t-name="mail.ChannelPreviewView" owl="1">
|
||||
<t t-if="channelPreviewView">
|
||||
<!--
|
||||
The preview template is used by the discuss in mobile, and by the systray
|
||||
menu in order to show preview of threads.
|
||||
-->
|
||||
<div class="o_NotificationListItem o_ThreadPreview d-flex flex-shrink-0 align-items-center p-1 cursor-pointer"
|
||||
t-att-class="{ 'o-muted': threadPreviewView.thread.channel.localMessageUnreadCounter === 0 }"
|
||||
<div class="o_NotificationListItem o_ChannelPreviewView d-flex flex-shrink-0 align-items-center p-1 cursor-pointer"
|
||||
t-att-class="{ 'o-muted': channelPreviewView.channel.localMessageUnreadCounter === 0 }"
|
||||
t-attf-class="{{ className }}"
|
||||
t-on-click="threadPreviewView.onClick"
|
||||
t-att-data-thread-id="threadPreviewView.thread.id"
|
||||
t-att-data-thread-model="threadPreviewView.thread.model"
|
||||
t-on-click="channelPreviewView.onClick"
|
||||
t-att-data-channel-id="channelPreviewView.channel.id"
|
||||
t-ref="root"
|
||||
>
|
||||
<div class="o_NotificationListItem_sidebar o_ThreadPreview_sidebar m-1">
|
||||
<div class="o_NotificationListItem_imageContainer o_ThreadPreview_imageContainer o_ThreadPreview_sidebarItem position-relative">
|
||||
<img class="o_NotificationListItem_image o_ThreadPreview_image w-100 h-100 rounded-circle" t-att-src="image()" alt="Thread Image"/>
|
||||
<t t-if="threadPreviewView.personaImStatusIconView">
|
||||
<div class="o_NotificationListItem_sidebar o_ChannelPreviewView_sidebar m-1">
|
||||
<div class="o_NotificationListItem_imageContainer o_ChannelPreviewView_imageContainer o_ChannelPreviewView_sidebarItem position-relative">
|
||||
<img class="o_NotificationListItem_image o_ChannelPreviewView_image w-100 h-100 rounded-circle" t-att-src="channelPreviewView.imageUrl" alt="Thread Image"/>
|
||||
<t t-if="channelPreviewView.personaImStatusIconView">
|
||||
<PersonaImStatusIcon
|
||||
className="'o_NotificationListItem_personaImStatusIcon o_ThreadPreview_personaImStatusIcon position-absolute bottom-0 end-0 d-flex align-items-center justify-content-center'"
|
||||
className="'o_NotificationListItem_personaImStatusIcon o_ChannelPreviewView_personaImStatusIcon position-absolute bottom-0 end-0 d-flex align-items-center justify-content-center'"
|
||||
classNameObj="{
|
||||
'o-isDeviceSmall': messaging.device.isSmall,
|
||||
'small': !messaging.device.isSmall,
|
||||
'o-muted': threadPreviewView.thread.channel.localMessageUnreadCounter === 0,
|
||||
'o-muted': channelPreviewView.channel.localMessageUnreadCounter === 0,
|
||||
}"
|
||||
record="threadPreviewView.personaImStatusIconView"
|
||||
record="channelPreviewView.personaImStatusIconView"
|
||||
/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_NotificationListItem_content o_ThreadPreview_content d-flex flex-column flex-grow-1 align-self-start m-2">
|
||||
<div class="o_NotificationListItem_header o_ThreadPreview_header d-flex align-items-baseline">
|
||||
<span class="o_NotificationListItem_name o_ThreadPreview_name text-truncate fw-bold" t-att-class="{ 'o-isDeviceSmall fs-5': messaging.device.isSmall, 'o-muted text-600': threadPreviewView.thread.channel.localMessageUnreadCounter === 0 }">
|
||||
<t t-esc="threadPreviewView.thread.displayName"/>
|
||||
<div class="o_NotificationListItem_content o_ChannelPreviewView_content d-flex flex-column flex-grow-1 align-self-start m-2">
|
||||
<div class="o_NotificationListItem_header o_ChannelPreviewView_header d-flex align-items-baseline">
|
||||
<span class="o_NotificationListItem_name o_ChannelPreviewView_name text-truncate fw-bold" t-att-class="{ 'o-isDeviceSmall fs-5': messaging.device.isSmall, 'o-muted text-600': channelPreviewView.channel.localMessageUnreadCounter === 0 }">
|
||||
<t t-esc="channelPreviewView.channel.displayName"/>
|
||||
</span>
|
||||
<t t-if="threadPreviewView.thread.channel.localMessageUnreadCounter > 1">
|
||||
<span class="o_NotificationListItem_counter o_ThreadPreview_counter mx-1 fw-bold">
|
||||
(<t t-esc="threadPreviewView.thread.channel.localMessageUnreadCounter"/>)
|
||||
<t t-if="channelPreviewView.channel.localMessageUnreadCounter > 1">
|
||||
<span class="o_NotificationListItem_counter o_ChannelPreviewView_counter mx-1 fw-bold">
|
||||
(<t t-esc="channelPreviewView.channel.localMessageUnreadCounter"/>)
|
||||
</span>
|
||||
</t>
|
||||
<t t-if="threadPreviewView.thread.rtcSessions.length > 0">
|
||||
<span class="o_ThreadPreview_callIndicator fa fa-volume-up mx-2" t-att-class="{ 'o-isCalling text-danger': threadPreviewView.thread.rtc }"/>
|
||||
<t t-if="channelPreviewView.thread.rtcSessions.length > 0">
|
||||
<span class="o_ChannelPreviewView_callIndicator fa fa-volume-up mx-2" t-att-class="{ 'o-isCalling text-danger': channelPreviewView.thread.rtc }"/>
|
||||
</t>
|
||||
<span class="flex-grow-1"/>
|
||||
<t t-if="threadPreviewView.thread.lastMessage and threadPreviewView.thread.lastMessage.date">
|
||||
<small class="o_NotificationListItem_date o_ThreadPreview_date flex-shrink-0 text-500" t-att-class="{ 'o-muted': threadPreviewView.thread.channel.localMessageUnreadCounter === 0 }">
|
||||
<t t-esc="threadPreviewView.thread.lastMessage.date.fromNow()"/>
|
||||
<t t-if="channelPreviewView.thread.lastMessage and channelPreviewView.thread.lastMessage.date">
|
||||
<small class="o_NotificationListItem_date o_ChannelPreviewView_date flex-shrink-0 text-500" t-att-class="{ 'o-muted': channelPreviewView.channel.localMessageUnreadCounter === 0 }">
|
||||
<t t-esc="channelPreviewView.thread.lastMessage.date.fromNow()"/>
|
||||
</small>
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_ThreadPreview_core d-flex align-items-baseline">
|
||||
<span class="o_NotificationListItem_coreItem o_NotificationListItem_inlineText o_ThreadPreview_coreItem o_ThreadPreview_inlineText me-2 text-truncate" t-att-class="{ 'o-empty': threadPreviewView.isEmpty }">
|
||||
<t t-if="threadPreviewView.lastTrackingValue">
|
||||
<TrackingValue value="threadPreviewView.lastTrackingValue"/>
|
||||
<div class="o_ChannelPreviewView_core d-flex align-items-baseline">
|
||||
<span class="o_NotificationListItem_coreItem o_NotificationListItem_inlineText o_ChannelPreviewView_coreItem o_ChannelPreviewView_inlineText me-2 text-truncate" t-att-class="{ 'o-empty': channelPreviewView.isEmpty }">
|
||||
<t t-if="channelPreviewView.lastTrackingValue">
|
||||
<TrackingValue value="channelPreviewView.lastTrackingValue"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-if="threadPreviewView.messageAuthorPrefixView">
|
||||
<MessageAuthorPrefix record="threadPreviewView.messageAuthorPrefixView"/>
|
||||
<t t-if="channelPreviewView.messageAuthorPrefixView">
|
||||
<MessageAuthorPrefix record="channelPreviewView.messageAuthorPrefixView"/>
|
||||
</t>
|
||||
<span class="o_ThreadPreview_messageBody" t-esc="threadPreviewView.inlineLastMessageBody"/>
|
||||
<span class="o_ChannelPreviewView_messageBody" t-esc="channelPreviewView.inlineLastMessageBody"/>
|
||||
</t>
|
||||
</span>
|
||||
<span class="flex-grow-1"/>
|
||||
<t t-if="threadPreviewView.thread.channel.localMessageUnreadCounter > 0">
|
||||
<span class="o_NotificationListItem_coreItem o_NotificationListItem_markAsRead o_ThreadPreview_coreItem o_ThreadPreview_markAsRead fa fa-check d-flex flex-shrink-0 ms-2 text-600 opacity-50 opacity-100-hover" title="Mark as Read" t-on-click="threadPreviewView.onClickMarkAsRead" t-ref="markAsRead"/>
|
||||
<t t-if="channelPreviewView.channel.localMessageUnreadCounter > 0">
|
||||
<span class="o_NotificationListItem_coreItem o_NotificationListItem_markAsRead o_ChannelPreviewView_coreItem o_ChannelPreviewView_markAsRead fa fa-check d-flex flex-shrink-0 ms-2 text-600 opacity-50 opacity-100-hover" title="Mark as Read" t-on-click="channelPreviewView.onClickMarkAsRead" t-ref="markAsRead"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-foreach="notificationListView.notificationViews" t-as="notificationView" t-key="notificationView.localId">
|
||||
<t t-if="notificationView.constructor.name === 'ThreadPreviewView'">
|
||||
<ThreadPreview
|
||||
<t t-if="notificationView.constructor.name === 'ChannelPreviewView'">
|
||||
<ChannelPreviewView
|
||||
className="'o_NotificationList_preview'"
|
||||
classNameObj="{ 'o-isDeviceSmall p-2': messaging.device.isSmall }"
|
||||
record="notificationView"
|
||||
|
||||
@@ -224,6 +224,10 @@ registerModel({
|
||||
inverse: 'channel',
|
||||
isCausal: true,
|
||||
}),
|
||||
channelPreviewViews: many('ChannelPreviewView', {
|
||||
inverse: 'channel',
|
||||
isCausal: true,
|
||||
}),
|
||||
channel_type: attr(),
|
||||
correspondent: one('Partner', {
|
||||
compute: '_computeCorrespondent',
|
||||
|
||||
@@ -6,7 +6,7 @@ import { clear } from '@mail/model/model_field_command';
|
||||
import { htmlToTextContentInline } from '@mail/js/utils';
|
||||
|
||||
registerModel({
|
||||
name: 'ThreadPreviewView',
|
||||
name: 'ChannelPreviewView',
|
||||
recordMethods: {
|
||||
/**
|
||||
* @param {MouseEvent} ev
|
||||
@@ -33,12 +33,21 @@ registerModel({
|
||||
this.thread.markAsSeen(this.thread.lastNonTransientMessage);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
_computeImageUrl() {
|
||||
if (this.channel.correspondent) {
|
||||
return this.channel.correspondent.avatarUrl;
|
||||
}
|
||||
return `/web/image/mail.channel/${this.channel.id}/avatar_128?unique=${this.channel.avatarCacheKey}`;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {string|FieldCommand}
|
||||
*/
|
||||
_computeInlineLastMessageBody() {
|
||||
if (!this.thread.lastMessage) {
|
||||
if (!this.thread || !this.thread.lastMessage) {
|
||||
return clear();
|
||||
}
|
||||
return htmlToTextContentInline(this.thread.lastMessage.prettyBody);
|
||||
@@ -52,20 +61,21 @@ registerModel({
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
* @returns {TrackingValue|FieldCommand}
|
||||
*/
|
||||
_computeLastTrackingValue() {
|
||||
if (this.thread.lastMessage && this.thread.lastMessage.lastTrackingValue) {
|
||||
if (this.thread && this.thread.lastMessage && this.thread.lastMessage.lastTrackingValue) {
|
||||
return this.thread.lastMessage.lastTrackingValue;
|
||||
}
|
||||
return clear();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
* @returns {Object|FieldCommand}
|
||||
*/
|
||||
_computeMessageAuthorPrefixView() {
|
||||
if (
|
||||
this.thread &&
|
||||
this.thread.lastMessage &&
|
||||
this.thread.lastMessage.author
|
||||
) {
|
||||
@@ -78,16 +88,23 @@ registerModel({
|
||||
* @returns {Object|FieldCommand}
|
||||
*/
|
||||
_computePersonaImStatusIconView() {
|
||||
if (!this.thread.channel.correspondent) {
|
||||
if (!this.channel.correspondent) {
|
||||
return clear();
|
||||
}
|
||||
if (this.thread.channel.correspondent.isImStatusSet) {
|
||||
if (this.channel.correspondent.isImStatusSet) {
|
||||
return {};
|
||||
}
|
||||
return clear();
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
channel: one('Channel', {
|
||||
identifying: true,
|
||||
inverse: 'channelPreviewViews',
|
||||
}),
|
||||
imageUrl: attr({
|
||||
compute: '_computeImageUrl',
|
||||
}),
|
||||
inlineLastMessageBody: attr({
|
||||
compute: '_computeInlineLastMessageBody',
|
||||
default: "",
|
||||
@@ -105,21 +122,20 @@ registerModel({
|
||||
markAsReadRef: attr(),
|
||||
messageAuthorPrefixView: one('MessageAuthorPrefixView', {
|
||||
compute: '_computeMessageAuthorPrefixView',
|
||||
inverse: 'threadPreviewViewOwner',
|
||||
inverse: 'channelPreviewViewOwner',
|
||||
isCausal: true,
|
||||
}),
|
||||
notificationListViewOwner: one('NotificationListView', {
|
||||
identifying: true,
|
||||
inverse: 'threadPreviewViews',
|
||||
inverse: 'channelPreviewViews',
|
||||
}),
|
||||
personaImStatusIconView: one('PersonaImStatusIconView', {
|
||||
compute: '_computePersonaImStatusIconView',
|
||||
inverse: 'threadPreviewViewOwner',
|
||||
inverse: 'channelPreviewViewOwner',
|
||||
isCausal: true,
|
||||
}),
|
||||
thread: one('Thread', {
|
||||
identifying: true,
|
||||
inverse: 'threadPreviewViews',
|
||||
related: 'channel.thread',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -13,12 +13,12 @@ registerModel({
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeMessage() {
|
||||
if (this.channelPreviewViewOwner) {
|
||||
return this.channelPreviewViewOwner.thread.lastMessage;
|
||||
}
|
||||
if (this.threadNeedactionPreviewViewOwner) {
|
||||
return this.threadNeedactionPreviewViewOwner.thread.lastNeedactionMessageAsOriginThread;
|
||||
}
|
||||
if (this.threadPreviewViewOwner) {
|
||||
return this.threadPreviewViewOwner.thread.lastMessage;
|
||||
}
|
||||
return clear();
|
||||
},
|
||||
/**
|
||||
@@ -26,16 +26,20 @@ registerModel({
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeThread() {
|
||||
if (this.channelPreviewViewOwner) {
|
||||
return this.channelPreviewViewOwner.thread;
|
||||
}
|
||||
if (this.threadNeedactionPreviewViewOwner) {
|
||||
return this.threadNeedactionPreviewViewOwner.thread;
|
||||
}
|
||||
if (this.threadPreviewViewOwner) {
|
||||
return this.threadPreviewViewOwner.thread;
|
||||
}
|
||||
return clear();
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
channelPreviewViewOwner: one('ChannelPreviewView', {
|
||||
identifying: true,
|
||||
inverse: 'messageAuthorPrefixView',
|
||||
}),
|
||||
message: one('Message', {
|
||||
compute: '_computeMessage',
|
||||
}),
|
||||
@@ -46,9 +50,5 @@ registerModel({
|
||||
identifying: true,
|
||||
inverse: 'messageAuthorPrefixView',
|
||||
}),
|
||||
threadPreviewViewOwner: one('ThreadPreviewView', {
|
||||
identifying: true,
|
||||
inverse: 'messageAuthorPrefixView',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -13,6 +13,32 @@ registerModel({
|
||||
},
|
||||
},
|
||||
recordMethods: {
|
||||
/**
|
||||
* @private
|
||||
* @returns {Object[]}
|
||||
*/
|
||||
_computeChannelPreviewViews() {
|
||||
return this.filteredChannels
|
||||
.sort((c1, c2) => {
|
||||
if (c1.localMessageUnreadCounter > 0 && c2.localMessageUnreadCounter === 0) {
|
||||
return -1;
|
||||
}
|
||||
if (c1.localMessageUnreadCounter === 0 && c2.localMessageUnreadCounter > 0) {
|
||||
return 1;
|
||||
}
|
||||
if (c1.thread.lastMessage && c2.thread.lastMessage) {
|
||||
return c1.thread.lastMessage.id < c2.thread.lastMessage.id ? 1 : -1;
|
||||
}
|
||||
if (c1.thread.lastMessage) {
|
||||
return -1;
|
||||
}
|
||||
if (c2.thread.lastMessage) {
|
||||
return 1;
|
||||
}
|
||||
return c1.id < c2.id ? -1 : 1;
|
||||
})
|
||||
.map(channel => ({ channel }));
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {string|FieldCommand}
|
||||
@@ -28,32 +54,30 @@ registerModel({
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
* @returns {Channel[]|FieldCommand}
|
||||
*/
|
||||
_computeFilteredThreads() {
|
||||
_computeFilteredChannels() {
|
||||
switch (this.filter) {
|
||||
case 'channel': {
|
||||
return this.messaging.models['Thread']
|
||||
.all(thread =>
|
||||
thread.channel &&
|
||||
thread.channel.channel_type === 'channel' &&
|
||||
thread.isPinned
|
||||
return this.messaging.models['Channel']
|
||||
.all(channel =>
|
||||
channel.channel_type === 'channel' &&
|
||||
channel.thread.isPinned
|
||||
)
|
||||
.sort((c1, c2) => c1.displayName < c2.displayName ? -1 : 1);
|
||||
}
|
||||
case 'chat': {
|
||||
return this.messaging.models['Thread']
|
||||
.all(thread =>
|
||||
thread.isChatChannel &&
|
||||
thread.isPinned &&
|
||||
thread.model === 'mail.channel'
|
||||
return this.messaging.models['Channel']
|
||||
.all(channel =>
|
||||
channel.thread.isChatChannel &&
|
||||
channel.thread.isPinned
|
||||
)
|
||||
.sort((c1, c2) => c1.displayName < c2.displayName ? -1 : 1);
|
||||
}
|
||||
case 'all': {
|
||||
// "All" filter is for channels and chats
|
||||
return this.messaging.models['Thread']
|
||||
.all(thread => thread.isPinned && thread.model === 'mail.channel')
|
||||
return this.messaging.models['Channel']
|
||||
.all(channel => channel.thread.isPinned)
|
||||
.sort((c1, c2) => c1.displayName < c2.displayName ? -1 : 1);
|
||||
}
|
||||
}
|
||||
@@ -90,7 +114,7 @@ registerModel({
|
||||
}
|
||||
notifications.push(...this.notificationGroupViews);
|
||||
notifications.push(...this.threadNeedactionPreviewViews);
|
||||
notifications.push(...this.threadPreviewViews);
|
||||
notifications.push(...this.channelPreviewViews);
|
||||
return notifications;
|
||||
},
|
||||
/**
|
||||
@@ -123,32 +147,6 @@ registerModel({
|
||||
})
|
||||
.map(thread => ({ thread }));
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeThreadPreviewViews() {
|
||||
return this.filteredThreads
|
||||
.sort((t1, t2) => {
|
||||
if (t1.channel.localMessageUnreadCounter > 0 && t2.channel.localMessageUnreadCounter === 0) {
|
||||
return -1;
|
||||
}
|
||||
if (t1.channel.localMessageUnreadCounter === 0 && t2.channel.localMessageUnreadCounter > 0) {
|
||||
return 1;
|
||||
}
|
||||
if (t1.lastMessage && t2.lastMessage) {
|
||||
return t1.lastMessage.id < t2.lastMessage.id ? 1 : -1;
|
||||
}
|
||||
if (t1.lastMessage) {
|
||||
return -1;
|
||||
}
|
||||
if (t2.lastMessage) {
|
||||
return 1;
|
||||
}
|
||||
return t1.id < t2.id ? -1 : 1;
|
||||
})
|
||||
.map(thread => ({ thread }));
|
||||
},
|
||||
/**
|
||||
* Load previews of given thread. Basically consists of fetching all missing
|
||||
* last messages of each thread.
|
||||
@@ -156,12 +154,17 @@ registerModel({
|
||||
* @private
|
||||
*/
|
||||
async _loadPreviews() {
|
||||
const threads = this.threadPreviewViews
|
||||
.map(threadPreviewView => threadPreviewView.thread);
|
||||
const threads = this.channelPreviewViews
|
||||
.map(channelPreviewView => channelPreviewView.thread);
|
||||
this.messaging.models['Thread'].loadPreviews(threads);
|
||||
},
|
||||
},
|
||||
fields: {
|
||||
channelPreviewViews: many('ChannelPreviewView', {
|
||||
compute: '_computeChannelPreviewViews',
|
||||
inverse: 'notificationListViewOwner',
|
||||
isCausal: true,
|
||||
}),
|
||||
discussOwner: one('Discuss', {
|
||||
identifying: true,
|
||||
inverse: 'notificationListView',
|
||||
@@ -169,8 +172,8 @@ registerModel({
|
||||
filter: attr({
|
||||
compute: '_computeFilter',
|
||||
}),
|
||||
filteredThreads: many('Thread', {
|
||||
compute: '_computeFilteredThreads',
|
||||
filteredChannels: many('Channel', {
|
||||
compute: '_computeFilteredChannels',
|
||||
}),
|
||||
messagingMenuOwner: one('MessagingMenu', {
|
||||
identifying: true,
|
||||
@@ -195,10 +198,5 @@ registerModel({
|
||||
inverse: 'notificationListViewOwner',
|
||||
isCausal: true,
|
||||
}),
|
||||
threadPreviewViews: many('ThreadPreviewView', {
|
||||
compute: '_computeThreadPreviewViews',
|
||||
inverse: 'notificationListViewOwner',
|
||||
isCausal: true,
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,6 +19,9 @@ registerModel({
|
||||
if (this.channelMemberViewOwner) {
|
||||
return this.channelMemberViewOwner.channelMember.persona;
|
||||
}
|
||||
if (this.channelPreviewViewOwner) {
|
||||
return this.channelPreviewViewOwner.channel.correspondent.persona;
|
||||
}
|
||||
if (this.composerSuggestionViewOwner) {
|
||||
return this.composerSuggestionViewOwner.suggestable.partner.persona;
|
||||
}
|
||||
@@ -36,9 +39,6 @@ registerModel({
|
||||
if (this.threadNeedactionPreviewViewOwner) {
|
||||
return this.threadNeedactionPreviewViewOwner.thread.channel.correspondent.persona;
|
||||
}
|
||||
if (this.threadPreviewViewOwner) {
|
||||
return this.threadPreviewViewOwner.thread.channel.correspondent.persona;
|
||||
}
|
||||
return clear();
|
||||
},
|
||||
},
|
||||
@@ -51,6 +51,10 @@ registerModel({
|
||||
identifying: true,
|
||||
inverse: 'personaImStatusIconView',
|
||||
}),
|
||||
channelPreviewViewOwner: one('ChannelPreviewView', {
|
||||
identifying: true,
|
||||
inverse: 'personaImStatusIconView',
|
||||
}),
|
||||
composerSuggestionViewOwner: one('ComposerSuggestionView', {
|
||||
identifying: true,
|
||||
inverse: 'personaImStatusIconView',
|
||||
@@ -63,17 +67,13 @@ registerModel({
|
||||
identifying: true,
|
||||
inverse: 'personaImStatusIconView',
|
||||
}),
|
||||
threadNeedactionPreviewViewOwner: one('ThreadNeedactionPreviewView', {
|
||||
identifying: true,
|
||||
inverse: 'personaImStatusIconView',
|
||||
}),
|
||||
threadPreviewViewOwner: one('ThreadPreviewView', {
|
||||
identifying: true,
|
||||
inverse: 'personaImStatusIconView',
|
||||
}),
|
||||
persona: one('Persona', {
|
||||
compute: '_computePersona',
|
||||
required: true,
|
||||
}),
|
||||
threadNeedactionPreviewViewOwner: one('ThreadNeedactionPreviewView', {
|
||||
identifying: true,
|
||||
inverse: 'personaImStatusIconView',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2110,10 +2110,6 @@ registerModel({
|
||||
inverse: 'thread',
|
||||
isCausal: true,
|
||||
}),
|
||||
threadPreviewViews: many('ThreadPreviewView', {
|
||||
inverse: 'thread',
|
||||
isCausal: true,
|
||||
}),
|
||||
/**
|
||||
* Members that are currently typing something in the composer of this
|
||||
* thread, including current partner.
|
||||
|
||||
@@ -39,23 +39,23 @@ QUnit.test('mark as read', async function (assert) {
|
||||
await click('.o_MessagingMenu_toggler');
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadPreview_markAsRead',
|
||||
'.o_ChannelPreviewView_markAsRead',
|
||||
"should have the mark as read button"
|
||||
);
|
||||
|
||||
await click('.o_ThreadPreview_markAsRead');
|
||||
await click('.o_ChannelPreviewView_markAsRead');
|
||||
assert.verifySteps(
|
||||
['set_last_seen_message'],
|
||||
"should have marked the thread as seen"
|
||||
);
|
||||
assert.hasClass(
|
||||
document.querySelector('.o_ThreadPreview'),
|
||||
document.querySelector('.o_ChannelPreviewView'),
|
||||
'o-muted',
|
||||
"should be muted once marked as read"
|
||||
);
|
||||
assert.containsNone(
|
||||
document.body,
|
||||
'.o_ThreadPreview_markAsRead',
|
||||
'.o_ChannelPreviewView_markAsRead',
|
||||
"should no longer have the mark as read button"
|
||||
);
|
||||
assert.containsNone(
|
||||
|
||||
+10
-10
@@ -274,7 +274,7 @@ QUnit.test('open chat from "new message" chat window should open chat in place o
|
||||
|
||||
// open channel-2
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`.o_NotificationListItem[data-thread-id="${mailChannelId2}"][data-thread-model="mail.channel"]`);
|
||||
await click(`.o_ChannelPreviewView[data-channel-id="${mailChannelId2}"]`);
|
||||
assert.containsN(
|
||||
document.body,
|
||||
'.o_ChatWindow',
|
||||
@@ -1015,7 +1015,7 @@ QUnit.test('open 2 different chat windows: enough screen width [REQUIRE FOCUS]',
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_NotificationList_preview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]
|
||||
`);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`.o_ChatWindow`).length,
|
||||
@@ -1039,7 +1039,7 @@ QUnit.test('open 2 different chat windows: enough screen width [REQUIRE FOCUS]',
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_NotificationList_preview[data-thread-id="${mailChannelId2}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId2}"]
|
||||
`);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`.o_ChatWindow`).length,
|
||||
@@ -1106,7 +1106,7 @@ QUnit.test('open 3 different chat windows: not enough screen width', async funct
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_NotificationList_preview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]
|
||||
`);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`.o_ChatWindow`).length,
|
||||
@@ -1127,7 +1127,7 @@ QUnit.test('open 3 different chat windows: not enough screen width', async funct
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_NotificationList_preview[data-thread-id="${mailChannelId2}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId2}"]
|
||||
`);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`.o_ChatWindow`).length,
|
||||
@@ -1148,7 +1148,7 @@ QUnit.test('open 3 different chat windows: not enough screen width', async funct
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_NotificationList_preview[data-thread-id="${mailChannelId3}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId3}"]
|
||||
`);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`.o_ChatWindow`).length,
|
||||
@@ -1197,7 +1197,7 @@ QUnit.test('chat window: switch on TAB', async function (assert) {
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_NotificationList_preview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]`
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]`
|
||||
);
|
||||
|
||||
assert.containsOnce(document.body, '.o_ChatWindow', "Only 1 chatWindow must be opened");
|
||||
@@ -1229,7 +1229,7 @@ QUnit.test('chat window: switch on TAB', async function (assert) {
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_NotificationList_preview[data-thread-id="${mailChannelId2}"][data-thread-model="mail.channel"]`
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId2}"]`
|
||||
);
|
||||
|
||||
assert.containsN(document.body, '.o_ChatWindow', 2, "2 chatWindows must be opened");
|
||||
@@ -1955,12 +1955,12 @@ QUnit.test('should not have chat window hidden menu in mobile (transition from 2
|
||||
await click('.o_MessagingMenu_toggler');
|
||||
await click(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_NotificationList_preview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]
|
||||
`);
|
||||
await click('.o_ChatWindowHeader_commandBack');
|
||||
await click(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_NotificationList_preview[data-thread-id="${mailChannelId2}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId2}"]
|
||||
`);
|
||||
// simulate resize to go into mobile
|
||||
await afterNextRender(
|
||||
|
||||
@@ -440,7 +440,7 @@ QUnit.test('channel preview: basic rendering', async function (assert) {
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu .o_ThreadPreview
|
||||
.o_MessagingMenu_dropdownMenu .o_ChannelPreviewView
|
||||
`).length,
|
||||
1,
|
||||
"should have one preview"
|
||||
@@ -448,7 +448,7 @@ QUnit.test('channel preview: basic rendering', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview_sidebar
|
||||
.o_ChannelPreviewView_sidebar
|
||||
`).length,
|
||||
1,
|
||||
"preview should have a sidebar"
|
||||
@@ -456,7 +456,7 @@ QUnit.test('channel preview: basic rendering', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview_content
|
||||
.o_ChannelPreviewView_content
|
||||
`).length,
|
||||
1,
|
||||
"preview should have some content"
|
||||
@@ -464,7 +464,7 @@ QUnit.test('channel preview: basic rendering', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview_header
|
||||
.o_ChannelPreviewView_header
|
||||
`).length,
|
||||
1,
|
||||
"preview should have header in content"
|
||||
@@ -472,8 +472,8 @@ QUnit.test('channel preview: basic rendering', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview_header
|
||||
.o_ThreadPreview_name
|
||||
.o_ChannelPreviewView_header
|
||||
.o_ChannelPreviewView_name
|
||||
`).length,
|
||||
1,
|
||||
"preview should have name in header of content"
|
||||
@@ -481,15 +481,15 @@ QUnit.test('channel preview: basic rendering', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelector(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview_name
|
||||
.o_ChannelPreviewView_name
|
||||
`).textContent,
|
||||
"General", "preview should have name of channel"
|
||||
);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview_content
|
||||
.o_ThreadPreview_core
|
||||
.o_ChannelPreviewView_content
|
||||
.o_ChannelPreviewView_core
|
||||
`).length,
|
||||
1,
|
||||
"preview should have core in content"
|
||||
@@ -497,8 +497,8 @@ QUnit.test('channel preview: basic rendering', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview_core
|
||||
.o_ThreadPreview_inlineText
|
||||
.o_ChannelPreviewView_core
|
||||
.o_ChannelPreviewView_inlineText
|
||||
`).length,
|
||||
1,
|
||||
"preview should have inline text in core of content"
|
||||
@@ -506,8 +506,8 @@ QUnit.test('channel preview: basic rendering', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelector(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview_core
|
||||
.o_ThreadPreview_inlineText
|
||||
.o_ChannelPreviewView_core
|
||||
.o_ChannelPreviewView_inlineText
|
||||
`).textContent.trim(),
|
||||
"Demo: test",
|
||||
"preview should have message content as inline text of core content"
|
||||
@@ -536,14 +536,14 @@ QUnit.test('filtered previews', async function (assert) {
|
||||
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`.o_MessagingMenu_dropdownMenu .o_ThreadPreview`).length,
|
||||
document.querySelectorAll(`.o_MessagingMenu_dropdownMenu .o_ChannelPreviewView`).length,
|
||||
2,
|
||||
"should have 2 previews"
|
||||
);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]
|
||||
`).length,
|
||||
1,
|
||||
"should have preview of chat"
|
||||
@@ -551,7 +551,7 @@ QUnit.test('filtered previews', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview[data-thread-id="${mailChannelId2}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId2}"]
|
||||
`).length,
|
||||
1,
|
||||
"should have preview of channel"
|
||||
@@ -559,14 +559,14 @@ QUnit.test('filtered previews', async function (assert) {
|
||||
|
||||
await click('.o_MessagingMenuTab[data-tab-id="chat"]');
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`.o_MessagingMenu_dropdownMenu .o_ThreadPreview`).length,
|
||||
document.querySelectorAll(`.o_MessagingMenu_dropdownMenu .o_ChannelPreviewView`).length,
|
||||
1,
|
||||
"should have one preview"
|
||||
);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]
|
||||
`).length,
|
||||
1,
|
||||
"should have preview of chat"
|
||||
@@ -574,7 +574,7 @@ QUnit.test('filtered previews', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview[data-thread-id="${mailChannelId2}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId2}"]
|
||||
`).length,
|
||||
0,
|
||||
"should not have preview of channel"
|
||||
@@ -584,7 +584,7 @@ QUnit.test('filtered previews', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview
|
||||
.o_ChannelPreviewView
|
||||
`).length,
|
||||
1,
|
||||
"should have one preview"
|
||||
@@ -592,7 +592,7 @@ QUnit.test('filtered previews', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]
|
||||
`).length,
|
||||
0,
|
||||
"should not have preview of chat"
|
||||
@@ -600,7 +600,7 @@ QUnit.test('filtered previews', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview[data-thread-id="${mailChannelId2}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId2}"]
|
||||
`).length,
|
||||
1,
|
||||
"should have preview of channel"
|
||||
@@ -608,14 +608,14 @@ QUnit.test('filtered previews', async function (assert) {
|
||||
|
||||
await click('.o_MessagingMenuTab[data-tab-id="all"]');
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`.o_MessagingMenu_dropdownMenu .o_ThreadPreview`).length,
|
||||
document.querySelectorAll(`.o_MessagingMenu_dropdownMenu .o_ChannelPreviewView`).length,
|
||||
2,
|
||||
"should have 2 previews"
|
||||
);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]
|
||||
`).length,
|
||||
1,
|
||||
"should have preview of chat"
|
||||
@@ -623,7 +623,7 @@ QUnit.test('filtered previews', async function (assert) {
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview[data-thread-id="${mailChannelId2}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId2}"]
|
||||
`).length,
|
||||
1,
|
||||
"should have preview of channel"
|
||||
@@ -638,7 +638,7 @@ QUnit.test('open chat window from preview', async function (assert) {
|
||||
const { click } = await start();
|
||||
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`.o_MessagingMenu_dropdownMenu .o_ThreadPreview`);
|
||||
await click(`.o_MessagingMenu_dropdownMenu .o_ChannelPreviewView`);
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`.o_ChatWindow`).length,
|
||||
1,
|
||||
@@ -661,27 +661,27 @@ QUnit.test('no code injection in message body preview', async function (assert)
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_MessagingMenu_dropdownMenu .o_ThreadPreview',
|
||||
'.o_MessagingMenu_dropdownMenu .o_ChannelPreviewView',
|
||||
"should display a preview",
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadPreview_core',
|
||||
'.o_ChannelPreviewView_core',
|
||||
"preview should have core in content",
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadPreview_inlineText',
|
||||
'.o_ChannelPreviewView_inlineText',
|
||||
"preview should have inline text in core of content",
|
||||
);
|
||||
assert.strictEqual(
|
||||
document.querySelector('.o_ThreadPreview_inlineText')
|
||||
document.querySelector('.o_ChannelPreviewView_inlineText')
|
||||
.textContent.replace(/\s/g, ""),
|
||||
"You:&shoulnotberaisedthrownewError('CodeInjectionError');",
|
||||
"should display correct uninjected last message inline content"
|
||||
);
|
||||
assert.containsNone(
|
||||
document.querySelector('.o_ThreadPreview_inlineText'),
|
||||
document.querySelector('.o_ChannelPreviewView_inlineText'),
|
||||
'script',
|
||||
"last message inline content should not have any code injection"
|
||||
);
|
||||
@@ -702,27 +702,27 @@ QUnit.test('no code injection in message body preview from sanitized message', a
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_MessagingMenu_dropdownMenu .o_ThreadPreview',
|
||||
'.o_MessagingMenu_dropdownMenu .o_ChannelPreviewView',
|
||||
"should display a preview",
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadPreview_core',
|
||||
'.o_ChannelPreviewView_core',
|
||||
"preview should have core in content",
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadPreview_inlineText',
|
||||
'.o_ChannelPreviewView_inlineText',
|
||||
"preview should have inline text in core of content",
|
||||
);
|
||||
assert.strictEqual(
|
||||
document.querySelector('.o_ThreadPreview_inlineText')
|
||||
document.querySelector('.o_ChannelPreviewView_inlineText')
|
||||
.textContent.replace(/\s/g, ""),
|
||||
"You:<em>&shoulnotberaised</em><script>thrownewError('CodeInjectionError');</script>",
|
||||
"should display correct uninjected last message inline content"
|
||||
);
|
||||
assert.containsNone(
|
||||
document.querySelector('.o_ThreadPreview_inlineText'),
|
||||
document.querySelector('.o_ChannelPreviewView_inlineText'),
|
||||
'script',
|
||||
"last message inline content should not have any code injection"
|
||||
);
|
||||
@@ -743,21 +743,21 @@ QUnit.test('<br/> tags in message body preview are transformed in spaces', async
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_MessagingMenu_dropdownMenu .o_ThreadPreview',
|
||||
'.o_MessagingMenu_dropdownMenu .o_ChannelPreviewView',
|
||||
"should display a preview",
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadPreview_core',
|
||||
'.o_ChannelPreviewView_core',
|
||||
"preview should have core in content",
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadPreview_inlineText',
|
||||
'.o_ChannelPreviewView_inlineText',
|
||||
"preview should have inline text in core of content",
|
||||
);
|
||||
assert.strictEqual(
|
||||
document.querySelector('.o_ThreadPreview_inlineText').textContent,
|
||||
document.querySelector('.o_ChannelPreviewView_inlineText').textContent,
|
||||
"You: a b c d",
|
||||
"should display correct last message inline content with brs replaced by spaces"
|
||||
);
|
||||
@@ -902,7 +902,7 @@ QUnit.test('Group chat should be displayed inside the chat section of the messag
|
||||
assert.strictEqual(
|
||||
document.querySelectorAll(`
|
||||
.o_MessagingMenu_dropdownMenu
|
||||
.o_ThreadPreview[data-thread-id="${mailChannelId1}"][data-thread-model="mail.channel"]
|
||||
.o_ChannelPreviewView[data-channel-id="${mailChannelId1}"]
|
||||
`).length,
|
||||
1,
|
||||
"should have one preview of group"
|
||||
|
||||
@@ -30,18 +30,18 @@ QUnit.test('marked as read thread notifications are ordered by last message date
|
||||
await click('.o_MessagingMenu_toggler');
|
||||
assert.containsN(
|
||||
document.body,
|
||||
'.o_ThreadPreview',
|
||||
'.o_ChannelPreviewView',
|
||||
2,
|
||||
"there should be two thread previews"
|
||||
);
|
||||
const threadPreviewElList = document.querySelectorAll('.o_ThreadPreview');
|
||||
const channelPreviewViewElList = document.querySelectorAll('.o_ChannelPreviewView');
|
||||
assert.strictEqual(
|
||||
threadPreviewElList[0].querySelector(':scope .o_ThreadPreview_name').textContent,
|
||||
channelPreviewViewElList[0].querySelector(':scope .o_ChannelPreviewView_name').textContent,
|
||||
'Channel 2020',
|
||||
"First channel in the list should be the channel of 2020 (more recent last message)"
|
||||
);
|
||||
assert.strictEqual(
|
||||
threadPreviewElList[1].querySelector(':scope .o_ThreadPreview_name').textContent,
|
||||
channelPreviewViewElList[1].querySelector(':scope .o_ChannelPreviewView_name').textContent,
|
||||
'Channel 2019',
|
||||
"Second channel in the list should be the channel of 2019 (least recent last message)"
|
||||
);
|
||||
@@ -71,7 +71,7 @@ QUnit.test('thread notifications are re-ordered on receiving a new message', asy
|
||||
await click('.o_MessagingMenu_toggler');
|
||||
assert.containsN(
|
||||
document.body,
|
||||
'.o_ThreadPreview',
|
||||
'.o_ChannelPreviewView',
|
||||
2,
|
||||
"there should be two thread previews"
|
||||
);
|
||||
@@ -94,18 +94,18 @@ QUnit.test('thread notifications are re-ordered on receiving a new message', asy
|
||||
});
|
||||
assert.containsN(
|
||||
document.body,
|
||||
'.o_ThreadPreview',
|
||||
'.o_ChannelPreviewView',
|
||||
2,
|
||||
"there should still be two thread previews"
|
||||
);
|
||||
const threadPreviewElList = document.querySelectorAll('.o_ThreadPreview');
|
||||
const channelPreviewViewElList = document.querySelectorAll('.o_ChannelPreviewView');
|
||||
assert.strictEqual(
|
||||
threadPreviewElList[0].querySelector(':scope .o_ThreadPreview_name').textContent,
|
||||
channelPreviewViewElList[0].querySelector(':scope .o_ChannelPreviewView_name').textContent,
|
||||
'Channel 2019',
|
||||
"First channel in the list should now be 'Channel 2019'"
|
||||
);
|
||||
assert.strictEqual(
|
||||
threadPreviewElList[1].querySelector(':scope .o_ThreadPreview_name').textContent,
|
||||
channelPreviewViewElList[1].querySelector(':scope .o_ChannelPreviewView_name').textContent,
|
||||
'Channel 2020',
|
||||
"Second channel in the list should now be 'Channel 2020'"
|
||||
);
|
||||
|
||||
@@ -42,7 +42,7 @@ QUnit.test('no conflicts between file uploaders', async function (assert) {
|
||||
|
||||
// Uploading file in the second thread: mail.channel in chatWindow.
|
||||
await click(`.o_MessagingMenu_toggler`);
|
||||
await click(`.o_NotificationListItem[data-thread-id="${channelId}"][data-thread-model="mail.channel"]`);
|
||||
await click(`.o_ChannelPreviewView[data-channel-id="${channelId}"]`);
|
||||
const file2 = await createFile({
|
||||
name: 'text2.txt',
|
||||
content: 'hello, world',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.o_ThreadPreview_ratingImage {
|
||||
.o_ChannelPreviewView_ratingImage {
|
||||
height: $font-size-base;
|
||||
width: $font-size-base;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-inherit="mail.ThreadPreview" t-inherit-mode="extension">
|
||||
<xpath expr="//*[hasclass('o_ThreadPreview_messageBody')]" position="replace">
|
||||
<t t-if="threadPreviewView.isRating">
|
||||
<span class="o_ThreadPreview_ratingText">Rating:</span>
|
||||
<img class="o_ThreadPreview_ratingImage ms-2" t-att-src="threadPreviewView.thread.lastMessage.rating.ratingImageUrl" t-att-alt="threadPreviewView.thread.lastMessage.rating.ratingText"/>
|
||||
<t t-inherit="mail.ChannelPreviewView" t-inherit-mode="extension">
|
||||
<xpath expr="//*[hasclass('o_ChannelPreviewView_messageBody')]" position="replace">
|
||||
<t t-if="channelPreviewView.isRating">
|
||||
<span class="o_ChannelPreviewView_ratingText">Rating:</span>
|
||||
<img class="o_ChannelPreviewView_ratingImage ms-2" t-att-src="channelPreviewView.thread.lastMessage.rating.ratingImageUrl" t-att-alt="channelPreviewView.thread.lastMessage.rating.ratingText"/>
|
||||
</t>
|
||||
<t t-else="">$0</t>
|
||||
</xpath>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { attr } from '@mail/model/model_field';
|
||||
// ensure the model definition is loaded before the patch
|
||||
import '@mail/models/channel_preview_view';
|
||||
|
||||
patchRecordMethods('ThreadPreviewView', {
|
||||
patchRecordMethods('ChannelPreviewView', {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -14,7 +14,7 @@ patchRecordMethods('ThreadPreviewView', {
|
||||
},
|
||||
});
|
||||
|
||||
addRecordMethods('ThreadPreviewView', {
|
||||
addRecordMethods('ChannelPreviewView', {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -23,7 +23,7 @@ addRecordMethods('ThreadPreviewView', {
|
||||
},
|
||||
});
|
||||
|
||||
addFields('ThreadPreviewView', {
|
||||
addFields('ChannelPreviewView', {
|
||||
isRating: attr({
|
||||
compute: '_computeIsRating',
|
||||
}),
|
||||
|
||||
@@ -31,22 +31,22 @@ QUnit.test('rating value displayed on the thread preview', async function (asser
|
||||
},
|
||||
}));
|
||||
assert.strictEqual(
|
||||
document.querySelector('.o_ThreadPreview_ratingText').textContent,
|
||||
document.querySelector('.o_ChannelPreviewView_ratingText').textContent,
|
||||
"Rating:",
|
||||
"should display the correct content (Rating:)"
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_ThreadPreview_ratingImage',
|
||||
'.o_ChannelPreviewView_ratingImage',
|
||||
"should have a rating image in the body"
|
||||
);
|
||||
assert.strictEqual(
|
||||
$('.o_ThreadPreview_ratingImage').attr('data-src'),
|
||||
$('.o_ChannelPreviewView_ratingImage').attr('data-src'),
|
||||
"/rating/static/src/img/rating_5.png",
|
||||
"should contain the correct rating image"
|
||||
);
|
||||
assert.strictEqual(
|
||||
$('.o_ThreadPreview_ratingImage').attr('data-alt'),
|
||||
$('.o_ChannelPreviewView_ratingImage').attr('data-alt'),
|
||||
"top",
|
||||
"should contain the correct rating text"
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user