[IMP] mail, *: move channel_type field from Thread to Channel
As the name suggests, `channel_type` only makes sense for Channel. This commit moves `channel_type` from Thread to Channel. * = im_livechat, test_discuss_full Part of task-2948676. closes odoo/odoo#97779 Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
|
||||
<t t-inherit="mail.Composer" t-inherit-mode="extension">
|
||||
<xpath expr="//*[hasclass('o_Composer_buttonAttachment')]" position="replace">
|
||||
<t t-if="!composerView.composer.activeThread or composerView.composer.activeThread.channel_type !== 'livechat'">$0</t>
|
||||
<t t-if="!composerView.composer.activeThread or !composerView.composer.activeThread.channel or composerView.composer.activeThread.channel.channel_type !== 'livechat'">$0</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<templates xml:space="preserve">
|
||||
<t t-inherit="mail.ThreadIcon" t-inherit-mode="extension">
|
||||
<xpath expr="//*[@name='root']" position="inside">
|
||||
<t t-elif="thread.channel_type === 'livechat'">
|
||||
<t t-elif="thread.channel and thread.channel.channel_type === 'livechat'">
|
||||
<t t-if="thread.orderedOtherTypingMembers.length > 0">
|
||||
<ThreadTypingIcon
|
||||
className="'o_ThreadIcon_typing'"
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ patch(components.ThreadNeedactionPreview.prototype, 'thread_needaction_preview',
|
||||
* @override
|
||||
*/
|
||||
image(...args) {
|
||||
if (this.threadNeedactionPreviewView.thread.channel_type === 'livechat') {
|
||||
if (this.threadNeedactionPreviewView.thread.channel && this.threadNeedactionPreviewView.thread.channel.channel_type === 'livechat') {
|
||||
return '/mail/static/src/img/smiley/avatar.jpg';
|
||||
}
|
||||
return this._super(...args);
|
||||
|
||||
@@ -16,7 +16,7 @@ patch(components.ThreadPreview.prototype, 'im_livechat/static/src/components/thr
|
||||
* @override
|
||||
*/
|
||||
image(...args) {
|
||||
if (this.threadPreviewView.thread.channel_type === 'livechat') {
|
||||
if (this.threadPreviewView.thread.channel.channel_type === 'livechat') {
|
||||
return '/mail/static/src/img/smiley/avatar.jpg';
|
||||
}
|
||||
return this._super(...args);
|
||||
|
||||
@@ -11,8 +11,8 @@ patchRecordMethods('ChatWindow', {
|
||||
close({ notifyServer } = {}) {
|
||||
if (
|
||||
this.thread &&
|
||||
this.thread.model === 'mail.channel' &&
|
||||
this.thread.channel_type === 'livechat' &&
|
||||
this.thread.channel &&
|
||||
this.thread.channel.channel_type === 'livechat' &&
|
||||
this.thread.cache.isLoaded &&
|
||||
this.thread.messages.length === 0
|
||||
) {
|
||||
|
||||
@@ -9,7 +9,7 @@ patchRecordMethods('ComposerView', {
|
||||
* @override
|
||||
*/
|
||||
_computeDropZoneView() {
|
||||
if (this.composer.thread && this.composer.thread.channel_type === 'livechat') {
|
||||
if (this.composer.thread && this.composer.thread.channel && this.composer.thread.channel.channel_type === 'livechat') {
|
||||
return clear();
|
||||
}
|
||||
return this._super();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { patchRecordMethods } from '@mail/model/model_core';
|
||||
import { clear } from '@mail/model/model_field_command';
|
||||
// ensure that the model definition is loaded before the patch
|
||||
import '@mail/models/discuss_sidebar_category_item';
|
||||
|
||||
@@ -9,9 +10,9 @@ patchRecordMethods('DiscussSidebarCategoryItem', {
|
||||
* @override
|
||||
*/
|
||||
_computeAvatarUrl() {
|
||||
if (this.channelType === 'livechat') {
|
||||
if (this.channel.correspondent && this.channel.correspondent.id > 0) {
|
||||
return this.channel.correspondent.avatarUrl;
|
||||
if (this.channel && this.channel.channel_type === 'livechat') {
|
||||
if (this.thread.correspondent && this.thread.correspondent.id > 0) {
|
||||
return this.thread.correspondent.avatarUrl;
|
||||
}
|
||||
}
|
||||
return this._super();
|
||||
@@ -20,9 +21,8 @@ patchRecordMethods('DiscussSidebarCategoryItem', {
|
||||
* @override
|
||||
*/
|
||||
_computeCategoryCounterContribution() {
|
||||
switch (this.channel.channel_type) {
|
||||
case 'livechat':
|
||||
return this.channel.localMessageUnreadCounter > 0 ? 1 : 0;
|
||||
if (this.channel && this.channel.channel_type === 'livechat') {
|
||||
return this.thread.localMessageUnreadCounter > 0 ? 1 : 0;
|
||||
}
|
||||
return this._super();
|
||||
},
|
||||
@@ -30,8 +30,8 @@ patchRecordMethods('DiscussSidebarCategoryItem', {
|
||||
* @override
|
||||
*/
|
||||
_computeCounter() {
|
||||
if (this.channelType === 'livechat') {
|
||||
return this.channel.localMessageUnreadCounter;
|
||||
if (this.channel && this.channel.channel_type === 'livechat') {
|
||||
return this.thread.localMessageUnreadCounter;
|
||||
}
|
||||
return this._super();
|
||||
},
|
||||
@@ -39,8 +39,8 @@ patchRecordMethods('DiscussSidebarCategoryItem', {
|
||||
* @override
|
||||
*/
|
||||
_computeHasUnpinCommand() {
|
||||
if (this.channelType === 'livechat') {
|
||||
return !this.channel.localMessageUnreadCounter;
|
||||
if (this.channel && this.channel.channel_type === 'livechat') {
|
||||
return !this.thread.localMessageUnreadCounter;
|
||||
}
|
||||
return this._super();
|
||||
},
|
||||
@@ -48,8 +48,8 @@ patchRecordMethods('DiscussSidebarCategoryItem', {
|
||||
* @override
|
||||
*/
|
||||
_computeHasThreadIcon() {
|
||||
if (this.channelType === 'livechat') {
|
||||
return false;
|
||||
if (this.channel && this.channel.channel_type === 'livechat') {
|
||||
return clear();
|
||||
}
|
||||
return this._super();
|
||||
},
|
||||
|
||||
@@ -29,7 +29,7 @@ patchRecordMethods('Message', {
|
||||
* @override
|
||||
*/
|
||||
_computeHasReactionIcon() {
|
||||
if (this.originThread && this.originThread.channel_type === 'livechat') {
|
||||
if (this.originThread && this.originThread.channel && this.originThread.channel.channel_type === 'livechat') {
|
||||
return false;
|
||||
}
|
||||
return this._super();
|
||||
|
||||
@@ -12,7 +12,8 @@ patchRecordMethods('MessageActionList', {
|
||||
if (
|
||||
this.message &&
|
||||
this.message.originThread &&
|
||||
this.message.originThread.channel_type === 'livechat'
|
||||
this.message.originThread.channel &&
|
||||
this.message.originThread.channel.channel_type === 'livechat'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11,9 +11,9 @@ patchRecordMethods('NotificationListView', {
|
||||
_computeFilteredThreads() {
|
||||
if (this.filter === 'livechat') {
|
||||
return replace(this.messaging.models['Thread'].all(thread =>
|
||||
thread.channel_type === 'livechat' &&
|
||||
thread.isPinned &&
|
||||
thread.model === 'mail.channel'
|
||||
thread.channel &&
|
||||
thread.channel.channel_type === 'livechat' &&
|
||||
thread.isPinned
|
||||
));
|
||||
}
|
||||
return this._super();
|
||||
|
||||
@@ -22,7 +22,7 @@ addRecordMethods('Thread', {
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeMessagingAsPinnedLivechat() {
|
||||
if (!this.messaging || this.channel_type !== 'livechat' || !this.isPinned) {
|
||||
if (!this.messaging || !this.channel || this.channel.channel_type !== 'livechat' || !this.isPinned) {
|
||||
return clear();
|
||||
}
|
||||
return replace(this.messaging);
|
||||
@@ -81,7 +81,7 @@ patchRecordMethods('Thread', {
|
||||
* @override
|
||||
*/
|
||||
getMemberName(partner) {
|
||||
if (this.channel_type === 'livechat' && partner.livechat_username) {
|
||||
if (this.channel && this.channel.channel_type === 'livechat' && partner.livechat_username) {
|
||||
return partner.livechat_username;
|
||||
}
|
||||
return this._super(partner);
|
||||
@@ -90,7 +90,7 @@ patchRecordMethods('Thread', {
|
||||
* @override
|
||||
*/
|
||||
_computeCorrespondent() {
|
||||
if (this.channel_type === 'livechat') {
|
||||
if (this.channel && this.channel.channel_type === 'livechat') {
|
||||
// livechat correspondent never change: always the public member.
|
||||
return;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ patchRecordMethods('Thread', {
|
||||
* @override
|
||||
*/
|
||||
_computeDisplayName() {
|
||||
if (this.channel_type === 'livechat' && this.correspondent) {
|
||||
if (this.channel && this.channel.channel_type === 'livechat' && this.correspondent) {
|
||||
if (this.correspondent.country) {
|
||||
return `${this.correspondent.nameOrDisplayName} (${this.correspondent.country.name})`;
|
||||
}
|
||||
@@ -112,7 +112,7 @@ patchRecordMethods('Thread', {
|
||||
* @override
|
||||
*/
|
||||
_computeHasInviteFeature() {
|
||||
if (this.channel_type === 'livechat') {
|
||||
if (this.channel && this.channel.channel_type === 'livechat') {
|
||||
return true;
|
||||
}
|
||||
return this._super();
|
||||
@@ -121,7 +121,7 @@ patchRecordMethods('Thread', {
|
||||
* @override
|
||||
*/
|
||||
_computeHasMemberListFeature() {
|
||||
if (this.channel_type === 'livechat') {
|
||||
if (this.channel && this.channel.channel_type === 'livechat') {
|
||||
return true;
|
||||
}
|
||||
return this._super();
|
||||
@@ -130,15 +130,17 @@ patchRecordMethods('Thread', {
|
||||
* @override
|
||||
*/
|
||||
_computeIsChatChannel() {
|
||||
return this.channel_type === 'livechat' || this._super();
|
||||
if (this.channel && this.channel.channel_type === 'livechat') {
|
||||
return true;
|
||||
}
|
||||
return this._super();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_getDiscussSidebarCategory() {
|
||||
switch (this.channel_type) {
|
||||
case 'livechat':
|
||||
return this.messaging.discuss.categoryLivechat;
|
||||
if (this.channel.channel_type === 'livechat') {
|
||||
return this.messaging.discuss.categoryLivechat;
|
||||
}
|
||||
return this._super();
|
||||
}
|
||||
|
||||
@@ -765,6 +765,10 @@ class Channel(models.Model):
|
||||
if self.env.user and self.env.user.partner_id and member.partner_id == self.env.user.partner_id:
|
||||
member_of_current_user_by_channel[member.channel_id] = member
|
||||
for channel in self:
|
||||
channel_data = {
|
||||
'channel_type': channel.channel_type,
|
||||
'id': channel.id,
|
||||
}
|
||||
info = {
|
||||
'avatarCacheKey': channel._get_avatar_cache_key(),
|
||||
'id': channel.id,
|
||||
@@ -774,7 +778,6 @@ class Channel(models.Model):
|
||||
'uuid': channel.uuid,
|
||||
'state': 'open',
|
||||
'is_minimized': False,
|
||||
'channel_type': channel.channel_type,
|
||||
'public': channel.public,
|
||||
'group_based_subscription': bool(channel.group_ids),
|
||||
'create_uid': channel.create_uid.id,
|
||||
@@ -820,6 +823,8 @@ class Channel(models.Model):
|
||||
'rtcSessions': [('insert', rtc_sessions_by_channel.get(channel, []))],
|
||||
})
|
||||
|
||||
info['channel'] = [('insert-and-replace', channel_data)]
|
||||
|
||||
channel_infos.append(info)
|
||||
return channel_infos
|
||||
|
||||
|
||||
+6
-6
@@ -8,22 +8,22 @@
|
||||
'bg-100': !categoryItem.isActive,
|
||||
'o-active bg-200': categoryItem.isActive,
|
||||
'o-unread': categoryItem.isUnread,
|
||||
}" t-attf-class="{{ className }}" t-on-click="categoryItem.onClick" t-att-data-thread-local-id="categoryItem.channel.localId" t-att-data-thread-name="categoryItem.channel.displayName"
|
||||
}" t-attf-class="{{ className }}" t-on-click="categoryItem.onClick" t-att-data-thread-local-id="categoryItem.thread.localId" t-att-data-thread-name="categoryItem.thread.displayName"
|
||||
t-ref="root"
|
||||
>
|
||||
<div class="o_DiscussSidebarCategoryItem_item o_DiscussSidebarCategoryItem_avatar ms-4">
|
||||
<div class="o_DiscussSidebarCategoryItem_imageContainer position-relative d-flex">
|
||||
<img class="o_DiscussSidebarCategoryItem_image w-100 h-100 rounded-circle" t-att-src="categoryItem.avatarUrl" alt="Thread Image"/>
|
||||
<t t-if="categoryItem.hasThreadIcon">
|
||||
<ThreadIcon className="'o_DiscussSidebarCategoryItem_threadIcon position-absolute bottom-0 end-0 d-flex align-items-center justify-content-center rounded-circle bg-100'" thread="categoryItem.channel"/>
|
||||
<ThreadIcon className="'o_DiscussSidebarCategoryItem_threadIcon position-absolute bottom-0 end-0 d-flex align-items-center justify-content-center rounded-circle bg-100'" thread="categoryItem.thread"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<span class="o_DiscussSidebarCategoryItem_item o_DiscussSidebarCategoryItem_name ms-3 me-2 text-truncate" t-att-class="{ 'o-item-unread fw-bolder': categoryItem.isUnread }">
|
||||
<t t-esc="categoryItem.channel.displayName"/>
|
||||
<t t-esc="categoryItem.thread.displayName"/>
|
||||
</span>
|
||||
<div class="o_DiscussSidebarCategoryItem_item flex-grow-1"/>
|
||||
<div t-attf-class="o_DiscussSidebarCategoryItem_item o_DiscussSidebarCategoryItem_commands ms-1 {{ categoryItem.channel and categoryItem.channel.rtcSessions.length ? 'me-1' : 'me-3' }}">
|
||||
<div t-attf-class="o_DiscussSidebarCategoryItem_item o_DiscussSidebarCategoryItem_commands ms-1 {{ categoryItem.thread and categoryItem.thread.rtcSessions.length ? 'me-1' : 'me-3' }}">
|
||||
<t t-if="categoryItem.hasSettingsCommand">
|
||||
<div t-attf-class="o_DiscussSidebarCategoryItem_command o_DiscussSidebarCategoryItem_commandSettings fa fa-cog {{ o_DiscussSidebarCategoryItem_hoverItem }}" t-on-click="categoryItem.onClickCommandSettings" title="Channel settings" role="img"/>
|
||||
</t>
|
||||
@@ -34,8 +34,8 @@
|
||||
<div t-attf-class="o_DiscussSidebarCategoryItem_command o_DiscussSidebarCategoryItem_commandUnpin fa fa-times {{ o_DiscussSidebarCategoryItem_hoverItem }} ms-1" t-on-click="categoryItem.onClickCommandUnpin" title="Unpin Conversation" role="img"/>
|
||||
</t>
|
||||
</div>
|
||||
<t t-if="categoryItem.channel and categoryItem.channel.rtcSessions.length">
|
||||
<div class="o_DiscussSidebarCategoryItem_item o_DiscussSidebarCategoryItem_callIndicator fa fa-volume-up ms-1 me-3" t-att-class="{ 'o-isCalling text-danger': categoryItem.channel.rtc }"/>
|
||||
<t t-if="categoryItem.thread and categoryItem.thread.rtcSessions.length">
|
||||
<div class="o_DiscussSidebarCategoryItem_item o_DiscussSidebarCategoryItem_callIndicator fa fa-volume-up ms-1 me-3" t-att-class="{ 'o-isCalling text-danger': categoryItem.thread.rtc }"/>
|
||||
</t>
|
||||
<t t-if="categoryItem.counter > 0">
|
||||
<div class="o_DiscussSidebarCategoryItem_counter o_DiscussSidebarCategoryItem_item badge rounded-pill text-bg-primary ms-1 me-3">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<t t-name="mail.ThreadIcon" owl="1">
|
||||
<t t-if="thread">
|
||||
<div class="o_ThreadIcon d-flex justify-content-center flex-shrink-0" t-attf-class="{{ className }}" t-ref="root" name="root">
|
||||
<t t-if="thread.channel_type === 'channel'">
|
||||
<t t-if="thread.channel and thread.channel.channel_type === 'channel'">
|
||||
<t t-if="thread.public === 'private'">
|
||||
<div class="o_ThreadIcon_channelPrivate fa fa-fw fa-lock" title="Private channel"/>
|
||||
</t>
|
||||
@@ -15,7 +15,7 @@
|
||||
<div class="o_ThreadIcon_channelGroups fa fa-fw fa-hashtag" title="Selected group of users"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-elif="thread.channel_type === 'chat' and thread.correspondent">
|
||||
<t t-elif="thread.channel and thread.channel.channel_type === 'chat' and thread.correspondent">
|
||||
<t t-if="thread.orderedOtherTypingMembers.length > 0">
|
||||
<ThreadTypingIcon
|
||||
className="'o_ThreadIcon_typing flex-grow-1'"
|
||||
@@ -39,7 +39,7 @@
|
||||
<div class="o_ThreadIcon_noImStatus fa fa-fw fa-question-circle" title="No IM status available"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-elif="thread.channel_type === 'group'">
|
||||
<t t-elif="thread.channel and thread.channel.channel_type === 'group'">
|
||||
<div class="o_ThreadIcon fa fa-fw fa-users" title="Grouped Chat"/>
|
||||
</t>
|
||||
<t t-elif="thread.model === 'mail.box'">
|
||||
|
||||
@@ -90,6 +90,7 @@ registerModel({
|
||||
inverse: 'channel',
|
||||
isCausal: true,
|
||||
}),
|
||||
channel_type: attr(),
|
||||
id: attr({
|
||||
readonly: true,
|
||||
required: true,
|
||||
|
||||
@@ -70,7 +70,7 @@ registerModel({
|
||||
* @returns {[ChannelCommand[], ChannelCommand[]]}
|
||||
*/
|
||||
searchSuggestions(searchTerm, { thread } = {}) {
|
||||
if (thread.model !== 'mail.channel') {
|
||||
if (!thread.channel) {
|
||||
// channel commands are channel specific
|
||||
return [[]];
|
||||
}
|
||||
@@ -80,7 +80,7 @@ registerModel({
|
||||
return false;
|
||||
}
|
||||
if (command.channel_types) {
|
||||
return command.channel_types.includes(thread.channel_type);
|
||||
return command.channel_types.includes(thread.channel.channel_type);
|
||||
}
|
||||
return true;
|
||||
})];
|
||||
|
||||
@@ -29,7 +29,7 @@ registerModel({
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
async onClickInvite(ev) {
|
||||
if (this.thread.channel_type === 'chat') {
|
||||
if (this.thread.channel.channel_type === 'chat') {
|
||||
const partners_to = [...new Set([
|
||||
this.messaging.currentPartner.id,
|
||||
...this.thread.members.map(member => member.id),
|
||||
@@ -182,10 +182,10 @@ registerModel({
|
||||
* @returns {string}
|
||||
*/
|
||||
_computeInviteButtonText() {
|
||||
if (!this.thread) {
|
||||
if (!this.thread || !this.thread.channel) {
|
||||
return clear();
|
||||
}
|
||||
switch (this.thread.channel_type) {
|
||||
switch (this.thread.channel.channel_type) {
|
||||
case 'chat':
|
||||
return this.env._t("Create group chat");
|
||||
case 'group':
|
||||
|
||||
@@ -364,10 +364,13 @@ registerModel({
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeHasCallButtons() {
|
||||
return Boolean(this.thread) && this.thread.rtcSessions.length === 0 && ['channel', 'chat', 'group'].includes(this.thread.channel_type);
|
||||
if (!this.thread || !this.thread.channel) {
|
||||
return clear();
|
||||
}
|
||||
return this.thread.rtcSessions.length === 0 && ['channel', 'chat', 'group'].includes(this.thread.channel.channel_type);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
@@ -581,8 +584,8 @@ registerModel({
|
||||
* Determines whether the buttons to start a RTC call should be displayed.
|
||||
*/
|
||||
hasCallButtons: attr({
|
||||
default: false,
|
||||
compute: '_computeHasCallButtons',
|
||||
default: false,
|
||||
}),
|
||||
hasCloseAsBackButton: attr({
|
||||
compute: '_computeHasCloseAsBackButton',
|
||||
|
||||
@@ -214,7 +214,7 @@ registerModel({
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeFollowButtonView() {
|
||||
if (this.hasFollowers && this.thread && this.thread.channel_type !== 'chat') {
|
||||
if (this.hasFollowers && this.thread && (!this.thread.channel || this.thread.channel.channel_type !== 'chat')) {
|
||||
return insertAndReplace();
|
||||
}
|
||||
return clear();
|
||||
|
||||
@@ -1182,7 +1182,7 @@ registerModel({
|
||||
return false;
|
||||
}
|
||||
if (command.channel_types) {
|
||||
return command.channel_types.includes(this.composer.thread.channel_type);
|
||||
return Boolean(this.composer.thread.channel) && command.channel_types.includes(this.composer.thread.channel.channel_type);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -143,8 +143,8 @@ registerModel({
|
||||
return;
|
||||
}
|
||||
thread.open();
|
||||
if (this.messaging.device.isSmall && thread.channel_type) {
|
||||
this.update({ activeMobileNavbarTabId: thread.channel_type });
|
||||
if (this.messaging.device.isSmall && thread.channel && thread.channel.channel_type) {
|
||||
this.update({ activeMobileNavbarTabId: thread.channel.channel_type });
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -51,13 +51,13 @@ registerModel({
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {DiscussSidebarCategoryItem|undefined}
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeActiveItem() {
|
||||
const thread = this.messaging.discuss.thread;
|
||||
if (thread && this.supportedChannelTypes.includes(thread.channel_type)) {
|
||||
const channel = this.messaging.discuss.thread && this.messaging.discuss.thread.channel;
|
||||
if (channel && this.supportedChannelTypes.includes(channel.channel_type)) {
|
||||
return insertAndReplace({
|
||||
channel: replace(thread),
|
||||
thread: replace(channel.thread),
|
||||
category: replace(this),
|
||||
});
|
||||
}
|
||||
@@ -109,7 +109,7 @@ registerModel({
|
||||
if (searchValue) {
|
||||
const qsVal = searchValue.toLowerCase();
|
||||
categoryItems = categoryItems.filter(categoryItem => {
|
||||
const nameVal = categoryItem.channel.displayName.toLowerCase();
|
||||
const nameVal = categoryItem.thread.displayName.toLowerCase();
|
||||
return nameVal.includes(qsVal);
|
||||
});
|
||||
}
|
||||
@@ -238,16 +238,16 @@ registerModel({
|
||||
switch (this.sortComputeMethod) {
|
||||
case 'name':
|
||||
return [
|
||||
['truthy-first', 'channel'],
|
||||
['truthy-first', 'channel.displayName'],
|
||||
['case-insensitive-asc', 'channel.displayName'],
|
||||
['truthy-first', 'thread'],
|
||||
['truthy-first', 'thread.displayName'],
|
||||
['case-insensitive-asc', 'thread.displayName'],
|
||||
['smaller-first', 'channel.id'],
|
||||
];
|
||||
case 'last_action':
|
||||
return [
|
||||
['truthy-first', 'channel'],
|
||||
['truthy-first', 'channel.lastInterestDateTime'],
|
||||
['most-recent-first', 'channel.lastInterestDateTime'],
|
||||
['truthy-first', 'thread'],
|
||||
['truthy-first', 'thread.lastInterestDateTime'],
|
||||
['most-recent-first', 'thread.lastInterestDateTime'],
|
||||
['greater-first', 'channel.id'],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -8,59 +8,71 @@ import Dialog from 'web.Dialog';
|
||||
|
||||
registerModel({
|
||||
name: 'DiscussSidebarCategoryItem',
|
||||
identifyingFields: ['category', 'channel'],
|
||||
identifyingFields: ['category', 'thread'],
|
||||
recordMethods: {
|
||||
/**
|
||||
* @private
|
||||
* @returns {string}
|
||||
* @returns {string|FieldCommand}
|
||||
*/
|
||||
_computeAvatarUrl() {
|
||||
switch (this.channelType) {
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
switch (this.channel.channel_type) {
|
||||
case 'channel':
|
||||
case 'group':
|
||||
return `/web/image/mail.channel/${this.channel.id}/avatar_128?unique=${this.channel.avatarCacheKey}`;
|
||||
return `/web/image/mail.channel/${this.channel.id}/avatar_128?unique=${this.thread.avatarCacheKey}`;
|
||||
case 'chat':
|
||||
if (this.channel.correspondent) {
|
||||
return this.channel.correspondent.avatarUrl;
|
||||
if (this.thread.correspondent) {
|
||||
return this.thread.correspondent.avatarUrl;
|
||||
}
|
||||
}
|
||||
return '/mail/static/src/img/smiley/avatar.jpg';
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {integer}
|
||||
* @returns {integer|FieldCommand}
|
||||
*/
|
||||
_computeCategoryCounterContribution() {
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
switch (this.channel.channel_type) {
|
||||
case 'channel':
|
||||
return this.channel.message_needaction_counter > 0 ? 1 : 0;
|
||||
return this.thread.message_needaction_counter > 0 ? 1 : 0;
|
||||
case 'chat':
|
||||
case 'group':
|
||||
return this.channel.localMessageUnreadCounter > 0 ? 1 : 0;
|
||||
return this.thread.localMessageUnreadCounter > 0 ? 1 : 0;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {integer}
|
||||
* @returns {integer|FieldCommand}
|
||||
*/
|
||||
_computeCounter() {
|
||||
switch (this.channelType) {
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
switch (this.channel.channel_type) {
|
||||
case 'channel':
|
||||
return this.channel.message_needaction_counter;
|
||||
return this.thread.message_needaction_counter;
|
||||
case 'chat':
|
||||
case 'group':
|
||||
return this.channel.localMessageUnreadCounter;
|
||||
return this.thread.localMessageUnreadCounter;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeHasLeaveCommand() {
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
return (
|
||||
['channel', 'group'].includes(this.channelType) &&
|
||||
!this.channel.message_needaction_counter &&
|
||||
!this.channel.group_based_subscription
|
||||
['channel', 'group'].includes(this.channel.channel_type) &&
|
||||
!this.thread.message_needaction_counter &&
|
||||
!this.thread.group_based_subscription
|
||||
);
|
||||
},
|
||||
/**
|
||||
@@ -68,40 +80,43 @@ registerModel({
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_computeHasSettingsCommand() {
|
||||
return this.channelType === 'channel';
|
||||
return this.channel.channel_type === 'channel';
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeHasUnpinCommand() {
|
||||
return this.channelType === 'chat' && !this.channel.localMessageUnreadCounter;
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
return this.channel.channel_type === 'chat' && !this.thread.localMessageUnreadCounter;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_computeIsActive() {
|
||||
return this.messaging.discuss && this.channel === this.messaging.discuss.thread;
|
||||
return this.messaging.discuss && this.thread === this.messaging.discuss.thread;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_computeIsUnread() {
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
return this.channel.localMessageUnreadCounter > 0;
|
||||
return this.thread.localMessageUnreadCounter > 0;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeHasThreadIcon() {
|
||||
switch (this.channelType) {
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
switch (this.channel.channel_type) {
|
||||
case 'channel':
|
||||
return ['private', 'public'].includes(this.channel.public);
|
||||
return ['private', 'public'].includes(this.thread.public);
|
||||
case 'chat':
|
||||
return true;
|
||||
case 'group':
|
||||
@@ -112,20 +127,20 @@ registerModel({
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
onClick(ev) {
|
||||
this.channel.open();
|
||||
this.thread.open();
|
||||
},
|
||||
/**
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
async onClickCommandLeave(ev) {
|
||||
ev.stopPropagation();
|
||||
if (this.channel.channel_type !== 'group' && this.channel.creator === this.messaging.currentUser) {
|
||||
if (this.channel.channel_type !== 'group' && this.thread.creator === this.messaging.currentUser) {
|
||||
await this._askAdminConfirmation();
|
||||
}
|
||||
if (this.channel.channel_type === 'group') {
|
||||
await this._askLeaveGroupConfirmation();
|
||||
}
|
||||
this.channel.leave();
|
||||
this.thread.leave();
|
||||
},
|
||||
/**
|
||||
* Redirects to channel form page when `settings` command is clicked.
|
||||
@@ -136,8 +151,8 @@ registerModel({
|
||||
ev.stopPropagation();
|
||||
return this.env.services.action.doAction({
|
||||
type: 'ir.actions.act_window',
|
||||
res_model: this.channel.model,
|
||||
res_id: this.channel.id,
|
||||
res_model: this.thread.model,
|
||||
res_id: this.thread.id,
|
||||
views: [[false, 'form']],
|
||||
target: 'current',
|
||||
});
|
||||
@@ -147,7 +162,7 @@ registerModel({
|
||||
*/
|
||||
onClickCommandUnpin(ev) {
|
||||
ev.stopPropagation();
|
||||
this.channel.unsubscribe();
|
||||
this.thread.unsubscribe();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
@@ -223,6 +238,10 @@ registerModel({
|
||||
compute: '_computeCategoryCounterContribution',
|
||||
readonly: true,
|
||||
}),
|
||||
channel: one('Channel', {
|
||||
readonly: true,
|
||||
related: 'thread.channel',
|
||||
}),
|
||||
/**
|
||||
* Amount of unread/action-needed messages
|
||||
*/
|
||||
@@ -266,18 +285,12 @@ registerModel({
|
||||
compute: '_computeIsUnread',
|
||||
}),
|
||||
/**
|
||||
* The related channel thread.
|
||||
* The related thread.
|
||||
*/
|
||||
channel: one('Thread', {
|
||||
thread: one('Thread', {
|
||||
inverse: 'discussSidebarCategoryItem',
|
||||
readonly: true,
|
||||
required: true,
|
||||
}),
|
||||
/**
|
||||
* Type of the related channel thread.
|
||||
*/
|
||||
channelType: attr({
|
||||
related: 'channel.channel_type',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -168,7 +168,7 @@ registerModel({
|
||||
// compute seen indicators (if applicable)
|
||||
for (const message of messages) {
|
||||
for (const thread of message.threads) {
|
||||
if (thread.model !== 'mail.channel' || thread.channel_type === 'channel') {
|
||||
if (!thread.channel || thread.channel.channel_type === 'channel') {
|
||||
// disabled on non-channel threads and
|
||||
// on `channel` channels for performance reasons
|
||||
continue;
|
||||
|
||||
@@ -337,7 +337,8 @@ registerModel({
|
||||
) ||
|
||||
(
|
||||
this.messageListViewMessageViewItemOwner &&
|
||||
this.messageListViewMessageViewItemOwner.messageListViewOwner.thread.channel_type === 'chat'
|
||||
this.messageListViewMessageViewItemOwner.messageListViewOwner.thread.channel &&
|
||||
this.messageListViewMessageViewItemOwner.messageListViewOwner.thread.channel.channel_type === 'chat'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -164,10 +164,7 @@ registerModel({
|
||||
last_message_id,
|
||||
partner_id,
|
||||
}) {
|
||||
const channel = this.messaging.models['Thread'].findFromIdentifyingData({
|
||||
id: channelId,
|
||||
model: 'mail.channel',
|
||||
});
|
||||
const channel = this.messaging.models['Channel'].findFromIdentifyingData({ id: channelId });
|
||||
if (!channel) {
|
||||
// for example seen from another browser, the current one has no
|
||||
// knowledge of the channel
|
||||
@@ -180,11 +177,11 @@ registerModel({
|
||||
this.messaging.models['ThreadPartnerSeenInfo'].insert({
|
||||
lastFetchedMessage: insert({ id: last_message_id }),
|
||||
partner: insertAndReplace({ id: partner_id }),
|
||||
thread: replace(channel),
|
||||
thread: replace(channel.thread),
|
||||
});
|
||||
this.messaging.models['MessageSeenIndicator'].insert({
|
||||
message: insertAndReplace({ id: last_message_id }),
|
||||
thread: replace(channel),
|
||||
thread: replace(channel.thread),
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -195,13 +192,13 @@ registerModel({
|
||||
* @param {boolean} [payload.open_chat_window] if true, will pin the channel
|
||||
*/
|
||||
_handleNotificationChannelJoined({ channel: channelData, invited_by_user_id: invitedByUserId, open_chat_window: openChatWindow }) {
|
||||
const channel = this.messaging.models['Thread'].insert(this.messaging.models['Thread'].convertData(channelData));
|
||||
const thread = this.messaging.models['Thread'].insert(this.messaging.models['Thread'].convertData(channelData));
|
||||
if (this.messaging.currentUser && invitedByUserId !== this.messaging.currentUser.id) {
|
||||
// Current user was invited by someone else.
|
||||
this.messaging.notify({
|
||||
message: sprintf(
|
||||
this.env._t("You have been invited to #%s"),
|
||||
channel.displayName
|
||||
thread.displayName
|
||||
),
|
||||
type: 'info',
|
||||
});
|
||||
@@ -209,8 +206,8 @@ registerModel({
|
||||
|
||||
if (openChatWindow) {
|
||||
// open chat upon being invited (if it was not already opened or folded)
|
||||
if (channel.channel_type !== 'channel' && !this.messaging.device.isSmall && !channel.chatWindow) {
|
||||
this.messaging.chatWindowManager.openThread(channel);
|
||||
if (thread.channel.channel_type !== 'channel' && !this.messaging.device.isSmall && !thread.chatWindow) {
|
||||
this.messaging.chatWindowManager.openThread(thread);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -238,10 +235,7 @@ registerModel({
|
||||
* @param {Object} payload.messageData
|
||||
*/
|
||||
async _handleNotificationChannelMessage({ id: channelId, message: messageData }) {
|
||||
let channel = this.messaging.models['Thread'].findFromIdentifyingData({
|
||||
id: channelId,
|
||||
model: 'mail.channel',
|
||||
});
|
||||
let channel = this.messaging.models['Channel'].findFromIdentifyingData({ id: channelId });
|
||||
if (!channel && this.messaging.isCurrentUserGuest) {
|
||||
return; // guests should not receive messages for channels they don't know, and they can't make the channel_info RPC
|
||||
}
|
||||
@@ -257,10 +251,10 @@ registerModel({
|
||||
if (!this.exists()) {
|
||||
return;
|
||||
}
|
||||
channel = res[0];
|
||||
channel = res[0].channel;
|
||||
}
|
||||
if (!channel.isPinned) {
|
||||
channel.pin();
|
||||
if (!channel.thread.isPinned) {
|
||||
channel.thread.pin();
|
||||
}
|
||||
|
||||
const message = this.messaging.models['Message'].insert(convertedData);
|
||||
@@ -274,26 +268,26 @@ registerModel({
|
||||
// Chat from OdooBot is considered disturbing and should only be
|
||||
// shown on the menu, but no notification and no thread open.
|
||||
const isChatWithOdooBot = (
|
||||
channel.correspondent &&
|
||||
channel.correspondent === this.messaging.partnerRoot
|
||||
channel.thread.correspondent &&
|
||||
channel.thread.correspondent === this.messaging.partnerRoot
|
||||
);
|
||||
if (!isChatWithOdooBot) {
|
||||
const isOdooFocused = this.env.services['presence'].isOdooFocused();
|
||||
// Notify if out of focus
|
||||
if (!isOdooFocused && channel.isChatChannel) {
|
||||
if (!isOdooFocused && channel.thread.isChatChannel) {
|
||||
this._notifyNewChannelMessageWhileOutOfFocus({
|
||||
channel,
|
||||
message,
|
||||
});
|
||||
}
|
||||
if (channel.model === 'mail.channel' && channel.channel_type !== 'channel' && !this.messaging.currentGuest) {
|
||||
if (channel.channel_type !== 'channel' && !this.messaging.currentGuest) {
|
||||
// disabled on non-channel threads and
|
||||
// on `channel` channels for performance reasons
|
||||
channel.markAsFetched();
|
||||
channel.thread.markAsFetched();
|
||||
}
|
||||
// open chat on receiving new message if it was not already opened or folded
|
||||
if (channel.channel_type !== 'channel' && !this.messaging.device.isSmall && !channel.chatWindow) {
|
||||
this.messaging.chatWindowManager.openThread(channel);
|
||||
if (channel.channel_type !== 'channel' && !this.messaging.device.isSmall && !channel.thread.chatWindow) {
|
||||
this.messaging.chatWindowManager.openThread(channel.thread);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -312,10 +306,7 @@ registerModel({
|
||||
last_message_id,
|
||||
partner_id,
|
||||
}) {
|
||||
const channel = this.messaging.models['Thread'].findFromIdentifyingData({
|
||||
id: channelId,
|
||||
model: 'mail.channel',
|
||||
});
|
||||
const channel = this.messaging.models['Channel'].findFromIdentifyingData({ id: channelId });
|
||||
if (!channel) {
|
||||
// for example seen from another browser, the current one has no
|
||||
// knowledge of the channel
|
||||
@@ -329,15 +320,15 @@ registerModel({
|
||||
this.messaging.models['ThreadPartnerSeenInfo'].insert({
|
||||
lastSeenMessage: replace(lastMessage),
|
||||
partner: insertAndReplace({ id: partner_id }),
|
||||
thread: replace(channel),
|
||||
thread: replace(channel.thread),
|
||||
});
|
||||
this.messaging.models['MessageSeenIndicator'].insert({
|
||||
message: replace(lastMessage),
|
||||
thread: replace(channel),
|
||||
thread: replace(channel.thread),
|
||||
});
|
||||
}
|
||||
if (this.messaging.currentPartner && this.messaging.currentPartner.id === partner_id) {
|
||||
channel.update({
|
||||
channel.thread.update({
|
||||
lastSeenByCurrentPartnerMessageId: last_message_id,
|
||||
pendingSeenMessageId: undefined,
|
||||
});
|
||||
@@ -639,7 +630,7 @@ registerModel({
|
||||
/**
|
||||
* @private
|
||||
* @param {Object} param0
|
||||
* @param {Thread} param0.channel
|
||||
* @param {Channel} param0.channel
|
||||
* @param {Message} param0.message
|
||||
*/
|
||||
_notifyNewChannelMessageWhileOutOfFocus({ channel, message }) {
|
||||
@@ -655,9 +646,9 @@ registerModel({
|
||||
// from component
|
||||
const channelIcon = renderToString('mail.ThreadIcon', {
|
||||
env: this.env,
|
||||
thread: channel,
|
||||
thread: channel.thread,
|
||||
});
|
||||
const channelName = channel.displayName;
|
||||
const channelName = channel.thread.displayName;
|
||||
const channelNameWithIcon = channelIcon + channelName;
|
||||
notificationTitle = sprintf(
|
||||
this.env._t("%s from %s"),
|
||||
|
||||
@@ -57,9 +57,9 @@ registerModel({
|
||||
case 'channel': {
|
||||
return replace(this.messaging.models['Thread']
|
||||
.all(thread =>
|
||||
thread.channel_type === 'channel' &&
|
||||
thread.isPinned &&
|
||||
thread.model === 'mail.channel'
|
||||
thread.channel &&
|
||||
thread.channel.channel_type === 'channel' &&
|
||||
thread.isPinned
|
||||
)
|
||||
.sort((c1, c2) => c1.displayName < c2.displayName ? -1 : 1)
|
||||
);
|
||||
|
||||
@@ -45,6 +45,10 @@ registerModel({
|
||||
if ('avatarCacheKey' in data) {
|
||||
data2.avatarCacheKey = data.avatarCacheKey;
|
||||
}
|
||||
if ('channel' in data) {
|
||||
data2.channel = data.channel;
|
||||
data2.model = 'mail.channel';
|
||||
}
|
||||
if ('defaultDisplayMode' in data) {
|
||||
data2.defaultDisplayMode = data.defaultDisplayMode;
|
||||
}
|
||||
@@ -54,10 +58,6 @@ registerModel({
|
||||
if ('model' in data) {
|
||||
data2.model = data.model;
|
||||
}
|
||||
if ('channel_type' in data) {
|
||||
data2.channel_type = data.channel_type;
|
||||
data2.model = 'mail.channel';
|
||||
}
|
||||
if ('create_uid' in data) {
|
||||
data2.creator = insert({ id: data.create_uid });
|
||||
}
|
||||
@@ -431,8 +431,15 @@ registerModel({
|
||||
limit,
|
||||
},
|
||||
});
|
||||
return this.insert(channelsData.map(
|
||||
channelData => this.convertData(channelData)
|
||||
return this.insert(channelsData.map(channelData =>
|
||||
this.messaging.models['Thread'].convertData({
|
||||
channel: insertAndReplace({
|
||||
channel_type: channelData.channel_type,
|
||||
id: channelData.id,
|
||||
}),
|
||||
id: channelData.id,
|
||||
name: channelData.name,
|
||||
})
|
||||
));
|
||||
},
|
||||
/**
|
||||
@@ -462,8 +469,8 @@ registerModel({
|
||||
const cleanedSearchTerm = cleanSearchTerm(searchTerm);
|
||||
return [threads.filter(thread =>
|
||||
!thread.isTemporary &&
|
||||
thread.model === 'mail.channel' &&
|
||||
thread.channel_type === 'channel' &&
|
||||
thread.channel &&
|
||||
thread.channel.channel_type === 'channel' &&
|
||||
thread.displayName &&
|
||||
cleanSearchTerm(thread.displayName).includes(cleanedSearchTerm)
|
||||
)];
|
||||
@@ -787,7 +794,7 @@ registerModel({
|
||||
* Only makes sense if isPendingPinned is set to the desired value.
|
||||
*/
|
||||
async notifyPinStateToServer() {
|
||||
if (this.channel_type === 'channel') {
|
||||
if (this.channel.channel_type === 'channel') {
|
||||
await this.leave();
|
||||
return;
|
||||
}
|
||||
@@ -1049,13 +1056,6 @@ registerModel({
|
||||
});
|
||||
return replace(allAttachments);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeChannel() {
|
||||
return this.model === 'mail.channel' ? insertAndReplace({ id: this.id }) : clear();
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {FieldCommand}
|
||||
@@ -1068,10 +1068,13 @@ registerModel({
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {Partner}
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeCorrespondent() {
|
||||
if (this.channel_type === 'channel') {
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
if (this.channel.channel_type === 'channel') {
|
||||
return clear();
|
||||
}
|
||||
const correspondents = this.members.filter(partner =>
|
||||
@@ -1093,9 +1096,9 @@ registerModel({
|
||||
*/
|
||||
_computeCorrespondentOfDmChat() {
|
||||
if (
|
||||
this.channel_type === 'chat' &&
|
||||
this.channel &&
|
||||
this.channel.channel_type === 'chat' &&
|
||||
this.correspondent &&
|
||||
this.model === 'mail.channel' &&
|
||||
this.public === 'private'
|
||||
) {
|
||||
return replace(this.correspondent);
|
||||
@@ -1107,7 +1110,7 @@ registerModel({
|
||||
* @returns {FieldCommand}
|
||||
*/
|
||||
_computeDiscussSidebarCategoryItem() {
|
||||
if (this.model !== 'mail.channel') {
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
if (!this.isPinned) {
|
||||
@@ -1127,10 +1130,10 @@ registerModel({
|
||||
* @returns {string}
|
||||
*/
|
||||
_computeDisplayName() {
|
||||
if (this.channel_type === 'chat' && this.correspondent) {
|
||||
if (this.channel && this.channel.channel_type === 'chat' && this.correspondent) {
|
||||
return this.custom_channel_name || this.correspondent.nameOrDisplayName;
|
||||
}
|
||||
if (this.channel_type === 'group' && !this.name) {
|
||||
if (this.channel && this.channel.channel_type === 'group' && !this.name) {
|
||||
const partnerNames = this.members.map(partner => partner.nameOrDisplayName);
|
||||
const guestNames = this.guestMembers.map(guest => guest.name);
|
||||
return [...partnerNames, ...guestNames].join(this.env._t(", "));
|
||||
@@ -1180,10 +1183,13 @@ registerModel({
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeHasCallFeature() {
|
||||
return ['channel', 'chat', 'group'].includes(this.channel_type);
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
return ['channel', 'chat', 'group'].includes(this.channel.channel_type);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
@@ -1194,20 +1200,23 @@ registerModel({
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeHasSeenIndicators() {
|
||||
if (this.model !== 'mail.channel') {
|
||||
return false;
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
return ['chat', 'livechat'].includes(this.channel_type);
|
||||
return ['chat', 'livechat'].includes(this.channel.channel_type);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeIsChannelDescriptionChangeable() {
|
||||
return this.model === 'mail.channel' && ['channel', 'group'].includes(this.channel_type);
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
return ['channel', 'group'].includes(this.channel.channel_type);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
@@ -1222,36 +1231,45 @@ registerModel({
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeIsChannelRenamable() {
|
||||
return (
|
||||
this.model === 'mail.channel' &&
|
||||
['chat', 'channel', 'group'].includes(this.channel_type)
|
||||
);
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
return ['chat', 'channel', 'group'].includes(this.channel.channel_type);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeHasMemberListFeature() {
|
||||
return this.model === 'mail.channel' && ['channel', 'group'].includes(this.channel_type);
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
return ['channel', 'group'].includes(this.channel.channel_type);
|
||||
},
|
||||
/**
|
||||
* @returns {string}
|
||||
* @returns {string|FieldCommand}
|
||||
*/
|
||||
_computeInvitationLink() {
|
||||
if (!this.uuid || !this.channel_type || this.channel_type === 'chat') {
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
if (!this.uuid || !this.channel.channel_type || this.channel.channel_type === 'chat') {
|
||||
return clear();
|
||||
}
|
||||
return `${window.location.origin}/chat/${this.id}/${this.uuid}`;
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
* @returns {boolean|FieldCommand}
|
||||
*/
|
||||
_computeIsChatChannel() {
|
||||
return this.channel_type === 'chat' || this.channel_type === 'group';
|
||||
if (!this.channel) {
|
||||
return clear();
|
||||
}
|
||||
return ['chat', 'group'].includes(this.channel.channel_type);
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
@@ -1582,7 +1600,7 @@ registerModel({
|
||||
* @returns {DiscussSidebarCategory}
|
||||
*/
|
||||
_getDiscussSidebarCategory() {
|
||||
switch (this.channel_type) {
|
||||
switch (this.channel.channel_type) {
|
||||
case 'channel':
|
||||
return this.messaging.discuss.categoryChannel;
|
||||
case 'chat':
|
||||
@@ -1768,12 +1786,10 @@ registerModel({
|
||||
required: true,
|
||||
}),
|
||||
channel: one('Channel', {
|
||||
compute: '_computeChannel',
|
||||
inverse: 'thread',
|
||||
isCausal: true,
|
||||
readonly: true,
|
||||
}),
|
||||
channel_type: attr(),
|
||||
/**
|
||||
* States the chat window related to this thread (if any).
|
||||
*/
|
||||
@@ -1857,7 +1873,7 @@ registerModel({
|
||||
*/
|
||||
discussSidebarCategoryItem: one('DiscussSidebarCategoryItem', {
|
||||
compute: '_computeDiscussSidebarCategoryItem',
|
||||
inverse: 'channel',
|
||||
inverse: 'thread',
|
||||
isCausal: true,
|
||||
readonly: true,
|
||||
}),
|
||||
|
||||
@@ -365,13 +365,13 @@ registerModel({
|
||||
isEditingThreadName: false,
|
||||
pendingThreadName: clear(),
|
||||
});
|
||||
if (this.thread.channel_type === 'chat' && newName !== this.thread.custom_channel_name) {
|
||||
if (this.thread.channel.channel_type === 'chat' && newName !== this.thread.custom_channel_name) {
|
||||
this.thread.setCustomName(newName);
|
||||
}
|
||||
if (newName && this.thread.channel_type === 'channel' && newName !== this.thread.name) {
|
||||
if (newName && this.thread.channel.channel_type === 'channel' && newName !== this.thread.name) {
|
||||
this.thread.rename(newName);
|
||||
}
|
||||
if (this.thread.channel_type === 'group' && newName !== this.thread.name) {
|
||||
if (this.thread.channel.channel_type === 'group' && newName !== this.thread.name) {
|
||||
this.thread.rename(newName);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1000,6 +1000,10 @@ patch(MockServer.prototype, 'mail', {
|
||||
['is_read', '=', false],
|
||||
['mail_message_id', 'in', messages.map(message => message.id)],
|
||||
]).length;
|
||||
const channelData = {
|
||||
channel_type: channel.channel_type,
|
||||
id: channel.id,
|
||||
};
|
||||
const res = Object.assign({}, channel, {
|
||||
last_message_id: lastMessageId,
|
||||
members: [...this._mockResPartnerMailPartnerFormat(partnerIds).values()],
|
||||
@@ -1031,6 +1035,7 @@ patch(MockServer.prototype, 'mail', {
|
||||
res['rtc_inviting_session'] = { 'id': memberOfCurrentUser.rtc_inviting_session_id };
|
||||
}
|
||||
}
|
||||
res.channel = [['insert-and-replace', channelData]];
|
||||
return res;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { insert } from '@mail/model/model_field_command';
|
||||
import { insert, insertAndReplace } from '@mail/model/model_field_command';
|
||||
import { start } from '@mail/../tests/helpers/test_utils';
|
||||
|
||||
QUnit.module('mail', {}, function () {
|
||||
@@ -26,18 +26,18 @@ QUnit.test('inbox & starred mailboxes', async function (assert) {
|
||||
});
|
||||
|
||||
QUnit.test('create (channel)', async function (assert) {
|
||||
assert.expect(23);
|
||||
assert.expect(20);
|
||||
|
||||
const { messaging } = await start();
|
||||
assert.notOk(messaging.models['Partner'].findFromIdentifyingData({ id: 9 }));
|
||||
assert.notOk(messaging.models['Partner'].findFromIdentifyingData({ id: 10 }));
|
||||
assert.notOk(messaging.models['Thread'].findFromIdentifyingData({
|
||||
id: 100,
|
||||
model: 'mail.channel',
|
||||
}));
|
||||
assert.notOk(messaging.models['Channel'].findFromIdentifyingData({ id: 100 }));
|
||||
|
||||
const thread = messaging.models['Thread'].insert({
|
||||
channel_type: 'channel',
|
||||
messaging.models['Thread'].insert({
|
||||
channel: insertAndReplace({
|
||||
channel_type: 'channel',
|
||||
id: 100,
|
||||
}),
|
||||
id: 100,
|
||||
members: insert([{
|
||||
email: "john@example.com",
|
||||
@@ -54,28 +54,20 @@ QUnit.test('create (channel)', async function (assert) {
|
||||
public: 'public',
|
||||
serverMessageUnreadCounter: 5,
|
||||
});
|
||||
assert.ok(thread);
|
||||
const channel = messaging.models['Channel'].findFromIdentifyingData({ id: 100 });
|
||||
assert.ok(channel);
|
||||
assert.ok(messaging.models['Partner'].findFromIdentifyingData({ id: 9 }));
|
||||
assert.ok(messaging.models['Partner'].findFromIdentifyingData({ id: 10 }));
|
||||
assert.ok(messaging.models['Thread'].findFromIdentifyingData({
|
||||
id: 100,
|
||||
model: 'mail.channel',
|
||||
}));
|
||||
const partner9 = messaging.models['Partner'].findFromIdentifyingData({ id: 9 });
|
||||
const partner10 = messaging.models['Partner'].findFromIdentifyingData({ id: 10 });
|
||||
assert.strictEqual(thread, messaging.models['Thread'].findFromIdentifyingData({
|
||||
id: 100,
|
||||
model: 'mail.channel',
|
||||
}));
|
||||
assert.strictEqual(thread.model, 'mail.channel');
|
||||
assert.strictEqual(thread.channel_type, 'channel');
|
||||
assert.strictEqual(thread.id, 100);
|
||||
assert.ok(thread.members.includes(partner9));
|
||||
assert.ok(thread.members.includes(partner10));
|
||||
assert.strictEqual(thread.message_needaction_counter, 6);
|
||||
assert.strictEqual(thread.name, "General");
|
||||
assert.strictEqual(thread.public, 'public');
|
||||
assert.strictEqual(thread.serverMessageUnreadCounter, 5);
|
||||
assert.strictEqual(channel.channel_type, 'channel');
|
||||
assert.strictEqual(channel.id, 100);
|
||||
assert.ok(channel.thread.members.includes(partner9));
|
||||
assert.ok(channel.thread.members.includes(partner10));
|
||||
assert.strictEqual(channel.thread.message_needaction_counter, 6);
|
||||
assert.strictEqual(channel.thread.name, "General");
|
||||
assert.strictEqual(channel.thread.public, 'public');
|
||||
assert.strictEqual(channel.thread.serverMessageUnreadCounter, 5);
|
||||
assert.strictEqual(partner9.email, "john@example.com");
|
||||
assert.strictEqual(partner9.id, 9);
|
||||
assert.strictEqual(partner9.name, "John");
|
||||
@@ -85,17 +77,17 @@ QUnit.test('create (channel)', async function (assert) {
|
||||
});
|
||||
|
||||
QUnit.test('create (chat)', async function (assert) {
|
||||
assert.expect(15);
|
||||
assert.expect(12);
|
||||
|
||||
const { messaging } = await start();
|
||||
assert.notOk(messaging.models['Partner'].findFromIdentifyingData({ id: 5 }));
|
||||
assert.notOk(messaging.models['Thread'].findFromIdentifyingData({
|
||||
id: 200,
|
||||
model: 'mail.channel',
|
||||
}));
|
||||
assert.notOk(messaging.models['Channel'].findFromIdentifyingData({ id: 200 }));
|
||||
|
||||
const channel = messaging.models['Thread'].insert({
|
||||
channel_type: 'chat',
|
||||
messaging.models['Thread'].insert({
|
||||
channel: insertAndReplace({
|
||||
channel_type: 'chat',
|
||||
id: 200,
|
||||
}),
|
||||
id: 200,
|
||||
members: insert({
|
||||
email: "demo@example.com",
|
||||
@@ -105,22 +97,14 @@ QUnit.test('create (chat)', async function (assert) {
|
||||
}),
|
||||
model: 'mail.channel',
|
||||
});
|
||||
const channel = messaging.models['Channel'].findFromIdentifyingData({ id: 200 });
|
||||
assert.ok(channel);
|
||||
assert.ok(messaging.models['Thread'].findFromIdentifyingData({
|
||||
id: 200,
|
||||
model: 'mail.channel',
|
||||
}));
|
||||
assert.ok(messaging.models['Partner'].findFromIdentifyingData({ id: 5 }));
|
||||
const partner = messaging.models['Partner'].findFromIdentifyingData({ id: 5 });
|
||||
assert.strictEqual(channel, messaging.models['Thread'].findFromIdentifyingData({
|
||||
id: 200,
|
||||
model: 'mail.channel',
|
||||
}));
|
||||
assert.strictEqual(channel.model, 'mail.channel');
|
||||
assert.strictEqual(channel.channel_type, 'chat');
|
||||
assert.strictEqual(channel.id, 200);
|
||||
assert.ok(channel.correspondent);
|
||||
assert.strictEqual(partner, channel.correspondent);
|
||||
assert.ok(channel.thread.correspondent);
|
||||
assert.strictEqual(partner, channel.thread.correspondent);
|
||||
assert.strictEqual(partner.email, "demo@example.com");
|
||||
assert.strictEqual(partner.id, 5);
|
||||
assert.strictEqual(partner.im_status, 'online');
|
||||
|
||||
@@ -119,7 +119,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': self.channel_general._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'channel',
|
||||
'id': self.channel_general.id,
|
||||
})],
|
||||
'create_uid': self.user_root.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -144,7 +147,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': self.channel_channel_public_1._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'channel',
|
||||
'id': self.channel_channel_public_1.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -169,7 +175,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': self.channel_channel_public_2._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'channel',
|
||||
'id': self.channel_channel_public_2.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -194,7 +203,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': self.channel_channel_group_1._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'channel',
|
||||
'id': self.channel_channel_group_1.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -219,7 +231,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': self.channel_channel_group_2._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'channel',
|
||||
'id': self.channel_channel_group_2.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -244,7 +259,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': self.channel_channel_private_1._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'channel',
|
||||
'id': self.channel_channel_private_1.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -269,7 +287,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': self.group_user.full_name,
|
||||
'avatarCacheKey': self.channel_channel_private_2._get_avatar_cache_key(),
|
||||
'channel_type': 'channel',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'channel',
|
||||
'id': self.channel_channel_private_2.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -294,7 +315,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': self.channel_group_1._get_avatar_cache_key(),
|
||||
'channel_type': 'group',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'group',
|
||||
'id': self.channel_group_1.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -358,7 +382,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': self.channel_chat_1._get_avatar_cache_key(),
|
||||
'channel_type': 'chat',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'chat',
|
||||
'id': self.channel_chat_1.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -422,7 +449,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': self.channel_chat_2._get_avatar_cache_key(),
|
||||
'channel_type': 'chat',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'chat',
|
||||
'id': self.channel_chat_2.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -486,7 +516,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': self.channel_chat_3._get_avatar_cache_key(),
|
||||
'channel_type': 'chat',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'chat',
|
||||
'id': self.channel_chat_3.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -550,7 +583,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': self.channel_chat_4._get_avatar_cache_key(),
|
||||
'channel_type': 'chat',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'chat',
|
||||
'id': self.channel_chat_4.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -614,7 +650,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': self.channel_livechat_1._get_avatar_cache_key(),
|
||||
'channel_type': 'livechat',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'livechat',
|
||||
'id': self.channel_livechat_1.id,
|
||||
})],
|
||||
'create_uid': self.env.user.id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
@@ -678,7 +717,10 @@ class TestDiscussFullPerformance(TransactionCase):
|
||||
{
|
||||
'authorizedGroupFullName': False,
|
||||
'avatarCacheKey': self.channel_livechat_2._get_avatar_cache_key(),
|
||||
'channel_type': 'livechat',
|
||||
'channel': [('insert-and-replace', {
|
||||
'channel_type': 'livechat',
|
||||
'id': self.channel_livechat_2.id,
|
||||
})],
|
||||
'create_uid': self.env.ref('base.public_user').id,
|
||||
'custom_channel_name': False,
|
||||
'defaultDisplayMode': False,
|
||||
|
||||
Reference in New Issue
Block a user