fix(statusChatInput): update mentions behavior when text is pasted

Fixed to update mentions positions when text is pasted or
added before those

Closes #4867
This commit is contained in:
Alexandra Betouni 2022-02-24 23:41:37 +02:00 committed by Iuri Matias
parent e3b70ef7fa
commit f8aebda0dd
2 changed files with 89 additions and 24 deletions

View File

@ -123,18 +123,17 @@ Rectangle {
function insertMention(aliasName, lastAtPosition, lastCursorPosition) {
const hasEmoji = Emoji.hasEmoji(messageInputField.text)
const spanPlusAlias = `${Constants.mentionSpanTag}@${aliasName}</a></span> `
const spanPlusAlias = `${Constants.mentionSpanTag}@${aliasName}</a></span> `;
let rightIndex = hasEmoji ? lastCursorPosition + 2 : lastCursorPosition
messageInputField.remove(lastAtPosition, rightIndex)
messageInputField.insert(lastAtPosition, spanPlusAlias)
messageInputField.cursorPosition = lastAtPosition + aliasName.length + 2;
mentionsPos.push({"leftIndex":lastAtPosition, "rightIndex": (messageInputField.cursorPosition-1)});
if (messageInputField.cursorPosition === 0) {
// It reset to 0 for some reason, go back to the end
messageInputField.cursorPosition = messageInputField.length
}
mentionsPos.push({"name": aliasName,"leftIndex": lastAtPosition, "rightIndex": (lastAtPosition+aliasName.length+1)});
}
property var interpretMessage: function (msg) {
@ -217,8 +216,21 @@ Rectangle {
}
}
if ((event.key === Qt.Key_C) && (event.modifiers & Qt.ControlModifier)) {
if (messageInputField.selectedText !== "") {
copiedTextPlain = messageInputField.getText(messageInputField.selectionStart, messageInputField.selectionEnd);
copiedTextFormatted = messageInputField.getFormattedText(messageInputField.selectionStart, messageInputField.selectionEnd);
}
}
if ((event.key === Qt.Key_V) && (event.modifiers & Qt.ControlModifier)) {
paste = true;
if (copiedTextPlain === QClipboardProxy.text) {
copyTextStart = messageInputField.cursorPosition;
paste = true;
} else {
copiedTextPlain = "";
copiedTextFormatted = "";
}
}
// U
@ -250,21 +262,6 @@ Rectangle {
suggestionsBox.hide();
}
}
if (mentionsPos.length > 0) {
for (var i = 0; i < mentionsPos.length; i++) {
if ((messageInputField.cursorPosition === mentionsPos[i].leftIndex) && (event.key === Qt.Key_Right)) {
messageInputField.cursorPosition = mentionsPos[i].rightIndex;
} else if ((messageInputField.cursorPosition === mentionsPos[i].rightIndex)) {
if ((event.key === Qt.Key_Backspace || event.key === Qt.Key_Delete)) {
messageInputField.remove(mentionsPos[i].rightIndex, mentionsPos[i].leftIndex);
mentionsPos.pop(i);
} else if (event.key === Qt.Key_Left) {
messageInputField.cursorPosition = mentionsPos[i].leftIndex;
}
}
}
}
}
function wrapSelection(wrapWith) {
@ -384,17 +381,42 @@ Rectangle {
}
}
//mentions helper properties
property int copyTextStart: 0
property string copiedTextPlain: ""
property string copiedTextFormatted: ""
ListView {
id: dummyContactList
model: control.usersStore.usersModel
delegate: Item {
property string contactName: model.name
}
}
function onRelease(event) {
if (event.key === Qt.Key_Backspace && textFormatMenu.opened) {
textFormatMenu.close()
}
// the text doesn't get registered to the textarea fast enough
// we can only get it in the `released` event
if (paste) {
if (copiedTextPlain.includes("@")) {
copiedTextFormatted = copiedTextFormatted.replace(/underline/g, "none").replace(/span style="/g, "span style=\" text-decoration:none;");
for (var j = 0; j < dummyContactList.count; j++) {
var name = dummyContactList.itemAtIndex(j).contactName;
if (copiedTextPlain.indexOf(name) > -1) {
var subStr = name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
var regex = new RegExp(subStr, 'gi'), result, indices = [];
while ((result = regex.exec(copiedTextPlain))) {
mentionsPos.push({"name": name, "leftIndex": (result.index + copyTextStart - 1), "rightIndex": (result.index + copyTextStart + name.length)});
}
}
}
}
messageInputField.remove(copyTextStart, (copyTextStart + copiedTextPlain.length));
insertInTextInput(copyTextStart, copiedTextFormatted);
paste = false;
const plainText = messageInputField.getFormattedText(0, messageInputField.length);
messageInputField.remove(0, messageInputField.length);
insertInTextInput(0, plainText);
}
if (event.key !== Qt.Key_Escape) {
@ -932,12 +954,52 @@ Rectangle {
color: isEdit ? Theme.palette.directColor1 : Style.current.textColor
topPadding: control.isStatusUpdateInput ? 18 : Style.current.smallPadding
bottomPadding: control.isStatusUpdateInput ? 14 : 12
Keys.onPressed: onKeyPress(event)
Keys.onPressed: {
keyEvent = event;
onKeyPress(event)
}
Keys.onReleased: onRelease(event) // gives much more up to date cursorPosition
Keys.onShortcutOverride: event.accepted = isUploadFilePressed(event)
leftPadding: 0
selectionColor: Style.current.primarySelectionColor
persistentSelection: true
property var keyEvent
onCursorPositionChanged: {
if (mentionsPos.length > 0) {
for (var i = 0; i < mentionsPos.length; i++) {
if ((messageInputField.cursorPosition === (mentionsPos[i].leftIndex + 1)) && (keyEvent.key === Qt.Key_Right)) {
messageInputField.cursorPosition = mentionsPos[i].rightIndex;
} else if (messageInputField.cursorPosition === (mentionsPos[i].rightIndex - 1)) {
if (keyEvent.key === Qt.Key_Left) {
messageInputField.cursorPosition = mentionsPos[i].leftIndex;
} else if ((keyEvent.key === Qt.Key_Backspace) || (keyEvent.key === Qt.Key_Delete)) {
messageInputField.remove(mentionsPos[i].rightIndex, mentionsPos[i].leftIndex);
mentionsPos.pop(i);
}
}
if ((keyEvent.key === Qt.Key_Up) || (keyEvent.key === Qt.Key_Down)) {
if (messageInputField.cursorPosition >= mentionsPos[i].leftIndex &&
messageInputField.cursorPosition <= (((mentionsPos[i].leftIndex + mentionsPos[i].rightIndex)/2))) {
messageInputField.cursorPosition = mentionsPos[i].leftIndex;
} else if (messageInputField.cursorPosition <= mentionsPos[i].rightIndex &&
messageInputField.cursorPosition > (((mentionsPos[i].leftIndex + mentionsPos[i].rightIndex)/2))) {
messageInputField.cursorPosition = mentionsPos[i].rightIndex;
}
}
}
}
if ((mentionsPos.length > 0) && (cursorPosition < length) && getText(cursorPosition, length).includes("@")
&& (keyEvent.key !== Qt.Key_Right) && (keyEvent.key !== Qt.Key_Left) && (keyEvent.key !== Qt.Key_Up)
&& (keyEvent.key !== Qt.Key_Down)) {
var unformattedText = getText(cursorPosition, length);
for (var k = 0; k < mentionsPos.length; k++) {
if ((unformattedText.indexOf(mentionsPos[k].name) !== -1) && (unformattedText.indexOf(mentionsPos[k].name) !== mentionsPos[k].leftIndex)) {
mentionsPos[k].leftIndex = (cursorPosition + unformattedText.indexOf(mentionsPos[k].name) - 1);
mentionsPos[k].rightIndex = (cursorPosition + unformattedText.indexOf(mentionsPos[k].name) + mentionsPos[k].name.length);
}
}
}
}
onTextChanged: {
var symbols = ":='xX><0O;*dB8-D#%\\";
if ((length > 1) && (symbols.indexOf(getText((cursorPosition - 2), (cursorPosition - 1))) !== -1)
@ -950,6 +1012,9 @@ Rectangle {
}
})
}
if (text === "") {
mentionsPos = [];
}
}
onReleased: function (event) {

2
vendor/DOtherSide vendored

@ -1 +1 @@
Subproject commit ea578a6ae64db716e194f61158520e9e469ba281
Subproject commit 676b1d9bc8a3b0d6e87d10f0ac7b5deff626266f