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.
This commit is contained in:
parent
85dab7367b
commit
d051085626
@ -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 {
|
||||||
|
71
dist/converse.js
vendored
71
dist/converse.js
vendored
@ -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
|
|||||||
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,27 +50235,38 @@ _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');
|
||||||
if (this.model.get('composing_spoiler')) {
|
return;
|
||||||
const hint_el = this.el.querySelector('form.sendXMPPMessage input.spoiler-hint');
|
|
||||||
spoiler_hint = hint_el.value;
|
|
||||||
hint_el.value = '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
textarea.value = '';
|
let spoiler_hint,
|
||||||
_converse_headless_utils_emoji__WEBPACK_IMPORTED_MODULE_21__["default"].removeClass('correcting', textarea);
|
hint_el = {};
|
||||||
textarea.focus(); // Trigger input event, so that the textarea resizes
|
|
||||||
|
|
||||||
const event = document.createEvent('Event');
|
if (this.model.get('composing_spoiler')) {
|
||||||
event.initEvent('input', true, true);
|
hint_el = this.el.querySelector('form.sendXMPPMessage input.spoiler-hint');
|
||||||
textarea.dispatchEvent(event);
|
spoiler_hint = hint_el.value;
|
||||||
this.onMessageSubmitted(message, spoiler_hint);
|
}
|
||||||
|
|
||||||
_converse.emit('messageSend', message); // Suppress events, otherwise superfluous CSN gets set
|
_converse_headless_utils_emoji__WEBPACK_IMPORTED_MODULE_21__["default"].addClass('disabled', textarea);
|
||||||
|
textarea.setAttribute('disabled', 'disabled');
|
||||||
|
|
||||||
|
if (this.parseMessageForCommands(message) || (await this.model.sendMessage(this.model.getOutgoingMessageAttributes(message, spoiler_hint)))) {
|
||||||
|
hint_el.value = '';
|
||||||
|
textarea.value = '';
|
||||||
|
_converse_headless_utils_emoji__WEBPACK_IMPORTED_MODULE_21__["default"].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
|
||||||
// immediately after the message, causing rate-limiting issues.
|
// 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
|
|||||||
});
|
});
|
||||||
|
|
||||||
_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
|
|||||||
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 {
|
|||||||
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 @@
|
|||||||
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 @@
|
|||||||
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
|
||||||
|
@ -2535,7 +2535,6 @@
|
|||||||
|
|
||||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
||||||
const view = _converse.chatboxviews.get('lounge@localhost');
|
const view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
|
||||||
var textarea = view.el.querySelector('.chat-textarea');
|
var textarea = view.el.querySelector('.chat-textarea');
|
||||||
textarea.value = '/help This is the groupchat subject';
|
textarea.value = '/help This is the groupchat subject';
|
||||||
view.keyPressed({
|
view.keyPressed({
|
||||||
@ -2544,7 +2543,6 @@
|
|||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
|
||||||
const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
|
const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
|
||||||
expect(info_messages.length).toBe(18);
|
expect(info_messages.length).toBe(18);
|
||||||
expect(info_messages.pop().textContent).toBe('/voice: Allow muted user to post messages');
|
expect(info_messages.pop().textContent).toBe('/voice: Allow muted user to post messages');
|
||||||
@ -2723,7 +2721,6 @@
|
|||||||
|
|
||||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
||||||
const view = _converse.chatboxviews.get('lounge@localhost');
|
const view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
|
||||||
spyOn(view, 'clearMessages');
|
spyOn(view, 'clearMessages');
|
||||||
let sent_stanza;
|
let sent_stanza;
|
||||||
spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
|
spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
|
||||||
@ -2737,7 +2734,6 @@
|
|||||||
preventDefault: _.noop,
|
preventDefault: _.noop,
|
||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
|
||||||
expect(_converse.connection.send).toHaveBeenCalled();
|
expect(_converse.connection.send).toHaveBeenCalled();
|
||||||
expect(sent_stanza.textContent).toBe('This is the groupchat subject');
|
expect(sent_stanza.textContent).toBe('This is the groupchat subject');
|
||||||
|
|
||||||
@ -2777,7 +2773,6 @@
|
|||||||
|
|
||||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
||||||
const view = _converse.chatboxviews.get('lounge@localhost');
|
const view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
|
||||||
spyOn(view, 'clearMessages');
|
spyOn(view, 'clearMessages');
|
||||||
const textarea = view.el.querySelector('.chat-textarea')
|
const textarea = view.el.querySelector('.chat-textarea')
|
||||||
textarea.value = '/clear';
|
textarea.value = '/clear';
|
||||||
@ -2786,7 +2781,6 @@
|
|||||||
preventDefault: _.noop,
|
preventDefault: _.noop,
|
||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
|
||||||
expect(view.clearMessages).toHaveBeenCalled();
|
expect(view.clearMessages).toHaveBeenCalled();
|
||||||
done();
|
done();
|
||||||
}));
|
}));
|
||||||
@ -2805,7 +2799,6 @@
|
|||||||
|
|
||||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
||||||
const view = _converse.chatboxviews.get('lounge@localhost');
|
const view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
|
||||||
spyOn(view.model, 'setAffiliation').and.callThrough();
|
spyOn(view.model, 'setAffiliation').and.callThrough();
|
||||||
spyOn(view, 'showErrorMessage').and.callThrough();
|
spyOn(view, 'showErrorMessage').and.callThrough();
|
||||||
spyOn(view, 'validateRoleChangeCommand').and.callThrough();
|
spyOn(view, 'validateRoleChangeCommand').and.callThrough();
|
||||||
@ -2830,22 +2823,27 @@
|
|||||||
preventDefault: _.noop,
|
preventDefault: _.noop,
|
||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
|
||||||
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
||||||
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
||||||
"Error: the \"owner\" command takes two arguments, the user's nickname and optionally a reason.");
|
"Error: the \"owner\" command takes two arguments, the user's nickname and optionally a reason.");
|
||||||
expect(view.model.setAffiliation).not.toHaveBeenCalled();
|
expect(view.model.setAffiliation).not.toHaveBeenCalled();
|
||||||
|
// XXX: Calling onFormSubmitted directly, trying
|
||||||
|
// again via triggering Event doesn't work for some weird
|
||||||
|
// reason.
|
||||||
|
textarea.value = '/owner nobody You\'re responsible';
|
||||||
|
view.onFormSubmitted(new Event('submit'));
|
||||||
|
|
||||||
view.onMessageSubmitted('/owner nobody You\'re responsible');
|
|
||||||
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
||||||
'Error: couldn\'t find a groupchat participant "nobody"');
|
'Error: couldn\'t find a groupchat participant "nobody"');
|
||||||
expect(view.model.setAffiliation).not.toHaveBeenCalled();
|
expect(view.model.setAffiliation).not.toHaveBeenCalled();
|
||||||
|
|
||||||
// Call now with the correct amount of arguments.
|
// Call now with the correct of arguments.
|
||||||
// XXX: Calling onMessageSubmitted directly, trying
|
// XXX: Calling onFormSubmitted directly, trying
|
||||||
// again via triggering Event doesn't work for some weird
|
// again via triggering Event doesn't work for some weird
|
||||||
// reason.
|
// reason.
|
||||||
view.onMessageSubmitted('/owner annoyingGuy You\'re responsible');
|
textarea.value = '/owner annoyingGuy You\'re responsible';
|
||||||
|
view.onFormSubmitted(new Event('submit'));
|
||||||
|
|
||||||
expect(view.validateRoleChangeCommand.calls.count()).toBe(3);
|
expect(view.validateRoleChangeCommand.calls.count()).toBe(3);
|
||||||
expect(view.model.setAffiliation).toHaveBeenCalled();
|
expect(view.model.setAffiliation).toHaveBeenCalled();
|
||||||
expect(view.showErrorMessage.calls.count()).toBe(2);
|
expect(view.showErrorMessage.calls.count()).toBe(2);
|
||||||
@ -2889,7 +2887,6 @@
|
|||||||
|
|
||||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
||||||
const view = _converse.chatboxviews.get('lounge@localhost');
|
const view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
|
||||||
spyOn(view.model, 'setAffiliation').and.callThrough();
|
spyOn(view.model, 'setAffiliation').and.callThrough();
|
||||||
spyOn(view, 'showErrorMessage').and.callThrough();
|
spyOn(view, 'showErrorMessage').and.callThrough();
|
||||||
spyOn(view, 'validateRoleChangeCommand').and.callThrough();
|
spyOn(view, 'validateRoleChangeCommand').and.callThrough();
|
||||||
@ -2914,17 +2911,17 @@
|
|||||||
preventDefault: _.noop,
|
preventDefault: _.noop,
|
||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
|
||||||
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
||||||
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
||||||
"Error: the \"ban\" command takes two arguments, the user's nickname and optionally a reason.");
|
"Error: the \"ban\" command takes two arguments, the user's nickname and optionally a reason.");
|
||||||
expect(view.model.setAffiliation).not.toHaveBeenCalled();
|
expect(view.model.setAffiliation).not.toHaveBeenCalled();
|
||||||
// Call now with the correct amount of arguments.
|
// Call now with the correct amount of arguments.
|
||||||
|
// XXX: Calling onFormSubmitted directly, trying
|
||||||
// XXX: Calling onMessageSubmitted directly, trying
|
|
||||||
// again via triggering Event doesn't work for some weird
|
// again via triggering Event doesn't work for some weird
|
||||||
// reason.
|
// reason.
|
||||||
view.onMessageSubmitted('/ban annoyingGuy You\'re annoying');
|
textarea.value = '/ban annoyingGuy You\'re annoying';
|
||||||
|
view.onFormSubmitted(new Event('submit'));
|
||||||
|
|
||||||
expect(view.validateRoleChangeCommand.calls.count()).toBe(2);
|
expect(view.validateRoleChangeCommand.calls.count()).toBe(2);
|
||||||
expect(view.showErrorMessage.calls.count()).toBe(1);
|
expect(view.showErrorMessage.calls.count()).toBe(1);
|
||||||
expect(view.model.setAffiliation).toHaveBeenCalled();
|
expect(view.model.setAffiliation).toHaveBeenCalled();
|
||||||
@ -2970,7 +2967,6 @@
|
|||||||
|
|
||||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
||||||
const view = _converse.chatboxviews.get('lounge@localhost');
|
const view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
|
||||||
spyOn(view, 'modifyRole').and.callThrough();
|
spyOn(view, 'modifyRole').and.callThrough();
|
||||||
spyOn(view, 'showErrorMessage').and.callThrough();
|
spyOn(view, 'showErrorMessage').and.callThrough();
|
||||||
spyOn(view, 'validateRoleChangeCommand').and.callThrough();
|
spyOn(view, 'validateRoleChangeCommand').and.callThrough();
|
||||||
@ -2995,16 +2991,17 @@
|
|||||||
preventDefault: _.noop,
|
preventDefault: _.noop,
|
||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
|
||||||
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
||||||
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
||||||
"Error: the \"kick\" command takes two arguments, the user's nickname and optionally a reason.");
|
"Error: the \"kick\" command takes two arguments, the user's nickname and optionally a reason.");
|
||||||
expect(view.modifyRole).not.toHaveBeenCalled();
|
expect(view.modifyRole).not.toHaveBeenCalled();
|
||||||
// Call now with the correct amount of arguments.
|
// Call now with the correct amount of arguments.
|
||||||
// XXX: Calling onMessageSubmitted directly, trying
|
// XXX: Calling onFormSubmitted directly, trying
|
||||||
// again via triggering Event doesn't work for some weird
|
// again via triggering Event doesn't work for some weird
|
||||||
// reason.
|
// reason.
|
||||||
view.onMessageSubmitted('/kick annoyingGuy You\'re annoying');
|
textarea.value = '/kick annoyingGuy You\'re annoying';
|
||||||
|
view.onFormSubmitted(new Event('submit'));
|
||||||
|
|
||||||
expect(view.validateRoleChangeCommand.calls.count()).toBe(2);
|
expect(view.validateRoleChangeCommand.calls.count()).toBe(2);
|
||||||
expect(view.showErrorMessage.calls.count()).toBe(1);
|
expect(view.showErrorMessage.calls.count()).toBe(1);
|
||||||
expect(view.modifyRole).toHaveBeenCalled();
|
expect(view.modifyRole).toHaveBeenCalled();
|
||||||
@ -3058,7 +3055,6 @@
|
|||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
});
|
});
|
||||||
var view = _converse.chatboxviews.get('lounge@localhost');
|
var view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
|
||||||
spyOn(view, 'modifyRole').and.callThrough();
|
spyOn(view, 'modifyRole').and.callThrough();
|
||||||
spyOn(view, 'showErrorMessage').and.callThrough();
|
spyOn(view, 'showErrorMessage').and.callThrough();
|
||||||
spyOn(view, 'showChatEvent').and.callThrough();
|
spyOn(view, 'showChatEvent').and.callThrough();
|
||||||
@ -3097,17 +3093,18 @@
|
|||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
|
||||||
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
||||||
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
||||||
"Error: the \"op\" command takes two arguments, the user's nickname and optionally a reason.");
|
"Error: the \"op\" command takes two arguments, the user's nickname and optionally a reason.");
|
||||||
|
|
||||||
expect(view.modifyRole).not.toHaveBeenCalled();
|
expect(view.modifyRole).not.toHaveBeenCalled();
|
||||||
// Call now with the correct amount of arguments.
|
// Call now with the correct amount of arguments.
|
||||||
// XXX: Calling onMessageSubmitted directly, trying
|
// XXX: Calling onFormSubmitted directly, trying
|
||||||
// again via triggering Event doesn't work for some weird
|
// again via triggering Event doesn't work for some weird
|
||||||
// reason.
|
// reason.
|
||||||
view.onMessageSubmitted('/op trustworthyguy You\'re trustworthy');
|
textarea.value = '/op trustworthyguy You\'re trustworthy';
|
||||||
|
view.onFormSubmitted(new Event('submit'));
|
||||||
|
|
||||||
expect(view.validateRoleChangeCommand.calls.count()).toBe(2);
|
expect(view.validateRoleChangeCommand.calls.count()).toBe(2);
|
||||||
expect(view.showErrorMessage.calls.count()).toBe(1);
|
expect(view.showErrorMessage.calls.count()).toBe(1);
|
||||||
expect(view.modifyRole).toHaveBeenCalled();
|
expect(view.modifyRole).toHaveBeenCalled();
|
||||||
@ -3143,8 +3140,13 @@
|
|||||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||||
info_msgs = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
|
info_msgs = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
|
||||||
expect(info_msgs.pop().textContent).toBe("trustworthyguy is now a moderator");
|
expect(info_msgs.pop().textContent).toBe("trustworthyguy is now a moderator");
|
||||||
|
// Call now with the correct amount of arguments.
|
||||||
|
// XXX: Calling onFormSubmitted directly, trying
|
||||||
|
// again via triggering Event doesn't work for some weird
|
||||||
|
// reason.
|
||||||
|
textarea.value = '/deop trustworthyguy Perhaps not';
|
||||||
|
view.onFormSubmitted(new Event('submit'));
|
||||||
|
|
||||||
view.onMessageSubmitted('/deop trustworthyguy Perhaps not');
|
|
||||||
expect(view.validateRoleChangeCommand.calls.count()).toBe(3);
|
expect(view.validateRoleChangeCommand.calls.count()).toBe(3);
|
||||||
expect(view.showChatEvent.calls.count()).toBe(1);
|
expect(view.showChatEvent.calls.count()).toBe(1);
|
||||||
expect(view.modifyRole).toHaveBeenCalled();
|
expect(view.modifyRole).toHaveBeenCalled();
|
||||||
@ -3195,7 +3197,6 @@
|
|||||||
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
IQ_id = sendIQ.bind(this)(iq, callback, errback);
|
||||||
});
|
});
|
||||||
var view = _converse.chatboxviews.get('lounge@localhost');
|
var view = _converse.chatboxviews.get('lounge@localhost');
|
||||||
spyOn(view, 'onMessageSubmitted').and.callThrough();
|
|
||||||
spyOn(view, 'modifyRole').and.callThrough();
|
spyOn(view, 'modifyRole').and.callThrough();
|
||||||
spyOn(view, 'showErrorMessage').and.callThrough();
|
spyOn(view, 'showErrorMessage').and.callThrough();
|
||||||
spyOn(view, 'showChatEvent').and.callThrough();
|
spyOn(view, 'showChatEvent').and.callThrough();
|
||||||
@ -3226,7 +3227,7 @@
|
|||||||
var info_msgs = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
|
var info_msgs = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
|
||||||
expect(info_msgs.pop().textContent).toBe("annoyingGuy has entered the groupchat");
|
expect(info_msgs.pop().textContent).toBe("annoyingGuy has entered the groupchat");
|
||||||
|
|
||||||
var textarea = view.el.querySelector('.chat-textarea')
|
const textarea = view.el.querySelector('.chat-textarea')
|
||||||
textarea.value = '/mute';
|
textarea.value = '/mute';
|
||||||
view.keyPressed({
|
view.keyPressed({
|
||||||
target: textarea,
|
target: textarea,
|
||||||
@ -3234,16 +3235,17 @@
|
|||||||
keyCode: 13
|
keyCode: 13
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(view.onMessageSubmitted).toHaveBeenCalled();
|
|
||||||
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
expect(view.validateRoleChangeCommand).toHaveBeenCalled();
|
||||||
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
expect(view.showErrorMessage).toHaveBeenCalledWith(
|
||||||
"Error: the \"mute\" command takes two arguments, the user's nickname and optionally a reason.");
|
"Error: the \"mute\" command takes two arguments, the user's nickname and optionally a reason.");
|
||||||
expect(view.modifyRole).not.toHaveBeenCalled();
|
expect(view.modifyRole).not.toHaveBeenCalled();
|
||||||
// Call now with the correct amount of arguments.
|
// Call now with the correct amount of arguments.
|
||||||
// XXX: Calling onMessageSubmitted directly, trying
|
// XXX: Calling onFormSubmitted directly, trying
|
||||||
// again via triggering Event doesn't work for some weird
|
// again via triggering Event doesn't work for some weird
|
||||||
// reason.
|
// reason.
|
||||||
view.onMessageSubmitted('/mute annoyingGuy You\'re annoying');
|
textarea.value = '/mute annoyingGuy You\'re annoying';
|
||||||
|
view.onFormSubmitted(new Event('submit'));
|
||||||
|
|
||||||
expect(view.validateRoleChangeCommand.calls.count()).toBe(2);
|
expect(view.validateRoleChangeCommand.calls.count()).toBe(2);
|
||||||
expect(view.showErrorMessage.calls.count()).toBe(1);
|
expect(view.showErrorMessage.calls.count()).toBe(1);
|
||||||
expect(view.modifyRole).toHaveBeenCalled();
|
expect(view.modifyRole).toHaveBeenCalled();
|
||||||
@ -3280,7 +3282,13 @@
|
|||||||
info_msgs = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
|
info_msgs = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
|
||||||
expect(info_msgs.pop().textContent).toBe("annoyingGuy has been muted");
|
expect(info_msgs.pop().textContent).toBe("annoyingGuy has been muted");
|
||||||
|
|
||||||
view.onMessageSubmitted('/voice annoyingGuy Now you can talk again');
|
// Call now with the correct of arguments.
|
||||||
|
// XXX: Calling onFormSubmitted directly, trying
|
||||||
|
// again via triggering Event doesn't work for some weird
|
||||||
|
// reason.
|
||||||
|
textarea.value = '/voice annoyingGuy Now you can talk again';
|
||||||
|
view.onFormSubmitted(new Event('submit'));
|
||||||
|
|
||||||
expect(view.validateRoleChangeCommand.calls.count()).toBe(3);
|
expect(view.validateRoleChangeCommand.calls.count()).toBe(3);
|
||||||
expect(view.showChatEvent.calls.count()).toBe(1);
|
expect(view.showChatEvent.calls.count()).toBe(1);
|
||||||
expect(view.modifyRole).toHaveBeenCalled();
|
expect(view.modifyRole).toHaveBeenCalled();
|
||||||
|
@ -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 @@
|
|||||||
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 @@
|
|||||||
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 @@
|
|||||||
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', {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
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', {
|
|||||||
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', {
|
|||||||
if (!message.replace(/\s/g, '').length) {
|
if (!message.replace(/\s/g, '').length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let spoiler_hint;
|
if (!_converse.connection.authenticated) {
|
||||||
if (this.model.get('composing_spoiler')) {
|
this.showHelpMessages(
|
||||||
const hint_el = this.el.querySelector('form.sendXMPPMessage input.spoiler-hint');
|
['Sorry, the connection has been lost, and your message could not be sent'],
|
||||||
spoiler_hint = hint_el.value;
|
'error'
|
||||||
hint_el.value = '';
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
textarea.value = '';
|
let spoiler_hint, hint_el = {};
|
||||||
u.removeClass('correcting', textarea);
|
if (this.model.get('composing_spoiler')) {
|
||||||
textarea.focus();
|
hint_el = this.el.querySelector('form.sendXMPPMessage input.spoiler-hint');
|
||||||
// Trigger input event, so that the textarea resizes
|
spoiler_hint = hint_el.value;
|
||||||
const event = document.createEvent('Event');
|
}
|
||||||
event.initEvent('input', true, true);
|
u.addClass('disabled', textarea);
|
||||||
textarea.dispatchEvent(event);
|
textarea.setAttribute('disabled', 'disabled');
|
||||||
|
if (this.parseMessageForCommands(message) ||
|
||||||
|
await this.model.sendMessage(this.model.getOutgoingMessageAttributes(message, spoiler_hint))) {
|
||||||
|
|
||||||
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', {
|
|||||||
'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', {
|
|||||||
} 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 () {
|
||||||
|
Loading…
Reference in New Issue
Block a user