[IMP] mail: move fields from env to messaging

Part of task-2582313
This commit is contained in:
Sébastien Theys
2021-08-18 12:26:41 +00:00
parent 5d0b8cdfc9
commit 5377376097
17 changed files with 91 additions and 43 deletions
@@ -66,7 +66,7 @@ export class Attachment extends Component {
if (this.attachment.fileType !== 'image') {
return '';
}
if (this.env.isQUnitTest) {
if (this.attachment.messaging.isQUnitTest) {
// background-image:url is hardly mockable, and attachments in
// QUnit tests do not actually exist in DB, so style should not
// be fetched at all.
@@ -406,7 +406,7 @@ export class Message extends Component {
el.remove();
}
this._insertReadMoreLess($(this._contentRef.el));
this.env.messagingBus.trigger('o-component-message-read-more-less-inserted', {
this.message.messaging.messagingBus.trigger('o-component-message-read-more-less-inserted', {
message: this.message,
});
}
@@ -505,7 +505,7 @@ export class MessageList extends Component {
return;
}
const scrollTop = this._getScrollableElement().scrollTop;
this.env.messagingBus.trigger('o-component-message-list-scrolled', {
this.threadView.messaging.messagingBus.trigger('o-component-message-list-scrolled', {
orderedMessages,
scrollTop,
thread,
@@ -49,7 +49,7 @@
<t t-set="prev_message" t-value="0"/>
<t t-foreach="orderedMessages" t-as="message" t-key="message.localId">
<t t-if="message === threadView.thread.messageAfterNewMessageSeparator">
<div class="o_MessageList_separator o_MessageList_separatorNewMessages o_MessageList_item" t-att-class="{ 'o-disable-animation': env.disableAnimation }" t-transition="fade">
<div class="o_MessageList_separator o_MessageList_separatorNewMessages o_MessageList_item" t-att-class="{ 'o-disable-animation': message.messaging.disableAnimation }" t-transition="fade">
<hr class="o_MessageList_separatorLine o_MessageList_separatorLineNewMessages"/><span class="o_MessageList_separatorLabel o_MessageList_separatorLabelNewMessages">New messages</span>
</div>
</t>
-13
View File
@@ -3,8 +3,6 @@
import { makeDeferred } from '@mail/utils/deferred/deferred';
import { nextTick } from '@mail/utils/utils';
const { EventBus } = owl.core;
/**
* @param {Object} [providedEnv={}]
* @returns {Object}
@@ -19,7 +17,6 @@ export function addMessagingToEnv(providedEnv = {}) {
* Environment keys used in messaging.
*/
Object.assign(env, {
autofetchPartnerImStatus: false,
browser: Object.assign({
innerHeight: 1080,
innerWidth: 1920,
@@ -30,24 +27,14 @@ export function addMessagingToEnv(providedEnv = {}) {
},
}, (env.browser && env.browser.Notification) || {}),
}, env.browser),
disableAnimation: true,
isMessagingInitialized() {
if (!this.messaging) {
return false;
}
return this.messaging.isInitialized;
},
/**
* States whether the environment is in QUnit test or not.
*
* Useful to prevent some behaviour in QUnit tests, like applying
* style of attachment that uses url.
*/
isQUnitTest: true,
loadingBaseDelayDuration: providedEnv.loadingBaseDelayDuration || 0,
messagingCreatedPromise: makeDeferred(),
messagingInitializedDeferred: makeDeferred(),
messagingBus: new EventBus(),
});
return env;
}
-12
View File
@@ -6,7 +6,6 @@ import MessagingService from '@mail/services/messaging/messaging';
import env from 'web.commonEnv';
import { serviceRegistry } from 'web.core';
const { EventBus } = owl.core;
async function createMessaging() {
await new Promise(resolve => {
@@ -39,23 +38,12 @@ async function createMessaging() {
* Environment keys used in messaging.
*/
Object.assign(env, {
autofetchPartnerImStatus: true,
disableAnimation: false,
isMessagingInitialized() {
if (!this.modelManager.messaging) {
return false;
}
return this.modelManager.messaging.isInitialized;
},
/**
* States whether the environment is in QUnit test or not.
*
* Useful to prevent some behaviour in QUnit tests, like applying
* style of attachment that uses url.
*/
isQUnitTest: false,
loadingBaseDelayDuration: 400,
messagingBus: new EventBus(),
/**
* Promise which becomes resolved when messaging is created.
*
@@ -101,8 +101,10 @@ export class ModelManager {
/**
* Called when all JS modules that register or patch models have been
* done. This launches generation of models.
*
* @param {Object} values field name/value pairs to give at messaging create
*/
start() {
start(values) {
/**
* Generate the models.
*/
@@ -110,7 +112,7 @@ export class ModelManager {
/**
* Create the messaging singleton record.
*/
this.models['mail.messaging'].create();
this.models['mail.messaging'].create(values);
}
//--------------------------------------------------------------------------
@@ -315,7 +315,7 @@ function factory(dependencies) {
if (!this.uploadingAbortController) {
const abortController = new AbortController();
abortController.signal.onabort = () => {
this.env.messagingBus.trigger('o-attachment-upload-abort', {
this.messaging.messagingBus.trigger('o-attachment-upload-abort', {
attachment: this
});
};
@@ -178,7 +178,7 @@ function factory(dependencies) {
this._attachmentsLoaderTimeout = this.env.browser.setTimeout(() => {
this.update({ isShowingAttachmentsLoading: true });
this._isPreparingAttachmentsLoading = false;
}, this.env.loadingBaseDelayDuration);
}, this.messaging.loadingBaseDelayDuration);
}
/**
@@ -5,6 +5,8 @@ import { attr, many2many, many2one, one2many, one2one } from '@mail/model/model_
import { create } from '@mail/model/model_field_command';
import { makeDeferred } from '@mail/utils/deferred/deferred';
const { EventBus } = owl.core;
function factory(dependencies) {
class Messaging extends dependencies['mail.model'] {
@@ -157,6 +159,17 @@ function factory(dependencies) {
return makeDeferred();
}
/**
* @private
* @returns {owl.EventBus}
*/
_computeMessagingBus() {
if (this.messagingBus) {
return;
}
return new EventBus();
}
/**
* @private
* @returns {boolean}
@@ -187,6 +200,13 @@ function factory(dependencies) {
inverse: 'messaging',
isCausal: true,
}),
/**
* Determines whether a loop should be started at initialization to
* periodically fetch the im_status of all users.
*/
autofetchPartnerImStatus: attr({
default: true,
}),
cannedResponses: one2many('mail.canned_response'),
chatWindowManager: one2one('mail.chat_window_manager', {
default: create(),
@@ -206,6 +226,12 @@ function factory(dependencies) {
isCausal: true,
readonly: true,
}),
/**
* Determines whether animations should be disabled.
*/
disableAnimation: attr({
default: false,
}),
discuss: one2one('mail.discuss', {
default: create(),
isCausal: true,
@@ -243,11 +269,34 @@ function factory(dependencies) {
isNotificationPermissionDefault: attr({
compute: '_computeIsNotificationPermissionDefault',
}),
/**
* States whether the current environment is QUnit test. Useful to
* disable some features that are not possible to test due to
* technical limitations.
*/
isQUnitTest: attr({
default: false,
}),
locale: one2one('mail.locale', {
default: create(),
isCausal: true,
readonly: true,
}),
/**
* Determines after how much time in ms a "loading" indicator should be
* shown. Useful to avoid flicker for almost instant loading.
*/
loadingBaseDelayDuration: attr({
default: 400,
}),
/**
* Determines the bus that is used to communicate messaging events.
*/
messagingBus: attr({
compute: '_computeMessagingBus',
readonly: true,
required: true,
}),
messagingMenu: one2one('mail.messaging_menu', {
default: create(),
isCausal: true,
@@ -52,7 +52,7 @@ function factory(dependencies) {
if (discuss.isOpen) {
discuss.openInitThread();
}
if (this.env.autofetchPartnerImStatus) {
if (this.messaging.autofetchPartnerImStatus) {
this.env.models['mail.partner'].startLoopFetchImStatus();
}
}
@@ -1540,7 +1540,7 @@ function factory(dependencies) {
* @private
*/
_onChangeLastSeenByCurrentPartnerMessageId() {
this.env.messagingBus.trigger('o-thread-last-seen-by-current-partner-message-id-changed', {
this.messaging.messagingBus.trigger('o-thread-last-seen-by-current-partner-message-id-changed', {
thread: this,
});
}
@@ -283,7 +283,7 @@ function factory(dependencies) {
if (!extraDomain && messages.length < limit) {
this.update({ isAllHistoryLoaded: true });
}
this.env.messagingBus.trigger('o-thread-cache-loaded-messages', {
this.messaging.messagingBus.trigger('o-thread-cache-loaded-messages', {
fetchedMessages: messages,
threadCache: this,
});
@@ -48,7 +48,7 @@ function factory(dependencies) {
this.update({
componentHintList: this.componentHintList.filter(h => h !== hint),
});
this.env.messagingBus.trigger('o-thread-view-hint-processed', {
this.messaging.messagingBus.trigger('o-thread-view-hint-processed', {
hint,
threadViewer: this.threadViewer,
});
@@ -54,12 +54,14 @@ QUnit.test('Open "New Message" chat window with a command', async function (asse
await afterNextRender(() => click(document.body, ".o_command.focused"));
assert.containsOnce(document.body, ".o_ChatWindow");
assert.strictEqual(document.querySelector(".o_ChatWindow .o_ChatWindowHeader_name").textContent, "New message");
webClient.destroy();
});
QUnit.test('open "New Message" chat window with a hotkey', async function (assert) {
assert.expect(2);
await start({
const { widget: webClient } = await start({
data: this.data,
hasChatWindow: true,
hasWebClient: true,
@@ -67,6 +69,8 @@ QUnit.test('open "New Message" chat window with a hotkey', async function (asser
await afterNextRender(() => triggerHotkey("alt+shift+w"));
assert.containsOnce(document.body, ".o_ChatWindow");
assert.strictEqual(document.querySelector(".o_ChatWindow .o_ChatWindowHeader_name").textContent, "New message");
webClient.destroy();
});
QUnit.test('Open "New Message" in discuss with a command', async function (assert) {
@@ -88,12 +92,14 @@ QUnit.test('Open "New Message" in discuss with a command', async function (asser
await afterNextRender(() => click(document.body, ".o_command.focused"));
assert.containsOnce(document.body, ".o_DiscussSidebar_itemNewInput");
webClient.destroy();
});
QUnit.test('Open "New Message" in discuss with a hotkey', async function (assert) {
assert.expect(1);
await start({
const { widget: webClient } = await start({
autoOpenDiscuss: true,
data: this.data,
hasDiscuss: true,
@@ -101,6 +107,8 @@ QUnit.test('Open "New Message" in discuss with a hotkey', async function (assert
});
await afterNextRender(() => triggerHotkey("alt+shift+w"));
assert.containsOnce(document.body, ".o_DiscussSidebar_itemNewInput");
webClient.destroy();
});
});
+14 -4
View File
@@ -33,6 +33,7 @@ const {
unpatch: legacyUnpatch,
} = mock;
const { Component } = owl;
const { EventBus } = owl.core;
//------------------------------------------------------------------------------
// Private
@@ -394,6 +395,7 @@ async function createRootMessagingComponent(self, componentName, { props = {}, t
* `env.testUtils`.
* @param {boolean} [param0.hasView=false] if set, use createView to create a
* view instead of a generic widget.
* @param {integer} [param0.loadingBaseDelayDuration=0]
* @param {Deferred|Promise} [param0.messagingBeforeCreationDeferred=Promise.resolve()]
* Deferred that let tests block messaging creation and simulate resolution.
* Useful for testing working components when messaging is not yet created.
@@ -445,6 +447,7 @@ async function start(param0 = {}) {
hasMessagingMenu = false,
hasTimeControl = false,
hasView = false,
loadingBaseDelayDuration = 0,
messagingBeforeCreationDeferred = Promise.resolve(),
waitUntilEvent,
waitUntilMessagingCondition = 'initialized',
@@ -471,6 +474,7 @@ async function start(param0 = {}) {
if (hasMessagingMenu) {
callbacks = _useMessagingMenu(callbacks);
}
const messagingBus = new EventBus();
const {
init: initCallbacks,
mount: mountCallbacks,
@@ -650,7 +654,7 @@ async function start(param0 = {}) {
});
// Set up the promise to resolve if the event is triggered.
const eventProm = new Promise(resolve => {
testEnv.messagingBus.on(eventName, null, data => {
messagingBus.on(eventName, null, data => {
if (!predicate || predicate(data)) {
resolve();
}
@@ -681,8 +685,14 @@ async function start(param0 = {}) {
*/
await env.session.is_bound;
testEnv.modelManager.start();
testEnv.messaging.start().then(() =>
testEnv.modelManager.start({
autofetchPartnerImStatus: false,
disableAnimation: true,
isQUnitTest: true,
loadingBaseDelayDuration,
messagingBus,
});
modelManager.messaging.start().then(() =>
testEnv.messagingInitializedDeferred.resolve()
);
testEnv.messagingCreatedPromise.resolve();
@@ -702,7 +712,7 @@ async function start(param0 = {}) {
returnCallbacks.forEach(callback => callback(result));
};
if (waitUntilEvent) {
await afterEvent(Object.assign({ func: start }, waitUntilEvent));
await afterEvent({ func: start, ...waitUntilEvent });
} else {
await start();
}
@@ -65,6 +65,8 @@ QUnit.module('mail', {}, function () {
await afterNextRender(() => click(document.body, ".o_command.focused"));
assert.containsOnce(document.body, ".o_ChatWindow");
assert.strictEqual(document.querySelector(".o_ChatWindow .o_ChatWindowHeader_name").textContent, "Partner 1");
webClient.destroy();
});
QUnit.test('open the chatWindow of a channel from the command palette', async function (assert) {
@@ -104,5 +106,7 @@ QUnit.module('mail', {}, function () {
await afterNextRender(() => click(document.body, ".o_command.focused"));
assert.containsOnce(document.body, ".o_ChatWindow");
assert.strictEqual(document.querySelector(".o_ChatWindow .o_ChatWindowHeader_name").textContent, "general");
webClient.destroy();
});
});