Skip to content
Permalink
Browse files

[IMP] mail: prevent message loss during connection issue

Before the changes, when a message was posted (on Discuss or in
the chat window), the composer was cleared directly as it didn't
wait for the rpc response. If there was latency or a connection
loss, the message disappeared from the composer but took time to
appear in the content window or didn't appear at all and was lost.
Now, the composer waits for the rpc response and then is cleared.

Task #1957856
  • Loading branch information...
jgi-odoo committed Apr 4, 2019
1 parent 25a8be0 commit 11abe9256a78c2778be38df787ce2b1ca900a864
@@ -510,9 +510,10 @@ var BasicComposer = Widget.extend({
clearTimeout(this._cannedTimeout);
var self = this;
this._preprocessMessage().then(function (message) {
self.trigger('post_message', message);
self._clearComposerOnSend();
self.$input.focus();
self.trigger('post_message', message, function(){
self._clearComposerOnSend();
self.$input.focus();
});
});
},
/**
@@ -1462,7 +1462,7 @@ var Discuss = AbstractAction.extend({
* @private
* @param {Object} messageData
*/
_onPostMessage: function (messageData) {
_onPostMessage: function (messageData, callback) {
var self = this;
var options = {};
if (this._selectedMessage) {
@@ -1483,6 +1483,7 @@ var Discuss = AbstractAction.extend({
} else {
self._threadWidget.scrollToBottom();
}
callback();
});
},
/**
@@ -392,14 +392,15 @@ var AbstractThreadWindow = Widget.extend({
* @private
* @param {Object} messageData
*/
_postMessage: function (messageData) {
_postMessage: function (messageData, callback) {
var self = this;
if (!this.hasThread()) {
return;
}
this._thread.postMessage(messageData)
.then(function () {
self._threadWidget.scrollToBottom();
callback();
});
},
/**
@@ -3,7 +3,6 @@ odoo.define('mail.discuss_test', function (require) {

var mailTestUtils = require('mail.testUtils');

var concurrency = require('web.concurrency');
var testUtils = require('web.test_utils');

var createDiscuss = mailTestUtils.createDiscuss;
@@ -1491,5 +1490,56 @@ QUnit.test('custom-named DM conversation', async function (assert) {
discuss.destroy();
});

QUnit.test('input not cleared on unresolved message_post rpc', async function (assert) {
assert.expect(2);

// Promise to simulate late server response on message post
var messagePostPromise = testUtils.makeTestPromise();

this.data.initMessaging = {
channel_slots: {
channel_channel: [{
id: 1,
channel_type: "channel",
name: "general",
}],
},
};

var discuss = await createDiscuss({
id: 1,
context: {},
params: {},
data: this.data,
services: this.services,
debug: true,
mockRPC: function (route, args) {
if (args.method === 'message_post') {
// unresolved promise to simulates message not posted
return messagePostPromise;
}
return this._super.apply(this, arguments);
},
});

// Click on channel 'general'
var $general = discuss.$('.o_mail_discuss_sidebar').find('.o_mail_discuss_item[data-thread-id=1]');
await testUtils.dom.click($general);

// Type message
var $input = discuss.$('textarea.o_composer_text_field').first();
$input.focus();
$input.val('test message');

// Send message
await testUtils.fields.triggerKeydown($input, 'enter');
assert.strictEqual($input.val(), 'test message', "composer should not be cleared on send without server response");

// Simulate server response
messagePostPromise.resolve();
await testUtils.nextTick();
assert.strictEqual($input.text(), '', "composer should be cleared on send after server response");
discuss.destroy();
});
});
});

0 comments on commit 11abe92

Please sign in to comment.
You can’t perform that action at this time.