[IMP] mail: Discuss: load older messages automatically
After this rev., in Discuss, messages are automatically loaded when the user scrolls to the top of the channel. Task 33958 Co-authored-by: Aaron Bohy <aab@odoo.com>
This commit is contained in:
committed by
Aaron Bohy
co-authored by
Aaron Bohy
parent
c5c2b4855b
commit
ea97fa3ac6
@@ -184,6 +184,11 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
.then(function () {
|
||||
self._startListening();
|
||||
self.thread.$el.on("scroll", null, _.debounce(function () {
|
||||
if (self.thread.get_scrolltop() < 20 &&
|
||||
!self.thread.$('.o_mail_no_content').length &&
|
||||
!self.call('chat_manager', 'isAllHistoryLoaded', self.channel, self.domain)) {
|
||||
self._loadMoreMessages();
|
||||
}
|
||||
if (self.thread.is_at_bottom()) {
|
||||
self.call('chat_manager', 'markChannelAsSeen', self.channel);
|
||||
}
|
||||
@@ -218,6 +223,7 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
if (this.channel) {
|
||||
this.thread.scroll_to({offset: this.channelsScrolltop[this.channel.id]});
|
||||
}
|
||||
this._loadEnoughMessages();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
@@ -243,6 +249,7 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
}).then(function (messages) {
|
||||
self.thread.render(messages, self._getThreadRenderingOptions(messages));
|
||||
self._updateButtonStatus(messages.length === 0);
|
||||
return self._loadEnoughMessages();
|
||||
});
|
||||
},
|
||||
/**
|
||||
@@ -274,6 +281,23 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
display_reply_icon: true,
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Ensures that enough messages have been loaded to fill the entire screen
|
||||
* (this is particularily important because remaining messages can only be
|
||||
* loaded when scrolling to the top, so they can't be loaded if there is no
|
||||
* scrollbar)
|
||||
*
|
||||
* @returns {Deferred} resolved when there are enough messages to fill the
|
||||
* screen, or when there is no more message to fetch
|
||||
*/
|
||||
_loadEnoughMessages: function () {
|
||||
var loadMoreMessages = this.thread.el.clientHeight &&
|
||||
this.thread.el.clientHeight === this.thread.el.scrollHeight &&
|
||||
!this.call('chat_manager', 'isAllHistoryLoaded', this.channel, this.domain);
|
||||
if (loadMoreMessages) {
|
||||
return this._loadMoreMessages().then(this._loadEnoughMessages.bind(this));
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Load more messages for the current thread
|
||||
*
|
||||
@@ -429,7 +453,7 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
*/
|
||||
_renderThread: function () {
|
||||
var self = this;
|
||||
this.thread = new ChatThread(this, {display_help: true});
|
||||
this.thread = new ChatThread(this, {display_help: true, loadMoreOnScroll: true});
|
||||
|
||||
this.thread.on('redirect', this, function (resModel, resID) {
|
||||
self.call('chat_manager', 'redirect', resModel, resID, self._setChannel.bind(self));
|
||||
@@ -615,7 +639,7 @@ var Discuss = AbstractAction.extend(ControlPanelMixin, {
|
||||
*/
|
||||
_unselectMessage: function () {
|
||||
this.basicComposer.do_toggle(this.channel.type !== 'static' && !this.channel.mass_mailing);
|
||||
this.extendedComposer.do_toggle(this.channel.type !== 'static' && this.channel.mass_mailing);
|
||||
this.extendedComposer.do_toggle(this.channel.type !== 'static' && !!this.channel.mass_mailing);
|
||||
|
||||
if (!config.device.touch) {
|
||||
var composer = this.channel.mass_mailing ? this.extendedComposer : this.basicComposer;
|
||||
|
||||
@@ -83,6 +83,7 @@ var Thread = Widget.extend({
|
||||
squash_close_messages: true,
|
||||
display_email_icon: true,
|
||||
display_reply_icon: false,
|
||||
loadMoreOnScroll: false,
|
||||
});
|
||||
this.disabledOptions = {
|
||||
display_order: this.enabledOptions.display_order,
|
||||
@@ -93,6 +94,7 @@ var Thread = Widget.extend({
|
||||
squash_close_messages: false,
|
||||
display_email_icon: false,
|
||||
display_reply_icon: false,
|
||||
loadMoreOnScroll: this.enabledOptions.loadMoreOnScroll,
|
||||
};
|
||||
this.expanded_msg_ids = [];
|
||||
this.selected_id = null;
|
||||
|
||||
@@ -332,8 +332,13 @@
|
||||
</t>
|
||||
|
||||
<t t-name="mail.ChatThread.LoadMore">
|
||||
<div t-if="!all_messages_loaded" class="o_thread_show_more">
|
||||
<button class="btn btn-sm btn-link">-------- Show older messages --------</button>
|
||||
<div class="o_thread_show_more">
|
||||
<t t-if="options.loadMoreOnScroll">
|
||||
<span><i class="fa fa-spinner fa-spin"/> Loading older messages... </span>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<button class="btn btn-sm btn-link">-------- Show older messages --------</button>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
|
||||
@@ -293,5 +293,87 @@ QUnit.test('no crash focusout emoji button', function (assert) {
|
||||
});
|
||||
});
|
||||
|
||||
QUnit.test('older messages are loaded on scroll', function (assert) {
|
||||
assert.expect(4);
|
||||
var done = assert.async();
|
||||
|
||||
// remove throttling
|
||||
testUtils.patch(BasicComposer, {MENTION_THROTTLE: 0});
|
||||
testUtils.patch(ChatManager, {CHANNEL_SEEN_THROTTLE: 0});
|
||||
|
||||
this.data.initMessaging = {
|
||||
channel_slots: {
|
||||
channel_channel: [{
|
||||
id: 1,
|
||||
channel_type: "channel",
|
||||
name: "general",
|
||||
static: true,
|
||||
}],
|
||||
},
|
||||
};
|
||||
|
||||
var limit;
|
||||
var loadDef = $.Deferred();
|
||||
var loadedMessages;
|
||||
var msgData = [];
|
||||
for (var i = 0; i < 35; i++) {
|
||||
msgData.push({
|
||||
author_id: ['1', 'Me'],
|
||||
body: '<p>test ' + i + '</p>',
|
||||
channel_ids: [1],
|
||||
id: i,
|
||||
});
|
||||
}
|
||||
msgData.reverse();
|
||||
|
||||
createDiscuss({
|
||||
context: {},
|
||||
data: this.data,
|
||||
params: {},
|
||||
services: [ChatManager, createBusService()],
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'message_fetch') {
|
||||
limit = args.kwargs.limit;
|
||||
loadedMessages += limit;
|
||||
var message = msgData.slice(0, loadedMessages);
|
||||
if (loadedMessages >= msgData.length) {
|
||||
loadDef.resolve();
|
||||
}
|
||||
return $.when(message);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
}).then(function (discuss) {
|
||||
var $general = discuss.$('.o_mail_chat_channel_item[data-channel-id=1]');
|
||||
assert.strictEqual($general.length, 1,
|
||||
"should have a channel item with id 1");
|
||||
|
||||
// switch to 'general'
|
||||
loadedMessages = 0;
|
||||
$general.click();
|
||||
|
||||
assert.ok(limit < 35, "there should be more messages than the limit");
|
||||
assert.strictEqual(discuss.$('.o_thread_message').length, limit,
|
||||
"should display the 'limit' first messages");
|
||||
|
||||
// simulate a scroll to top to load more messages
|
||||
discuss.$('.o_mail_thread').scrollTop(0);
|
||||
|
||||
loadDef
|
||||
.then(concurrency.delay.bind(concurrency, 0))
|
||||
.then(function () {
|
||||
assert.strictEqual(discuss.$('.o_thread_message').length, 35,
|
||||
"all messages should now be loaded");
|
||||
|
||||
// restore throttling
|
||||
testUtils.unpatch(BasicComposer);
|
||||
testUtils.unpatch(ChatManager);
|
||||
|
||||
discuss.destroy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user