Update chat state notifications when message is edited.

This commit is contained in:
Lance Stout 2020-02-26 17:42:09 -08:00 committed by JC Brand
parent f34cc63d4c
commit a6aaf3f595
4 changed files with 86 additions and 2 deletions

View File

@ -4,6 +4,7 @@
- #1313: Stylistic improvements to the send button - #1313: Stylistic improvements to the send button
- #1535: Add option to destroy a MUC - #1535: Add option to destroy a MUC
- #1715: Update chat state notification after receiving a message correction.
- #1793: Send button doesn't appear in Firefox in 1:1 chats - #1793: Send button doesn't appear in Firefox in 1:1 chats
- #1820: Set focus on jid field after controlbox is loaded - #1820: Set focus on jid field after controlbox is loaded
- #1822: Don't log error if user has no bookmarks - #1822: Don't log error if user has no bookmarks

View File

@ -1057,6 +1057,68 @@
done(); done();
})); }));
}); });
describe("On receiving a message correction", function () {
it("will be updated",
mock.initConverse(
['rosterGroupsFetched'], {},
async function (done, _converse) {
await test_utils.waitForRoster(_converse, 'current');
await test_utils.openControlBox(_converse);
// See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await test_utils.openChatBoxFor(_converse, sender_jid);
// Original message
const original_id = u.getUniqueId();
const original = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: original_id,
body: "Original message",
}).c('active', {'xmlns': Strophe.NS.CHATSTATES}).tree();
spyOn(_converse.api, "trigger").and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(original));
await u.waitUntil(() => _converse.api.trigger.calls.count());
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
const view = _converse.chatboxviews.get(sender_jid);
expect(view).toBeDefined();
// <composing> state
const msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: u.getUniqueId()
}).c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
await _converse.handleMessageStanza(msg);
const event = await u.waitUntil(() => view.el.querySelector('.chat-state-notification'));
expect(event.textContent).toEqual(mock.cur_names[1] + ' is typing');
// Edited message
const edited = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: u.getUniqueId(),
body: "Edited message",
})
.c('active', {'xmlns': Strophe.NS.CHATSTATES}).up()
.c('replace', {'xmlns': Strophe.NS.MESSAGE_CORRECT, 'id': original_id }).tree();
await _converse.handleMessageStanza(edited);
const events = view.el.querySelectorAll('.chat-state-notification');
expect(events.length).toBe(0);
done();
}));
});
}); });
}); });

View File

@ -196,6 +196,7 @@ converse.plugins.add('converse-chatview', {
this.initDebounced(); this.initDebounced();
this.listenTo(this.model.messages, 'add', this.onMessageAdded); this.listenTo(this.model.messages, 'add', this.onMessageAdded);
this.listenTo(this.model.messages, 'change:edited', this.onMessageEdited);
this.listenTo(this.model.messages, 'rendered', this.scrollDown); this.listenTo(this.model.messages, 'rendered', this.scrollDown);
this.model.messages.on('reset', () => { this.model.messages.on('reset', () => {
this.content.innerHTML = ''; this.content.innerHTML = '';
@ -724,8 +725,7 @@ converse.plugins.add('converse-chatview', {
await message.initialized; await message.initialized;
const view = this.add(message.get('id'), new _converse.MessageView({'model': message})); const view = this.add(message.get('id'), new _converse.MessageView({'model': message}));
await view.render(); await view.render();
// Clear chat state notifications this.clearChatStateForSender(message.get('from'));
sizzle(`.chat-state-notification[data-csn="${message.get('from')}"]`, this.content).forEach(u.removeElement);
this.insertMessage(view); this.insertMessage(view);
this.insertDayIndicator(view.el); this.insertDayIndicator(view.el);
this.setScrollPosition(view.el); this.setScrollPosition(view.el);
@ -780,6 +780,16 @@ converse.plugins.add('converse-chatview', {
}); });
}, },
/**
* Handler that gets called when a message object has been edited via LMC.
* @private
* @method _converse.ChatBoxView#onMessageEdited
* @param { object } message - The updated message object.
*/
onMessageEdited (message) {
this.clearChatStateForSender(message.get('from'));
},
parseMessageForCommands (text) { parseMessageForCommands (text) {
const match = text.replace(/^\s*/, "").match(/^\/(.*)\s*$/); const match = text.replace(/^\s*/, "").match(/^\/(.*)\s*$/);
if (match) { if (match) {
@ -1072,6 +1082,16 @@ converse.plugins.add('converse-chatview', {
return this; return this;
}, },
/**
* Remove chat state notifications for a given sender JID.
* @private
* @method _converse.ChatBoxView#clearChatStateForSender
* @param {string} sender - The sender of the chat state
*/
clearChatStateForSender (sender) {
sizzle(`.chat-state-notification[data-csn="${sender}"]`, this.content).forEach(u.removeElement);
},
/** /**
* Insert a particular string value into the textarea of this chat box. * Insert a particular string value into the textarea of this chat box.
* @private * @private

View File

@ -700,6 +700,7 @@ converse.plugins.add('converse-muc-views', {
this.initDebounced(); this.initDebounced();
this.listenTo(this.model.messages, 'add', this.onMessageAdded); this.listenTo(this.model.messages, 'add', this.onMessageAdded);
this.listenTo(this.model.messages, 'change:edited', this.onMessageEdited);
this.listenTo(this.model.messages, 'rendered', this.scrollDown); this.listenTo(this.model.messages, 'rendered', this.scrollDown);
this.model.messages.on('reset', () => { this.model.messages.on('reset', () => {
this.content.innerHTML = ''; this.content.innerHTML = '';