Allow any earlier message to be edited.

updates #421
This commit is contained in:
JC Brand 2018-07-08 15:20:58 +02:00
parent a9bb99a1a7
commit b4d2007972
3 changed files with 149 additions and 33 deletions

66
dist/converse.js vendored
View File

@ -70210,9 +70210,9 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
if (ev.keyCode === KEY.ENTER) { if (ev.keyCode === KEY.ENTER) {
this.onFormSubmitted(ev); this.onFormSubmitted(ev);
} else if (ev.keyCode === KEY.UP_ARROW && !ev.target.selectionEnd) { } else if (ev.keyCode === KEY.UP_ARROW && !ev.target.selectionEnd) {
this.editPreviousMessage(); this.editEarlierMessage();
} else if (ev.keyCode === KEY.DOWN_ARROW && ev.target.selectionEnd === ev.target.value.length) { } else if (ev.keyCode === KEY.DOWN_ARROW && ev.target.selectionEnd === ev.target.value.length) {
this.cancelMessageCorrection(); this.editLaterMessage();
} else if (ev.keyCode !== KEY.FORWARD_SLASH && this.model.get('chat_state') !== _converse.COMPOSING) { } else if (ev.keyCode !== KEY.FORWARD_SLASH && this.model.get('chat_state') !== _converse.COMPOSING) {
// Set chat state to composing if keyCode is not a forward-slash // Set chat state to composing if keyCode is not a forward-slash
// (which would imply an internal command and not a message). // (which would imply an internal command and not a message).
@ -70220,19 +70220,53 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
} }
}, },
cancelMessageCorrection() { editLaterMessage() {
this.insertIntoTextArea('', true); let message;
this.model.messages.where('correcting').forEach(msg => msg.save('correcting', false)); let idx = this.model.messages.findLastIndex('correcting');
if (idx >= 0) {
this.model.messages.at(idx).save('correcting', false);
while (idx < this.model.messages.length - 1) {
idx += 1;
if (this.model.messages.at(idx).get('message')) {
message = this.model.messages.at(idx);
break;
}
}
}
if (message) {
this.insertIntoTextArea(message.get('message'), true);
message.save('correcting', true);
} else {
this.insertIntoTextArea('', true);
}
}, },
editPreviousMessage() { editEarlierMessage() {
const msg = _.findLast(this.model.messages.models, msg => msg.get('message')); let message;
let idx = this.model.messages.findLastIndex('correcting');
if (msg) { if (idx >= 0) {
this.insertIntoTextArea(msg.get('message'), true); // We don't set "correcting" the Backbone-way, because this.model.messages.at(idx).save('correcting', false);
// we don't want it to persist to storage.
msg.save('correcting', true); while (idx > 0) {
idx -= 1;
if (this.model.messages.at(idx).get('message')) {
message = this.model.messages.at(idx);
break;
}
}
}
message = message || _.findLast(this.model.messages.models, msg => msg.get('message'));
if (message) {
this.insertIntoTextArea(message.get('message'), true);
message.save('correcting', true);
} }
}, },
@ -70260,21 +70294,21 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
}, },
insertIntoTextArea(value, replace = false) { insertIntoTextArea(value, replace = false) {
const textbox_el = this.el.querySelector('.chat-textarea'); const textarea = this.el.querySelector('.chat-textarea');
if (replace) { if (replace) {
textbox_el.value = value; textarea.value = value;
} else { } else {
let existing = textbox_el.value; let existing = textarea.value;
if (existing && existing[existing.length - 1] !== ' ') { if (existing && existing[existing.length - 1] !== ' ') {
existing = existing + ' '; existing = existing + ' ';
} }
textbox_el.value = existing + value + ' '; textarea.value = existing + value + ' ';
} }
textbox_el.focus(); textarea.focus();
}, },
createEmojiPicker() { createEmojiPicker() {

View File

@ -106,6 +106,62 @@
expect(view.model.messages.at(0).get('correcting')).toBe(false); expect(view.model.messages.at(0).get('correcting')).toBe(false);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1); expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(u.hasClass('correcting', view.el.querySelector('.chat-msg'))).toBe(false); expect(u.hasClass('correcting', view.el.querySelector('.chat-msg'))).toBe(false);
textarea.value = 'It is the east, and Juliet is the one.';
view.keyPressed({
target: textarea,
preventDefault: _.noop,
keyCode: 13 // Enter
});
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
textarea.value = 'Arise, fair sun, and kill the envious moon';
view.keyPressed({
target: textarea,
preventDefault: _.noop,
keyCode: 13 // Enter
});
expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
view.keyPressed({
target: textarea,
keyCode: 38 // Up arrow
});
expect(textarea.value).toBe('Arise, fair sun, and kill the envious moon');
expect(view.model.messages.at(0).get('correcting')).toBeFalsy();
expect(view.model.messages.at(1).get('correcting')).toBeFalsy();
expect(view.model.messages.at(2).get('correcting')).toBe(true);
textarea.selectionEnd = 0; // Happens by pressing up,
// but for some reason not in tests, so we set it manually.
view.keyPressed({
target: textarea,
keyCode: 38 // Up arrow
});
expect(textarea.value).toBe('It is the east, and Juliet is the one.');
expect(view.model.messages.at(0).get('correcting')).toBeFalsy();
expect(view.model.messages.at(1).get('correcting')).toBe(true);
expect(view.model.messages.at(2).get('correcting')).toBeFalsy();
textarea.value = 'It is the east, and Juliet is the sun.';
view.keyPressed({
target: textarea,
preventDefault: _.noop,
keyCode: 13 // Enter
});
expect(textarea.value).toBe('');
const messages = view.el.querySelectorAll('.chat-msg');
expect(messages.length).toBe(3);
expect(messages[0].querySelector('.chat-msg-text').textContent)
.toBe('But soft, what light through yonder window breaks?');
expect(messages[1].querySelector('.chat-msg-text').textContent)
.toBe('It is the east, and Juliet is the sun.');
expect(messages[2].querySelector('.chat-msg-text').textContent)
.toBe('Arise, fair sun, and kill the envious moon');
expect(view.model.messages.at(0).get('correcting')).toBeFalsy();
expect(view.model.messages.at(1).get('correcting')).toBeFalsy();
expect(view.model.messages.at(2).get('correcting')).toBeFalsy();
done(); done();
})); }));

View File

@ -919,9 +919,9 @@
if (ev.keyCode === KEY.ENTER) { if (ev.keyCode === KEY.ENTER) {
this.onFormSubmitted(ev); this.onFormSubmitted(ev);
} else if (ev.keyCode === KEY.UP_ARROW && !ev.target.selectionEnd) { } else if (ev.keyCode === KEY.UP_ARROW && !ev.target.selectionEnd) {
this.editPreviousMessage(); this.editEarlierMessage();
} else if (ev.keyCode === KEY.DOWN_ARROW && ev.target.selectionEnd === ev.target.value.length) { } else if (ev.keyCode === KEY.DOWN_ARROW && ev.target.selectionEnd === ev.target.value.length) {
this.cancelMessageCorrection(); this.editLaterMessage();
} else if (ev.keyCode !== KEY.FORWARD_SLASH && this.model.get('chat_state') !== _converse.COMPOSING) { } else if (ev.keyCode !== KEY.FORWARD_SLASH && this.model.get('chat_state') !== _converse.COMPOSING) {
// Set chat state to composing if keyCode is not a forward-slash // Set chat state to composing if keyCode is not a forward-slash
// (which would imply an internal command and not a message). // (which would imply an internal command and not a message).
@ -929,18 +929,44 @@
} }
}, },
cancelMessageCorrection () { editLaterMessage () {
this.insertIntoTextArea('', true); let message;
this.model.messages.where('correcting').forEach(msg => msg.save('correcting', false)); let idx = this.model.messages.findLastIndex('correcting');
if (idx >= 0) {
this.model.messages.at(idx).save('correcting', false);
while (idx < this.model.messages.length-1) {
idx += 1;
if (this.model.messages.at(idx).get('message')) {
message = this.model.messages.at(idx);
break;
}
}
}
if (message) {
this.insertIntoTextArea(message.get('message'), true);
message.save('correcting', true);
} else {
this.insertIntoTextArea('', true);
}
}, },
editPreviousMessage () { editEarlierMessage () {
const msg = _.findLast(this.model.messages.models, (msg) => msg.get('message')); let message;
if (msg) { let idx = this.model.messages.findLastIndex('correcting');
this.insertIntoTextArea(msg.get('message'), true); if (idx >= 0) {
// We don't set "correcting" the Backbone-way, because this.model.messages.at(idx).save('correcting', false);
// we don't want it to persist to storage. while (idx > 0) {
msg.save('correcting', true); idx -= 1;
if (this.model.messages.at(idx).get('message')) {
message = this.model.messages.at(idx);
break;
}
}
}
message = message || _.findLast(this.model.messages.models, (msg) => msg.get('message'));
if (message) {
this.insertIntoTextArea(message.get('message'), true);
message.save('correcting', true);
} }
}, },
@ -961,17 +987,17 @@
}, },
insertIntoTextArea (value, replace=false) { insertIntoTextArea (value, replace=false) {
const textbox_el = this.el.querySelector('.chat-textarea'); const textarea = this.el.querySelector('.chat-textarea');
if (replace) { if (replace) {
textbox_el.value = value; textarea.value = value;
} else { } else {
let existing = textbox_el.value; let existing = textarea.value;
if (existing && (existing[existing.length-1] !== ' ')) { if (existing && (existing[existing.length-1] !== ' ')) {
existing = existing + ' '; existing = existing + ' ';
} }
textbox_el.value = existing+value+' '; textarea.value = existing+value+' ';
} }
textbox_el.focus() textarea.focus()
}, },
createEmojiPicker () { createEmojiPicker () {