Files
odoo_source/addons/mail/static/src/models/messaging_initializer.js
T
tsm-odoo 5471bd4cb8 [IMP] mail: remove im status route
*: bus, hr_holidays.

The `/bus/im_status` route polls the server every minute in order for
the user im_status to be up to date. This commit removes this poll
by sending the im_status on the bus when updating the current user
presence.

Moreover, before [1], the user bus presence was updated on each poll.
When the user didn't poll for 50 seconds, we assumed the user was
disconnected. Since [1], the bus presence is updated each 30 seconds
by the `im_status` service. This is too frequent: there is no need
to update the user presence so often.

In order not to overhelm the server with unnecessary requests, the update
presence interval as well as the delay to be considered disconnected
have been updated: the former from 30 to 60 seconds, the later from
55 to 65 seconds (assuming that a user that has missed an update
presence tick is disconnected).

[1]: odoo/odoo@a5623d2

closes odoo/odoo#100249

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2022-09-20 11:33:51 +02:00

231 lines
8.0 KiB
JavaScript

/** @odoo-module **/
import { registerModel } from '@mail/model/model_core';
import { insert } from '@mail/model/model_field_command';
registerModel({
name: 'MessagingInitializer',
recordMethods: {
/**
* @returns {Object}
*/
async performInitRpc() {
return await this.messaging.rpc({
route: '/mail/init_messaging',
}, { shadow: true });
},
/**
* Fetch messaging data initially to populate the store specifically for
* the current user. This includes pinned channels for instance.
*/
async start() {
this.messaging.device.start();
const discuss = this.messaging.discuss;
const data = await this.performInitRpc();
if (!this.exists()) {
return;
}
await this._init(data);
if (!this.exists()) {
return;
}
if (discuss.discussView) {
discuss.openInitThread();
}
if (this.messaging.currentUser) {
this.messaging.updateImStatusRegistration();
this._loadMessageFailures();
}
},
/**
* @private
* @param {Object} param0
* @param {Object[]} param0.channels
* @param {Object} param0.currentGuest
* @param {Object} param0.current_partner
* @param {integer} param0.current_user_id
* @param {Object} param0.current_user_settings
* @param {boolean} [param0.hasLinkPreviewFeature]
* @param {integer} [param0.internalUserGroupId]
* @param {integer} [param0.needaction_inbox_counter=0]
* @param {Object} param0.partner_root
* @param {Object[]} [param0.shortcodes=[]]
* @param {integer} [param0.starred_counter=0]
*/
async _init({
channels,
commands = [],
companyName,
current_partner,
currentGuest,
current_user_id,
current_user_settings,
hasLinkPreviewFeature,
internalUserGroupId,
menu_id,
needaction_inbox_counter = 0,
partner_root,
shortcodes = [],
starred_counter = 0,
}) {
const discuss = this.messaging.discuss;
// partners first because the rest of the code relies on them
this._initPartners({
currentGuest,
current_partner,
current_user_id,
partner_root,
});
// mailboxes after partners and before other initializers that might
// manipulate threads or messages
this._initMailboxes({
needaction_inbox_counter,
starred_counter,
});
// init mail user settings
if (current_user_settings) {
this.messaging.models['res.users.settings'].insert(current_user_settings);
}
// various suggestions in no particular order
this._initCannedResponses(shortcodes);
// FIXME: guests should have (at least some) commands available
if (!this.messaging.isCurrentUserGuest) {
this._initCommands();
}
// channels when the rest of messaging is ready
if (channels) {
await this._initChannels(channels);
}
if (!this.exists()) {
return;
}
discuss.update({ menu_id });
// company related data
this.messaging.update({ companyName, hasLinkPreviewFeature, internalUserGroupId });
},
/**
* @private
* @param {Object[]} cannedResponsesData
*/
_initCannedResponses(cannedResponsesData) {
this.messaging.update({
cannedResponses: insert(cannedResponsesData),
});
},
/**
* @private
* @param {Object[]} channelsData
*/
async _initChannels(channelsData) {
return this.messaging.executeGracefully(channelsData.map(channelData => () => {
if (!this.exists()) {
return;
}
const convertedData = this.messaging.models['Thread'].convertData(channelData);
const channel = this.messaging.models['Thread'].insert(
Object.assign({ model: 'mail.channel' }, convertedData)
);
// flux specific: channels received at init have to be
// considered pinned. task-2284357
if (!channel.isPinned) {
channel.pin();
}
}));
},
/**
* @private
*/
_initCommands() {
this.messaging.update({
commands: insert([
{
help: this.env._t("Show a helper message"),
methodName: 'execute_command_help',
name: "help",
},
{
help: this.env._t("Leave this channel"),
methodName: 'execute_command_leave',
name: "leave",
},
{
channel_types: ['channel', 'chat', 'group'],
help: this.env._t("List users in the current channel"),
methodName: 'execute_command_who',
name: "who",
}
]),
});
},
/**
* @private
* @param {Object} param0
* @param {integer} param0.needaction_inbox_counter
* @param {integer} param0.starred_counter
*/
_initMailboxes({
needaction_inbox_counter,
starred_counter,
}) {
this.messaging.inbox.update({ counter: needaction_inbox_counter });
this.messaging.starred.update({ counter: starred_counter });
},
/**
* @private
* @param {Object[]} mailFailuresData
*/
async _initMailFailures(mailFailuresData) {
await this.messaging.executeGracefully(mailFailuresData.map(messageData => () => {
if (!this.exists()) {
return;
}
const message = this.messaging.models['Message'].insert(
this.messaging.models['Message'].convertData(messageData)
);
// implicit: failures are sent by the server at initialization
// only if the current partner is author of the message
if (!message.author && this.messaging.currentPartner) {
message.update({ author: this.messaging.currentPartner });
}
}));
},
/**
* @private
* @param {Object} currentGuest
* @param {Object} current_partner
* @param {integer} current_user_id
* @param {Object} partner_root
*/
_initPartners({
currentGuest,
current_partner,
current_user_id: currentUserId,
partner_root,
}) {
if (currentGuest) {
this.messaging.update({ currentGuest: insert(currentGuest) });
}
if (current_partner) {
this.messaging.update({
currentPartner: current_partner,
currentUser: insert({ id: currentUserId }),
});
}
if (partner_root) {
this.messaging.update({
partnerRoot: partner_root,
});
}
},
/**
* @private
*/
async _loadMessageFailures() {
const data = await this.messaging.rpc({
route: '/mail/load_message_failures',
}, { shadow: true });
this._initMailFailures(data);
},
},
});