[IMP] mail: move boot code in service
Part of task-2582313 closes odoo/odoo#75147 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
-5
@@ -9,10 +9,6 @@ import { nextTick } from '@mail/utils/utils';
|
||||
*/
|
||||
export function addMessagingToEnv(providedEnv = {}) {
|
||||
const env = { ...providedEnv };
|
||||
/**
|
||||
* Registry of models.
|
||||
*/
|
||||
env.models = {};
|
||||
/**
|
||||
* Environment keys used in messaging.
|
||||
*/
|
||||
@@ -34,7 +30,6 @@ export function addMessagingToEnv(providedEnv = {}) {
|
||||
return this.messaging.isInitialized;
|
||||
},
|
||||
messagingCreatedPromise: makeDeferred(),
|
||||
messagingInitializedDeferred: makeDeferred(),
|
||||
});
|
||||
return env;
|
||||
}
|
||||
|
||||
@@ -1,45 +1,17 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { ModelManager } from '@mail/model/model_manager';
|
||||
import MessagingService from '@mail/services/messaging/messaging';
|
||||
import { makeDeferred } from '@mail/utils/deferred/deferred';
|
||||
|
||||
import env from 'web.commonEnv';
|
||||
import { serviceRegistry } from 'web.core';
|
||||
|
||||
|
||||
async function createMessaging() {
|
||||
await new Promise(resolve => {
|
||||
/**
|
||||
* Called when all JS resources are loaded. This is useful in order
|
||||
* to do some processing after other JS files have been parsed, for
|
||||
* example new models or patched models that are coming from
|
||||
* other modules, because some of those patches might need to be
|
||||
* applied before messaging initialization.
|
||||
*/
|
||||
window.addEventListener('load', resolve);
|
||||
});
|
||||
/**
|
||||
* All JS resources are loaded, but not necessarily processed.
|
||||
* We assume no messaging-related modules return any Promise,
|
||||
* therefore they should be processed *at most* asynchronously at
|
||||
* "Promise time".
|
||||
*/
|
||||
await new Promise(resolve => setTimeout(resolve));
|
||||
/**
|
||||
* Some models require session data, like locale text direction (depends on
|
||||
* fully loaded translation).
|
||||
*/
|
||||
await env.session.is_bound;
|
||||
|
||||
env.modelManager.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Environment keys used in messaging.
|
||||
*/
|
||||
Object.assign(env, {
|
||||
isMessagingInitialized() {
|
||||
if (!this.modelManager.messaging) {
|
||||
if (!this.modelManager || !this.modelManager.messaging) {
|
||||
return false;
|
||||
}
|
||||
return this.modelManager.messaging.isInitialized;
|
||||
@@ -50,17 +22,16 @@ Object.assign(env, {
|
||||
* Useful for discuss widget to know when messaging is created, because this
|
||||
* is an essential condition to make it work.
|
||||
*/
|
||||
messagingCreatedPromise: createMessaging(),
|
||||
modelManager: new ModelManager(env),
|
||||
messagingCreatedPromise: makeDeferred(),
|
||||
});
|
||||
Object.defineProperty(env, 'messaging', {
|
||||
get() {
|
||||
return this.modelManager.messaging;
|
||||
return this.modelManager && this.modelManager.messaging;
|
||||
},
|
||||
});
|
||||
Object.defineProperty(env, 'models', {
|
||||
get() {
|
||||
return this.modelManager.models;
|
||||
return this.modelManager && this.modelManager.models;
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import AbstractService from 'web.AbstractService';
|
||||
import { bus, serviceRegistry } from 'web.core';
|
||||
|
||||
const ChatWindowService = AbstractService.extend({
|
||||
dependencies: ['messaging'],
|
||||
/**
|
||||
* @override {web.AbstractService}
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ import AbstractService from 'web.AbstractService';
|
||||
import { bus, serviceRegistry } from 'web.core';
|
||||
|
||||
const DialogService = AbstractService.extend({
|
||||
dependencies: ['messaging'],
|
||||
/**
|
||||
* @override {web.AbstractService}
|
||||
*/
|
||||
|
||||
@@ -1,14 +1,56 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { ModelManager } from '@mail/model/model_manager';
|
||||
|
||||
import AbstractService from 'web.AbstractService';
|
||||
|
||||
export default AbstractService.extend({
|
||||
dependencies: ['bus_service'],
|
||||
/**
|
||||
* @override {web.AbstractService}
|
||||
* @override
|
||||
*/
|
||||
start() {
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.env.messagingCreatedPromise.then(() => this.env.messaging.start());
|
||||
this._modelManager = new ModelManager(this.env);
|
||||
this.env.modelManager = this._modelManager;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async start() {
|
||||
this._super(...arguments);
|
||||
if (document.readyState === 'loading') {
|
||||
await new Promise(resolve => {
|
||||
/**
|
||||
* Called when all JS resources are loaded. This is useful in order
|
||||
* to do some processing after other JS files have been parsed, for
|
||||
* example new models or patched models that are coming from
|
||||
* other modules, because some of those patches might need to be
|
||||
* applied before messaging initialization.
|
||||
*/
|
||||
window.addEventListener('load', resolve);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* All JS resources are loaded, but not necessarily processed.
|
||||
* We assume no messaging-related modules return any Promise,
|
||||
* therefore they should be processed *at most* asynchronously at
|
||||
* "Promise time".
|
||||
*/
|
||||
await new Promise(resolve => setTimeout(resolve));
|
||||
/**
|
||||
* Some models require session data, like locale text direction (depends on
|
||||
* fully loaded translation).
|
||||
*/
|
||||
await this.env.session.is_bound;
|
||||
await this.startModelManager();
|
||||
this.env.messagingCreatedPromise.resolve();
|
||||
await this.env.messaging.start();
|
||||
},
|
||||
/**
|
||||
* Starts the model manager.
|
||||
*/
|
||||
async startModelManager() {
|
||||
await this._modelManager.start();
|
||||
},
|
||||
});
|
||||
|
||||
@@ -6,8 +6,9 @@ import {
|
||||
addMessagingToEnv,
|
||||
addTimeControlToEnv,
|
||||
} from '@mail/env/test_env';
|
||||
import { ModelManager } from '@mail/model/model_manager';
|
||||
import ChatWindowService from '@mail/services/chat_window_service/chat_window_service';
|
||||
import MessagingService from '@mail/services/messaging/messaging';
|
||||
import { makeDeferred } from '@mail/utils/deferred/deferred';
|
||||
import DialogService from '@mail/services/dialog_service/dialog_service';
|
||||
import { getMessagingComponent } from '@mail/utils/messaging_component';
|
||||
import { nextTick } from '@mail/utils/utils';
|
||||
@@ -483,7 +484,7 @@ async function start(param0 = {}) {
|
||||
} = callbacks;
|
||||
const { debug = false } = param0;
|
||||
initCallbacks.forEach(callback => callback(param0));
|
||||
|
||||
const testSetupDoneDeferred = makeDeferred();
|
||||
let env = Object.assign(providedEnv || {});
|
||||
env.session = Object.assign(
|
||||
{
|
||||
@@ -520,6 +521,56 @@ async function start(param0 = {}) {
|
||||
_listenHomeMenu: () => {},
|
||||
}),
|
||||
local_storage: AbstractStorageService.extend({ storage: new RamStorage() }),
|
||||
messaging: MessagingService.extend({
|
||||
/**
|
||||
* Override to bind the getters on the actual env that is given,
|
||||
* because the env in the scope of this test might only serve as
|
||||
* template and not be the one actually used.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
Object.defineProperty(this.env, 'messaging', {
|
||||
get() {
|
||||
return this.modelManager.messaging;
|
||||
},
|
||||
});
|
||||
Object.defineProperty(this.env, 'models', {
|
||||
get() {
|
||||
return this.modelManager.models;
|
||||
},
|
||||
});
|
||||
},
|
||||
/**
|
||||
* Override to control when messaging is created, useful to test
|
||||
* spinners and race conditions.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
async start() {
|
||||
const _super = this._super.bind(this);
|
||||
await messagingBeforeCreationDeferred;
|
||||
await _super();
|
||||
},
|
||||
/**
|
||||
* Override to ensure the test setup is complete before starting
|
||||
* otherwise for example the mock server might not be ready yet.
|
||||
* And also override to give test values to messaging.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
async startModelManager() {
|
||||
await testSetupDoneDeferred;
|
||||
await this._modelManager.start({
|
||||
autofetchPartnerImStatus: false,
|
||||
disableAnimation: true,
|
||||
isQUnitTest: true,
|
||||
loadingBaseDelayDuration,
|
||||
messagingBus,
|
||||
});
|
||||
},
|
||||
}),
|
||||
}, param0.services);
|
||||
|
||||
const kwargs = Object.assign({}, param0, {
|
||||
@@ -615,18 +666,6 @@ async function start(param0 = {}) {
|
||||
}
|
||||
// get the final test env after execution of createView/createWebClient/addMockEnvironment
|
||||
testEnv = Component.env;
|
||||
const modelManager = new ModelManager(testEnv);
|
||||
Object.assign(testEnv, { modelManager });
|
||||
Object.defineProperty(testEnv, 'messaging', {
|
||||
get() {
|
||||
return this.modelManager.messaging;
|
||||
},
|
||||
});
|
||||
Object.defineProperty(testEnv, 'models', {
|
||||
get() {
|
||||
return this.modelManager.models;
|
||||
},
|
||||
});
|
||||
/**
|
||||
* Returns a promise resolved after the expected event is received.
|
||||
*
|
||||
@@ -671,51 +710,34 @@ async function start(param0 = {}) {
|
||||
await funcRes;
|
||||
});
|
||||
|
||||
let waitUntilEventPromise;
|
||||
if (waitUntilEvent) {
|
||||
waitUntilEventPromise = afterEvent({ func: () => testSetupDoneDeferred.resolve(), ...waitUntilEvent, });
|
||||
} else {
|
||||
testSetupDoneDeferred.resolve();
|
||||
waitUntilEventPromise = Promise.resolve();
|
||||
}
|
||||
|
||||
const result = {
|
||||
afterEvent,
|
||||
env: testEnv,
|
||||
mockServer,
|
||||
widget,
|
||||
};
|
||||
const start = async () => {
|
||||
messagingBeforeCreationDeferred.then(async () => {
|
||||
/**
|
||||
* Some models require session data, like locale text direction
|
||||
* (depends on fully loaded translation).
|
||||
*/
|
||||
await env.session.is_bound;
|
||||
|
||||
testEnv.modelManager.start({
|
||||
autofetchPartnerImStatus: false,
|
||||
disableAnimation: true,
|
||||
isQUnitTest: true,
|
||||
loadingBaseDelayDuration,
|
||||
messagingBus,
|
||||
});
|
||||
modelManager.messaging.start().then(() =>
|
||||
testEnv.messagingInitializedDeferred.resolve()
|
||||
);
|
||||
testEnv.messagingCreatedPromise.resolve();
|
||||
});
|
||||
if (waitUntilMessagingCondition === 'created') {
|
||||
await testEnv.messagingCreatedPromise;
|
||||
}
|
||||
if (waitUntilMessagingCondition === 'initialized') {
|
||||
await testEnv.messagingInitializedDeferred;
|
||||
}
|
||||
|
||||
if (mountCallbacks.length > 0) {
|
||||
await afterNextRender(async () => {
|
||||
await Promise.all(mountCallbacks.map(callback => callback({ selector, widget })));
|
||||
});
|
||||
}
|
||||
returnCallbacks.forEach(callback => callback(result));
|
||||
};
|
||||
if (waitUntilEvent) {
|
||||
await afterEvent({ func: start, ...waitUntilEvent });
|
||||
} else {
|
||||
await start();
|
||||
if (waitUntilMessagingCondition === 'created') {
|
||||
await testEnv.messagingCreatedPromise;
|
||||
}
|
||||
if (waitUntilMessagingCondition === 'initialized') {
|
||||
await testEnv.messagingCreatedPromise;
|
||||
await testEnv.modelManager.messaging.initializedPromise;
|
||||
}
|
||||
if (mountCallbacks.length > 0) {
|
||||
await afterNextRender(async () => {
|
||||
await Promise.all(mountCallbacks.map(callback => callback({ selector, widget })));
|
||||
});
|
||||
}
|
||||
returnCallbacks.forEach(callback => callback(result));
|
||||
await waitUntilEventPromise;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,20 +31,15 @@ const DiscussWidget = AbstractAction.extend({
|
||||
this.component = undefined;
|
||||
|
||||
this._lastPushStateActiveThread = null;
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async willStart() {
|
||||
await this._super(...arguments);
|
||||
this.env = Component.env;
|
||||
await this.env.messagingCreatedPromise;
|
||||
const initActiveId = this.options.active_id ||
|
||||
(this.action.context && this.action.context.active_id) ||
|
||||
(this.action.params && this.action.params.default_active_id) ||
|
||||
'mail.box_inbox';
|
||||
this.discuss = this.env.messaging.discuss;
|
||||
this.discuss.update({ initActiveId });
|
||||
this.env.messagingCreatedPromise.then(() => {
|
||||
const initActiveId = this.options.active_id ||
|
||||
(this.action.context && this.action.context.active_id) ||
|
||||
(this.action.params && this.action.params.default_active_id) ||
|
||||
'mail.box_inbox';
|
||||
this.discuss = this.env.messaging.discuss;
|
||||
this.discuss.update({ initActiveId });
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @override {web.AbstractAction}
|
||||
|
||||
Reference in New Issue
Block a user