Commit d0510856 authored by JC Brand's avatar JC Brand

Only clear textarea once message was sent

This now requires `sendMessage` to return a boolean to indicate success.
Disable the textarea while message is being sent.
parent 85dab736
...@@ -9583,6 +9583,8 @@ body.reset { ...@@ -9583,6 +9583,8 @@ body.reset {
font-size: var(--font-size); font-size: var(--font-size);
direction: ltr; direction: ltr;
z-index: 1031; } z-index: 1031; }
#conversejs textarea:disabled {
background-color: #EEE !important; }
#conversejs .nopadding { #conversejs .nopadding {
padding: 0 !important; } padding: 0 !important; }
#conversejs.converse-overlayed > .row { #conversejs.converse-overlayed > .row {
......
...@@ -50200,27 +50200,6 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins ...@@ -50200,27 +50200,6 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
} }
}, },
onMessageSubmitted(text, spoiler_hint) {
/* This method gets called once the user has typed a message
* and then pressed enter in a chat box.
*
* Parameters:
* (String) text - The chat message text.
* (String) spoiler_hint - A hint in case the message
* text is a hidden/spoiler message. See XEP-0382
*/
if (!_converse.connection.authenticated) {
return this.showHelpMessages(['Sorry, the connection has been lost, ' + 'and your message could not be sent'], 'error');
}
if (this.parseMessageForCommands(text)) {
return;
}
const attrs = this.model.getOutgoingMessageAttributes(text, spoiler_hint);
this.model.sendMessage(attrs);
},
setChatState(state, options) { setChatState(state, options) {
/* Mutator for setting the chat state of this chat session. /* Mutator for setting the chat state of this chat session.
* Handles clearing of any chat state notification timeouts and * Handles clearing of any chat state notification timeouts and
...@@ -50247,7 +50226,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins ...@@ -50247,7 +50226,7 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
return this; return this;
}, },
onFormSubmitted(ev) { async onFormSubmitted(ev) {
ev.preventDefault(); ev.preventDefault();
const textarea = this.el.querySelector('.chat-textarea'), const textarea = this.el.querySelector('.chat-textarea'),
message = textarea.value; message = textarea.value;
...@@ -50256,26 +50235,37 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins ...@@ -50256,26 +50235,37 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_5__["default"].plugins
return; return;
} }
let spoiler_hint; if (!_converse.connection.authenticated) {
this.showHelpMessages(['Sorry, the connection has been lost, and your message could not be sent'], 'error');
return;
}
let spoiler_hint,
hint_el = {};
if (this.model.get('composing_spoiler')) { if (this.model.get('composing_spoiler')) {
const hint_el = this.el.querySelector('form.sendXMPPMessage input.spoiler-hint'); hint_el = this.el.querySelector('form.sendXMPPMessage input.spoiler-hint');
spoiler_hint = hint_el.value; spoiler_hint = hint_el.value;
hint_el.value = '';
} }
textarea.value = ''; _converse_headless_utils_emoji__WEBPACK_IMPORTED_MODULE_21__["default"].addClass('disabled', textarea);
_converse_headless_utils_emoji__WEBPACK_IMPORTED_MODULE_21__["default"].removeClass('correcting', textarea); textarea.setAttribute('disabled', 'disabled');
textarea.focus(); // Trigger input event, so that the textarea resizes
const event = document.createEvent('Event'); if (this.parseMessageForCommands(message) || (await this.model.sendMessage(this.model.getOutgoingMessageAttributes(message, spoiler_hint)))) {
event.initEvent('input', true, true); hint_el.value = '';
textarea.dispatchEvent(event); textarea.value = '';
this.onMessageSubmitted(message, spoiler_hint); _converse_headless_utils_emoji__WEBPACK_IMPORTED_MODULE_21__["default"].removeClass('correcting', textarea);
textarea.focus(); // Trigger input event, so that the textarea resizes
_converse.emit('messageSend', message); // Suppress events, otherwise superfluous CSN gets set const event = document.createEvent('Event');
// immediately after the message, causing rate-limiting issues. event.initEvent('input', true, true);
textarea.dispatchEvent(event);
_converse.emit('messageSend', message);
}
textarea.removeAttribute('disabled'); // Suppress events, otherwise superfluous CSN gets set
// immediately after the message, causing rate-limiting issues.
this.setChatState(_converse.ACTIVE, { this.setChatState(_converse.ACTIVE, {
'silent': true 'silent': true
...@@ -56296,7 +56286,11 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins ...@@ -56296,7 +56286,11 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins
}); });
_converse.log(e, Strophe.LogLevel.ERROR); _converse.log(e, Strophe.LogLevel.ERROR);
return false;
} }
return true;
} else { } else {
return this.__super__.sendMessage.apply(this, arguments); return this.__super__.sendMessage.apply(this, arguments);
} }
...@@ -61901,7 +61895,8 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha ...@@ -61901,7 +61895,8 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
message = this.messages.create(attrs); message = this.messages.create(attrs);
} }
return this.sendMessageStanza(this.createMessageStanza(message)); this.sendMessageStanza(this.createMessageStanza(message));
return true;
}, },
sendChatState() { sendChatState() {
...@@ -115,6 +115,10 @@ body.reset { ...@@ -115,6 +115,10 @@ body.reset {
direction: ltr; direction: ltr;
z-index: 1031; // One more than bootstrap navbar z-index: 1031; // One more than bootstrap navbar
textarea:disabled {
background-color: #EEE !important;
}
.nopadding { .nopadding {
padding: 0 !important; padding: 0 !important;
} }
......
...@@ -284,7 +284,7 @@ ...@@ -284,7 +284,7 @@
done(); done();
})); }));
it("can be closed by clicking a DOM element with class 'close-chatbox-button'", it("can be closed by clicking a DOM element with class 'close-chatbox-button'",
mock.initConverseWithPromises( mock.initConverseWithPromises(
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {}, null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) { async function (done, _converse) {
...@@ -1024,21 +1024,23 @@ ...@@ -1024,21 +1024,23 @@
await test_utils.openChatBoxFor(_converse, contact_jid); await test_utils.openChatBoxFor(_converse, contact_jid);
const view = _converse.chatboxviews.get(contact_jid); const view = _converse.chatboxviews.get(contact_jid);
let message = 'This message is another sent from this chatbox'; let message = 'This message is another sent from this chatbox';
// Lets make sure there is at least one message already await test_utils.sendMessage(view, message);
// (e.g for when this test is run on its own).
test_utils.sendMessage(view, message);
expect(view.model.messages.length > 0).toBeTruthy(); expect(view.model.messages.length > 0).toBeTruthy();
expect(view.model.messages.browserStorage.records.length > 0).toBeTruthy(); expect(view.model.messages.browserStorage.records.length > 0).toBeTruthy();
expect(_converse.emit).toHaveBeenCalledWith('messageSend', message); await test_utils.waitUntil(() => view.el.querySelector('.chat-msg'));
message = '/clear'; message = '/clear';
spyOn(view, 'onMessageSubmitted').and.callThrough();
spyOn(view, 'clearMessages').and.callThrough(); spyOn(view, 'clearMessages').and.callThrough();
spyOn(window, 'confirm').and.callFake(function () { spyOn(window, 'confirm').and.callFake(function () {
return true; return true;
}); });
test_utils.sendMessage(view, message); view.el.querySelector('.chat-textarea').value = message;
expect(view.onMessageSubmitted).toHaveBeenCalled(); view.keyPressed({
target: view.el.querySelector('textarea.chat-textarea'),
preventDefault: _.noop,
keyCode: 13
});
expect(view.clearMessages).toHaveBeenCalled(); expect(view.clearMessages).toHaveBeenCalled();
expect(window.confirm).toHaveBeenCalled(); expect(window.confirm).toHaveBeenCalled();
expect(view.model.messages.length, 0); // The messages must be removed from the chatbox expect(view.model.messages.length, 0); // The messages must be removed from the chatbox
......
This diff is collapsed.
...@@ -102,7 +102,6 @@ ...@@ -102,7 +102,6 @@
await test_utils.openChatBoxFor(_converse, contact_jid); await test_utils.openChatBoxFor(_converse, contact_jid);
await test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]); await test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]);
const view = _converse.chatboxviews.get(contact_jid); const view = _converse.chatboxviews.get(contact_jid);
spyOn(view, 'onMessageSubmitted').and.callThrough();
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
await test_utils.waitUntil(() => view.el.querySelector('.toggle-compose-spoiler')); await test_utils.waitUntil(() => view.el.querySelector('.toggle-compose-spoiler'));
...@@ -116,7 +115,6 @@ ...@@ -116,7 +115,6 @@
preventDefault: _.noop, preventDefault: _.noop,
keyCode: 13 keyCode: 13
}); });
expect(view.onMessageSubmitted).toHaveBeenCalled();
await new Promise((resolve, reject) => view.once('messageInserted', resolve)); await new Promise((resolve, reject) => view.once('messageInserted', resolve));
/* Test the XML stanza /* Test the XML stanza
...@@ -184,7 +182,6 @@ ...@@ -184,7 +182,6 @@
let spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler'); let spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
spoiler_toggle.click(); spoiler_toggle.click();
spyOn(view, 'onMessageSubmitted').and.callThrough();
spyOn(_converse.connection, 'send'); spyOn(_converse.connection, 'send');
const textarea = view.el.querySelector('.chat-textarea'); const textarea = view.el.querySelector('.chat-textarea');
...@@ -197,7 +194,6 @@ ...@@ -197,7 +194,6 @@
preventDefault: _.noop, preventDefault: _.noop,
keyCode: 13 keyCode: 13
}); });
expect(view.onMessageSubmitted).toHaveBeenCalled();
await new Promise((resolve, reject) => view.once('messageInserted', resolve)); await new Promise((resolve, reject) => view.once('messageInserted', resolve));
/* Test the XML stanza /* Test the XML stanza
......
...@@ -818,29 +818,6 @@ converse.plugins.add('converse-chatview', { ...@@ -818,29 +818,6 @@ converse.plugins.add('converse-chatview', {
} }
}, },
onMessageSubmitted (text, spoiler_hint) {
/* This method gets called once the user has typed a message
* and then pressed enter in a chat box.
*
* Parameters:
* (String) text - The chat message text.
* (String) spoiler_hint - A hint in case the message
* text is a hidden/spoiler message. See XEP-0382
*/
if (!_converse.connection.authenticated) {
return this.showHelpMessages(
['Sorry, the connection has been lost, '+
'and your message could not be sent'],
'error'
);
}
if (this.parseMessageForCommands(text)) {
return;
}
const attrs = this.model.getOutgoingMessageAttributes(text, spoiler_hint);
this.model.sendMessage(attrs);
},
setChatState (state, options) { setChatState (state, options) {
/* Mutator for setting the chat state of this chat session. /* Mutator for setting the chat state of this chat session.
* Handles clearing of any chat state notification timeouts and * Handles clearing of any chat state notification timeouts and
...@@ -873,7 +850,7 @@ converse.plugins.add('converse-chatview', { ...@@ -873,7 +850,7 @@ converse.plugins.add('converse-chatview', {
return this; return this;
}, },
onFormSubmitted (ev) { async onFormSubmitted (ev) {
ev.preventDefault(); ev.preventDefault();
const textarea = this.el.querySelector('.chat-textarea'), const textarea = this.el.querySelector('.chat-textarea'),
message = textarea.value; message = textarea.value;
...@@ -881,22 +858,34 @@ converse.plugins.add('converse-chatview', { ...@@ -881,22 +858,34 @@ converse.plugins.add('converse-chatview', {
if (!message.replace(/\s/g, '').length) { if (!message.replace(/\s/g, '').length) {
return; return;
} }
let spoiler_hint; if (!_converse.connection.authenticated) {
this.showHelpMessages(
['Sorry, the connection has been lost, and your message could not be sent'],
'error'
);
return;
}
let spoiler_hint, hint_el = {};
if (this.model.get('composing_spoiler')) { if (this.model.get('composing_spoiler')) {
const hint_el = this.el.querySelector('form.sendXMPPMessage input.spoiler-hint'); hint_el = this.el.querySelector('form.sendXMPPMessage input.spoiler-hint');
spoiler_hint = hint_el.value; spoiler_hint = hint_el.value;
hint_el.value = '';
} }
textarea.value = ''; u.addClass('disabled', textarea);
u.removeClass('correcting', textarea); textarea.setAttribute('disabled', 'disabled');
textarea.focus(); if (this.parseMessageForCommands(message) ||
// Trigger input event, so that the textarea resizes await this.model.sendMessage(this.model.getOutgoingMessageAttributes(message, spoiler_hint))) {
const event = document.createEvent('Event');
event.initEvent('input', true, true);
textarea.dispatchEvent(event);
this.onMessageSubmitted(message, spoiler_hint); hint_el.value = '';
_converse.emit('messageSend', message); textarea.value = '';
u.removeClass('correcting', textarea);
textarea.focus();
// Trigger input event, so that the textarea resizes
const event = document.createEvent('Event');
event.initEvent('input', true, true);
textarea.dispatchEvent(event);
_converse.emit('messageSend', message);
}
textarea.removeAttribute('disabled');
// Suppress events, otherwise superfluous CSN gets set // Suppress events, otherwise superfluous CSN gets set
// immediately after the message, causing rate-limiting issues. // immediately after the message, causing rate-limiting issues.
this.setChatState(_converse.ACTIVE, {'silent': true}); this.setChatState(_converse.ACTIVE, {'silent': true});
......
...@@ -326,7 +326,9 @@ converse.plugins.add('converse-omemo', { ...@@ -326,7 +326,9 @@ converse.plugins.add('converse-omemo', {
'type': 'error', 'type': 'error',
}); });
_converse.log(e, Strophe.LogLevel.ERROR); _converse.log(e, Strophe.LogLevel.ERROR);
return false;
} }
return true;
} else { } else {
return this.__super__.sendMessage.apply(this, arguments); return this.__super__.sendMessage.apply(this, arguments);
} }
......
...@@ -433,7 +433,8 @@ converse.plugins.add('converse-chatboxes', { ...@@ -433,7 +433,8 @@ converse.plugins.add('converse-chatboxes', {
} else { } else {
message = this.messages.create(attrs); message = this.messages.create(attrs);
} }
return this.sendMessageStanza(this.createMessageStanza(message)); this.sendMessageStanza(this.createMessageStanza(message));
return true;
}, },
sendChatState () { sendChatState () {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment