Commit 84a10d77 authored by JC Brand's avatar JC Brand

Cancel message correction by pressing the down arrow

Also, add a class `correcting` to the message being corrected, to
provide a visual cue.

updates #421
parent 39c85db1
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
"array-bracket-spacing": "off", "array-bracket-spacing": "off",
"array-callback-return": "error", "array-callback-return": "error",
"arrow-body-style": "off", "arrow-body-style": "off",
"arrow-parens": "error", "arrow-parens": "off",
"arrow-spacing": "error", "arrow-spacing": "error",
"block-scoped-var": "off", "block-scoped-var": "off",
"block-spacing": "off", "block-spacing": "off",
......
...@@ -8859,6 +8859,10 @@ body.reset { ...@@ -8859,6 +8859,10 @@ body.reset {
-webkit-animation: colorchange-chatmessage 1s; } -webkit-animation: colorchange-chatmessage 1s; }
#conversejs .message.chat-msg:hover { #conversejs .message.chat-msg:hover {
background-color: rgba(0, 0, 0, 0.035); } background-color: rgba(0, 0, 0, 0.035); }
#conversejs .message.chat-msg.correcting.groupchat {
background-color: #fdf1ee; }
#conversejs .message.chat-msg.correcting:not(.groupchat) {
background-color: #e7f7ee; }
#conversejs .message.chat-msg .spoiler { #conversejs .message.chat-msg .spoiler {
margin-top: 0.5em; } margin-top: 0.5em; }
#conversejs .message.chat-msg .spoiler-hint { #conversejs .message.chat-msg .spoiler-hint {
......
...@@ -68675,7 +68675,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -68675,7 +68675,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
return { return {
'fullname': fullname, 'fullname': fullname,
'replace': this.correction,
'from': _converse.bare_jid, 'from': _converse.bare_jid,
'sender': 'me', 'sender': 'me',
'time': moment().format(), 'time': moment().format(),
...@@ -68691,21 +68690,18 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -68691,21 +68690,18 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
* Parameters: * Parameters:
* (Message) message - The chat message * (Message) message - The chat message
*/ */
if (attrs.replace) { const message = this.messages.findWhere('correcting');
const message = this.messages.findWhere({
'id': attrs.replace if (message) {
const older_versions = message.get('older_versions') || [];
older_versions.push(message.get('message'));
message.save({
'message': attrs.message,
'older_versions': older_versions,
'edited': true,
'correcting': false
}); });
return this.sendMessageStanza(message);
if (message) {
const older_versions = message.get('older_versions') || [];
older_versions.push(message.get('message'));
message.save({
'message': attrs.message,
'older_versions': older_versions,
'edited': true
});
return this.sendMessageStanza(message);
}
} }
return this.sendMessageStanza(this.messages.create(attrs)); return this.sendMessageStanza(this.messages.create(attrs));
...@@ -69344,6 +69340,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -69344,6 +69340,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
const KEY = { const KEY = {
ENTER: 13, ENTER: 13,
UP_ARROW: 38, UP_ARROW: 38,
DOWN_ARROW: 40,
FORWARD_SLASH: 47 FORWARD_SLASH: 47
}; };
converse.plugins.add('converse-chatview', { converse.plugins.add('converse-chatview', {
...@@ -69621,7 +69618,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -69621,7 +69618,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'click .toggle-smiley ul.emoji-picker li': 'insertEmoji', 'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
'click .toggle-smiley': 'toggleEmojiMenu', 'click .toggle-smiley': 'toggleEmojiMenu',
'click .upload-file': 'toggleFileUpload', 'click .upload-file': 'toggleFileUpload',
'keyup .chat-textarea': 'keyPressed', 'keydown .chat-textarea': 'keyPressed',
'input .chat-textarea': 'inputChanged' 'input .chat-textarea': 'inputChanged'
}, },
...@@ -70103,6 +70100,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -70103,6 +70100,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
*/ */
this.showMessage(message); this.showMessage(message);
if (message.get('correcting')) {
this.insertIntoTextArea(message.get('message'), true);
}
_converse.emit('messageAdded', { _converse.emit('messageAdded', {
'message': message, 'message': message,
'chatbox': this.model 'chatbox': this.model
...@@ -70142,7 +70143,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -70142,7 +70143,6 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
} }
const attrs = this.model.getOutgoingMessageAttributes(text, spoiler_hint); const attrs = this.model.getOutgoingMessageAttributes(text, spoiler_hint);
delete this.model.correction;
this.model.sendMessage(attrs); this.model.sendMessage(attrs);
}, },
...@@ -70203,10 +70203,16 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -70203,10 +70203,16 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
keyPressed(ev) { keyPressed(ev) {
/* Event handler for when a key is pressed in a chat box textarea. /* Event handler for when a key is pressed in a chat box textarea.
*/ */
if (ev.keyCode === KEY.ENTER && !ev.shiftKey) { if (ev.shiftKey) {
return;
}
if (ev.keyCode === KEY.ENTER) {
this.onFormSubmitted(ev); this.onFormSubmitted(ev);
} else if (ev.keyCode === KEY.UP_ARROW && !ev.shiftKey) { } else if (ev.keyCode === KEY.UP_ARROW && !ev.target.selectionEnd) {
this.editPreviousMessage(); this.editPreviousMessage();
} else if (ev.keyCode === KEY.DOWN_ARROW && ev.target.selectionEnd === ev.target.value.length) {
this.cancelMessageCorrection();
} 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).
...@@ -70214,16 +70220,19 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -70214,16 +70220,19 @@ 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));
},
editPreviousMessage() { editPreviousMessage() {
const msg = _.findLast(this.model.messages.models, msg => msg.get('message')); const msg = _.findLast(this.model.messages.models, msg => msg.get('message'));
if (msg) { if (msg) {
const textbox_el = this.el.querySelector('.chat-textarea'); this.insertIntoTextArea(msg.get('message'), true); // We don't set "correcting" the Backbone-way, because
textbox_el.value = msg.get('message');
textbox_el.focus(); // We don't set "correcting" the Backbone-way, because
// we don't want it to persist to storage. // we don't want it to persist to storage.
this.model.correction = msg.get('id'); msg.save('correcting', true);
} }
}, },
...@@ -70250,15 +70259,21 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -70250,15 +70259,21 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
return this; return this;
}, },
insertIntoTextArea(value) { insertIntoTextArea(value, replace = false) {
const textbox_el = this.el.querySelector('.chat-textarea'); const textbox_el = this.el.querySelector('.chat-textarea');
let existing = textbox_el.value;
if (existing && existing[existing.length - 1] !== ' ') { if (replace) {
existing = existing + ' '; textbox_el.value = value;
} else {
let existing = textbox_el.value;
if (existing && existing[existing.length - 1] !== ' ') {
existing = existing + ' ';
}
textbox_el.value = existing + value + ' ';
} }
textbox_el.value = existing + value + ' ';
textbox_el.focus(); textbox_el.focus();
}, },
...@@ -74572,10 +74587,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74572,10 +74587,11 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
initialize() { initialize() {
this.model.vcard.on('change', this.render, this); this.model.vcard.on('change', this.render, this);
this.model.on('change:correcting', this.render, this);
this.model.on('change:message', this.render, this);
this.model.on('change:progress', this.renderFileUploadProgresBar, this); this.model.on('change:progress', this.renderFileUploadProgresBar, this);
this.model.on('change:type', this.render, this); this.model.on('change:type', this.render, this);
this.model.on('change:upload', this.render, this); this.model.on('change:upload', this.render, this);
this.model.on('change:message', this.render, this);
this.model.on('destroy', this.remove, this); this.model.on('destroy', this.remove, this);
this.render(); this.render();
}, },
...@@ -74746,6 +74762,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -74746,6 +74762,10 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
} }
} }
if (this.model.get('correcting')) {
extra_classes += ' correcting';
}
return extra_classes; return extra_classes;
} }
...@@ -75997,7 +76017,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ ...@@ -75997,7 +76017,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
'click .toggle-smiley ul.emoji-picker li': 'insertEmoji', 'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
'click .toggle-smiley': 'toggleEmojiMenu', 'click .toggle-smiley': 'toggleEmojiMenu',
'click .upload-file': 'toggleFileUpload', 'click .upload-file': 'toggleFileUpload',
'keypress .chat-textarea': 'keyPressed', 'keydown .chat-textarea': 'keyPressed',
'input .chat-textarea': 'inputChanged' 'input .chat-textarea': 'inputChanged'
}, },
...@@ -85632,13 +85652,13 @@ __p += '\n </span>\n <time timestamp="' + ...@@ -85632,13 +85652,13 @@ __p += '\n </span>\n <time timestamp="' +
__e(o.isodate) + __e(o.isodate) +
'" class="chat-msg-time">' + '" class="chat-msg-time">' +
__e(o.pretty_time) + __e(o.pretty_time) +
'</time>\n </span>\n <span class="chat-msg-text"></span>\n <div class="chat-msg-media"></div>\n '; '</time>\n </span>\n ';
if (o.edited) { ; if (o.edited) { ;
__p += ' <i title="' + __p += ' <i title="' +
__e(o.__('This message has been edited')) + __e(o.__('This message has been edited')) +
'" class="fa fa-edit chat-msg-edited"></i> '; '" class="fa fa-edit chat-msg-edited"></i> ';
} ; } ;
__p += '\n </div>\n</div>\n'; __p += '\n <span class="chat-msg-text"></span>\n <div class="chat-msg-media"></div>\n </div>\n</div>\n';
return __p return __p
}; };
...@@ -73,6 +73,14 @@ ...@@ -73,6 +73,14 @@
&:hover { &:hover {
background-color: rgba(0, 0, 0, 0.035); background-color: rgba(0, 0, 0, 0.035);
} }
&.correcting {
&.groupchat {
background-color: lighten($chatroom-head-color, 35%);
}
&:not(.groupchat) {
background-color: lighten($chat-head-color, 50%);
}
}
.spoiler { .spoiler {
margin-top: 0.5em; margin-top: 0.5em;
......
This diff is collapsed.
...@@ -365,7 +365,6 @@ ...@@ -365,7 +365,6 @@
return { return {
'fullname': fullname, 'fullname': fullname,
'replace': this.correction,
'from': _converse.bare_jid, 'from': _converse.bare_jid,
'sender': 'me', 'sender': 'me',
'time': moment().format(), 'time': moment().format(),
...@@ -381,18 +380,17 @@ ...@@ -381,18 +380,17 @@
* Parameters: * Parameters:
* (Message) message - The chat message * (Message) message - The chat message
*/ */
if (attrs.replace) { const message = this.messages.findWhere('correcting')
const message = this.messages.findWhere({'id': attrs.replace}) if (message) {
if (message) { const older_versions = message.get('older_versions') || [];
const older_versions = message.get('older_versions') || []; older_versions.push(message.get('message'));
older_versions.push(message.get('message')); message.save({
message.save({ 'message': attrs.message,
'message': attrs.message, 'older_versions': older_versions,
'older_versions': older_versions, 'edited': true,
'edited': true 'correcting': false
}); });
return this.sendMessageStanza(message); return this.sendMessageStanza(message);
}
} }
return this.sendMessageStanza(this.messages.create(attrs)); return this.sendMessageStanza(this.messages.create(attrs));
}, },
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
const KEY = { const KEY = {
ENTER: 13, ENTER: 13,
UP_ARROW: 38, UP_ARROW: 38,
DOWN_ARROW: 40,
FORWARD_SLASH: 47 FORWARD_SLASH: 47
}; };
...@@ -334,7 +335,7 @@ ...@@ -334,7 +335,7 @@
'click .toggle-smiley ul.emoji-picker li': 'insertEmoji', 'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
'click .toggle-smiley': 'toggleEmojiMenu', 'click .toggle-smiley': 'toggleEmojiMenu',
'click .upload-file': 'toggleFileUpload', 'click .upload-file': 'toggleFileUpload',
'keyup .chat-textarea': 'keyPressed', 'keydown .chat-textarea': 'keyPressed',
'input .chat-textarea': 'inputChanged' 'input .chat-textarea': 'inputChanged'
}, },
...@@ -802,7 +803,9 @@ ...@@ -802,7 +803,9 @@
* (Object) message - The message Backbone object that was added. * (Object) message - The message Backbone object that was added.
*/ */
this.showMessage(message); this.showMessage(message);
if (message.get('correcting')) {
this.insertIntoTextArea(message.get('message'), true);
}
_converse.emit('messageAdded', { _converse.emit('messageAdded', {
'message': message, 'message': message,
'chatbox': this.model 'chatbox': this.model
...@@ -848,7 +851,6 @@ ...@@ -848,7 +851,6 @@
return; return;
} }
const attrs = this.model.getOutgoingMessageAttributes(text, spoiler_hint); const attrs = this.model.getOutgoingMessageAttributes(text, spoiler_hint);
delete this.model.correction;
this.model.sendMessage(attrs); this.model.sendMessage(attrs);
}, },
...@@ -912,10 +914,14 @@ ...@@ -912,10 +914,14 @@
keyPressed (ev) { keyPressed (ev) {
/* Event handler for when a key is pressed in a chat box textarea. /* Event handler for when a key is pressed in a chat box textarea.
*/ */
if (ev.keyCode === KEY.ENTER && !ev.shiftKey) { if (ev.shiftKey) { return; }
if (ev.keyCode === KEY.ENTER) {
this.onFormSubmitted(ev); this.onFormSubmitted(ev);
} else if (ev.keyCode === KEY.UP_ARROW && !ev.shiftKey) { } else if (ev.keyCode === KEY.UP_ARROW && !ev.target.selectionEnd) {
this.editPreviousMessage(); this.editPreviousMessage();
} else if (ev.keyCode === KEY.DOWN_ARROW && ev.target.selectionEnd === ev.target.value.length) {
this.cancelMessageCorrection();
} 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).
...@@ -923,15 +929,18 @@ ...@@ -923,15 +929,18 @@
} }
}, },
cancelMessageCorrection () {
this.insertIntoTextArea('', true);
this.model.messages.where('correcting').forEach(msg => msg.save('correcting', false));
},
editPreviousMessage () { editPreviousMessage () {
const msg = _.findLast(this.model.messages.models, (msg) => msg.get('message')); const msg = _.findLast(this.model.messages.models, (msg) => msg.get('message'));
if (msg) { if (msg) {
const textbox_el = this.el.querySelector('.chat-textarea'); this.insertIntoTextArea(msg.get('message'), true);
textbox_el.value = msg.get('message');
textbox_el.focus()
// We don't set "correcting" the Backbone-way, because // We don't set "correcting" the Backbone-way, because
// we don't want it to persist to storage. // we don't want it to persist to storage.
this.model.correction = msg.get('id'); msg.save('correcting', true);
} }
}, },
...@@ -951,13 +960,17 @@ ...@@ -951,13 +960,17 @@
return this; return this;
}, },
insertIntoTextArea (value) { insertIntoTextArea (value, replace=false) {
const textbox_el = this.el.querySelector('.chat-textarea'); const textbox_el = this.el.querySelector('.chat-textarea');
let existing = textbox_el.value; if (replace) {
if (existing && (existing[existing.length-1] !== ' ')) { textbox_el.value = value;
existing = existing + ' '; } else {
let existing = textbox_el.value;
if (existing && (existing[existing.length-1] !== ' ')) {
existing = existing + ' ';
}
textbox_el.value = existing+value+' ';
} }
textbox_el.value = existing+value+' ';
textbox_el.focus() textbox_el.focus()
}, },
......
...@@ -91,10 +91,11 @@ ...@@ -91,10 +91,11 @@
initialize () { initialize () {
this.model.vcard.on('change', this.render, this); this.model.vcard.on('change', this.render, this);
this.model.on('change:correcting', this.render, this);
this.model.on('change:message', this.render, this);
this.model.on('change:progress', this.renderFileUploadProgresBar, this); this.model.on('change:progress', this.renderFileUploadProgresBar, this);
this.model.on('change:type', this.render, this); this.model.on('change:type', this.render, this);
this.model.on('change:upload', this.render, this); this.model.on('change:upload', this.render, this);
this.model.on('change:message', this.render, this);
this.model.on('destroy', this.remove, this); this.model.on('destroy', this.remove, this);
this.render(); this.render();
}, },
...@@ -262,6 +263,9 @@ ...@@ -262,6 +263,9 @@
extra_classes += ' mentioned'; extra_classes += ' mentioned';
} }
} }
if (this.model.get('correcting')) {
extra_classes += ' correcting';
}
return extra_classes; return extra_classes;
} }
}); });
......
...@@ -529,7 +529,7 @@ ...@@ -529,7 +529,7 @@
'click .toggle-smiley ul.emoji-picker li': 'insertEmoji', 'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
'click .toggle-smiley': 'toggleEmojiMenu', 'click .toggle-smiley': 'toggleEmojiMenu',
'click .upload-file': 'toggleFileUpload', 'click .upload-file': 'toggleFileUpload',
'keypress .chat-textarea': 'keyPressed', 'keydown .chat-textarea': 'keyPressed',
'input .chat-textarea': 'inputChanged' 'input .chat-textarea': 'inputChanged'
}, },
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
</span> </span>
<time timestamp="{{{o.isodate}}}" class="chat-msg-time">{{{o.pretty_time}}}</time> <time timestamp="{{{o.isodate}}}" class="chat-msg-time">{{{o.pretty_time}}}</time>
</span> </span>
{[ if (o.edited) { ]} <i title="{{{o.__('This message has been edited')}}}" class="fa fa-edit chat-msg-edited"></i> {[ } ]}
<span class="chat-msg-text"></span> <span class="chat-msg-text"></span>
<div class="chat-msg-media"></div> <div class="chat-msg-media"></div>
{[ if (o.edited) { ]} <i title="{{{o.__('This message has been edited')}}}" class="fa fa-edit chat-msg-edited"></i> {[ } ]}
</div> </div>
</div> </div>
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