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) {
this.onFormSubmitted(ev);
} 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) {
this.cancelMessageCorrection();
this.editLaterMessage();
} 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
// (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() {
this.insertIntoTextArea('', true);
this.model.messages.where('correcting').forEach(msg => msg.save('correcting', false));
editLaterMessage() {
let message;
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() {
const msg = _.findLast(this.model.messages.models, msg => msg.get('message'));
editEarlierMessage() {
let message;
let idx = this.model.messages.findLastIndex('correcting');
if (msg) {
this.insertIntoTextArea(msg.get('message'), true); // We don't set "correcting" the Backbone-way, because
// we don't want it to persist to storage.
if (idx >= 0) {
this.model.messages.at(idx).save('correcting', false);
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) {
const textbox_el = this.el.querySelector('.chat-textarea');
const textarea = this.el.querySelector('.chat-textarea');
if (replace) {
textbox_el.value = value;
textarea.value = value;
} else {
let existing = textbox_el.value;
let existing = textarea.value;
if (existing && existing[existing.length - 1] !== ' ') {
existing = existing + ' ';
}
textbox_el.value = existing + value + ' ';
textarea.value = existing + value + ' ';
}
textbox_el.focus();
textarea.focus();
},
createEmojiPicker() {

View File

@ -106,6 +106,62 @@
expect(view.model.messages.at(0).get('correcting')).toBe(false);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
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();
}));

View File

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