feat: highlite mentions in the chat input as well
This commit is contained in:
parent
d2b9d54c4b
commit
7fb9578285
|
@ -74,6 +74,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
let filterWithoutAt = filter.substring(lastAtPosition + 1, this.cursorPosition)
|
let filterWithoutAt = filter.substring(lastAtPosition + 1, this.cursorPosition)
|
||||||
|
filterWithoutAt = filterWithoutAt.replace(/\*/g, "")
|
||||||
|
|
||||||
return !properties.every(p => item[p].toLowerCase().match(filterWithoutAt.toLowerCase()) === null)
|
return !properties.every(p => item[p].toLowerCase().match(filterWithoutAt.toLowerCase()) === null)
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,4 +125,7 @@ QtObject {
|
||||||
|
|
||||||
readonly property var acceptedImageExtensions: [".png", ".jpg", ".jpeg", ".svg", ".gif"]
|
readonly property var acceptedImageExtensions: [".png", ".jpg", ".jpeg", ".svg", ".gif"]
|
||||||
readonly property var acceptedDragNDropImageExtensions: [".png", ".jpg", ".jpeg", ".heif", "tif", ".tiff"]
|
readonly property var acceptedDragNDropImageExtensions: [".png", ".jpg", ".jpeg", ".heif", "tif", ".tiff"]
|
||||||
|
|
||||||
|
|
||||||
|
readonly property string mentionSpanTag: `<span style="color:${Style.current.mentionColor}; background-color: ${Style.current.mentionBgColor};">`
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ QtObject {
|
||||||
function fromCodePoint(value) {
|
function fromCodePoint(value) {
|
||||||
return Twemoji.twemoji.convert.fromCodePoint(value)
|
return Twemoji.twemoji.convert.fromCodePoint(value)
|
||||||
}
|
}
|
||||||
function deparse(value){
|
function deparse(value) {
|
||||||
return value.replace(/<img src=\"qrc:\/imports\/twemoji\/.+?" alt=\"(.+?)\" width=\"[0-9]*\" height=\"[0-9]*\" \/>/g, "$1");
|
return value.replace(/<img src=\"qrc:\/imports\/twemoji\/.+?" alt=\"(.+?)\" width=\"[0-9]*\" height=\"[0-9]*\" \/>/g, "$1");
|
||||||
}
|
}
|
||||||
function deparseFromParse(value) {
|
function deparseFromParse(value) {
|
||||||
|
|
|
@ -200,11 +200,29 @@ Rectangle {
|
||||||
formatInputMessage()
|
formatInputMessage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPlainText() {
|
||||||
|
const textWithoutMention = messageInputField.text.replace(/<span style="[ :#0-9a-z;\-\.,\(\)]+">(@([a-z\.]+(\ ?[a-z]+\ ?[a-z]+)?))<\/span>/ig, "\[\[mention\]\]$1\[\[mention\]\]")
|
||||||
|
|
||||||
|
const deparsedEmoji = Emoji.deparse(textWithoutMention);
|
||||||
|
|
||||||
|
return chatsModel.plainText(deparsedEmoji);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeMentions(currentText) {
|
||||||
|
return currentText.replace(/\[\[mention\]\]/g, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseBackText(plainText) {
|
||||||
|
plainText = plainText.replace(/\[\[mention\]\](@([a-z\.]+(\ ?[a-z]+\ ?[a-z]+)?))\[\[mention\]\]/gi, `${Constants.mentionSpanTag}$1</span>`)
|
||||||
|
|
||||||
|
|
||||||
|
return parseMarkdown(Emoji.parse(plainText.replace(/\n/g, "<br />")))
|
||||||
|
}
|
||||||
|
|
||||||
function formatInputMessage() {
|
function formatInputMessage() {
|
||||||
const posBeforeEnd = messageInputField.length - messageInputField.cursorPosition;
|
const posBeforeEnd = messageInputField.length - messageInputField.cursorPosition;
|
||||||
const deparsedEmoji = Emoji.deparse(messageInputField.text);
|
const plainText = getPlainText()
|
||||||
const plainText = chatsModel.plainText(deparsedEmoji);
|
const formatted = parseBackText(plainText)
|
||||||
const formatted = parseMarkdown(Emoji.parse(plainText.replace(/\n/g, "<br />")))
|
|
||||||
messageInputField.text = formatted
|
messageInputField.text = formatted
|
||||||
messageInputField.cursorPosition = messageInputField.length - posBeforeEnd;
|
messageInputField.cursorPosition = messageInputField.length - posBeforeEnd;
|
||||||
}
|
}
|
||||||
|
@ -271,34 +289,51 @@ Rectangle {
|
||||||
// to the actual position in the string.
|
// to the actual position in the string.
|
||||||
function extrapolateCursorPosition() {
|
function extrapolateCursorPosition() {
|
||||||
// we need only the message part to be html
|
// we need only the message part to be html
|
||||||
const text = chatsModel.plainText(Emoji.deparse(messageInputField.text));
|
const text = getPlainText()
|
||||||
|
const completelyPlainText = removeMentions(text)
|
||||||
const plainText = Emoji.parse(text);
|
const plainText = Emoji.parse(text);
|
||||||
|
|
||||||
|
|
||||||
var bracketEvent = false;
|
var bracketEvent = false;
|
||||||
|
var almostMention = false;
|
||||||
|
var mentionEvent = false;
|
||||||
var length = 0;
|
var length = 0;
|
||||||
|
|
||||||
for (var i = 0; i < plainText.length;) {
|
|
||||||
if (length >= messageInputField.cursorPosition) break;
|
|
||||||
|
|
||||||
if (!bracketEvent && plainText.charAt(i) !== '<') {
|
|
||||||
i++;
|
// This loop calculates the cursor position inside the plain text which contains the image tags (<img>) and the mention tags ([[mention]])
|
||||||
|
const cursorPos = messageInputField.cursorPosition
|
||||||
|
for (var i = 0; i < plainText.length;) {
|
||||||
|
if (length >= cursorPos) break;
|
||||||
|
|
||||||
|
if (!bracketEvent && plainText.charAt(i) !== '<' && !mentionEvent && plainText.charAt(i) !== '[') {
|
||||||
length++;
|
length++;
|
||||||
} else if (!bracketEvent && plainText.charAt(i) === '<') {
|
} else if (!bracketEvent && plainText.charAt(i) === '<') {
|
||||||
bracketEvent = true;
|
bracketEvent = true;
|
||||||
i++;
|
|
||||||
} else if (bracketEvent && plainText.charAt(i) !== '>') {
|
|
||||||
i++;
|
|
||||||
} else if (bracketEvent && plainText.charAt(i) === '>') {
|
} else if (bracketEvent && plainText.charAt(i) === '>') {
|
||||||
bracketEvent = false;
|
bracketEvent = false;
|
||||||
i++;
|
|
||||||
length++;
|
length++;
|
||||||
|
} else if (!mentionEvent && almostMention && plainText.charAt(i) === '[') {
|
||||||
|
almostMention = false
|
||||||
|
mentionEvent = true
|
||||||
|
} else if (!mentionEvent && !almostMention && plainText.charAt(i) === '[') {
|
||||||
|
almostMention = true
|
||||||
|
} else if (!mentionEvent && almostMention && plainText.charAt(i) !== '[') {
|
||||||
|
almostMention = false
|
||||||
|
} else if (mentionEvent && !almostMention && plainText.charAt(i) === ']') {
|
||||||
|
almostMention = true
|
||||||
|
} else if (mentionEvent && almostMention && plainText.charAt(i) === ']') {
|
||||||
|
almostMention = false
|
||||||
|
mentionEvent = false
|
||||||
}
|
}
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
let textBeforeCursor = Emoji.deparseFromParse(plainText.substr(0, i));
|
let textBeforeCursor = Emoji.deparseFromParse(plainText.substr(0, i));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
cursor: countEmojiLengths(plainText.substr(0, i)) + messageInputField.cursorPosition,
|
cursor: countEmojiLengths(plainText.substr(0, i)) + messageInputField.cursorPosition + text.length - completelyPlainText.length,
|
||||||
data: Emoji.deparseFromParse(textBeforeCursor),
|
data: textBeforeCursor,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +396,7 @@ Rectangle {
|
||||||
.replace(shortname, encodedCodePoint)
|
.replace(shortname, encodedCodePoint)
|
||||||
.replace(/ /g, " ");
|
.replace(/ /g, " ");
|
||||||
messageInputField.remove(0, messageInputField.cursorPosition);
|
messageInputField.remove(0, messageInputField.cursorPosition);
|
||||||
insertInTextInput(0, Emoji.parse(newMessage));
|
insertInTextInput(0, parseBackText(newMessage));
|
||||||
emojiSuggestions.close()
|
emojiSuggestions.close()
|
||||||
emojiEvent = false
|
emojiEvent = false
|
||||||
}
|
}
|
||||||
|
@ -496,29 +531,38 @@ Rectangle {
|
||||||
cursorPosition: messageInputField.cursorPosition
|
cursorPosition: messageInputField.cursorPosition
|
||||||
property: "ensName, localNickname, alias"
|
property: "ensName, localNickname, alias"
|
||||||
onItemSelected: function (item, lastAtPosition, lastCursorPosition) {
|
onItemSelected: function (item, lastAtPosition, lastCursorPosition) {
|
||||||
let hasEmoji = Emoji.hasEmoji(messageInputField.text)
|
const hasEmoji = Emoji.hasEmoji(messageInputField.text)
|
||||||
let currentText = hasEmoji ?
|
const currentText = getPlainText()
|
||||||
chatsModel.plainText(Emoji.deparse(messageInputField.text)) :
|
|
||||||
chatsModel.plainText(messageInputField.text);
|
|
||||||
|
|
||||||
var properties = "ensName, alias"; // Ignore localNickname
|
const completelyPlainText = removeMentions(currentText)
|
||||||
|
|
||||||
|
lastAtPosition += currentText.length - completelyPlainText.length
|
||||||
|
lastCursorPosition += currentText.length - completelyPlainText.length
|
||||||
|
|
||||||
|
const properties = "ensName, alias"; // Ignore localNickname
|
||||||
|
|
||||||
let aliasName = item[properties.split(",").map(p => p.trim()).find(p => !!item[p])]
|
let aliasName = item[properties.split(",").map(p => p.trim()).find(p => !!item[p])]
|
||||||
aliasName = aliasName.replace(/(\.stateofus)?\.eth/, "")
|
aliasName = aliasName.replace(/(\.stateofus)?\.eth/, "")
|
||||||
let nameLen = aliasName.length + 2 // We're doing a +2 here because of the `@` and the trailing whitespace
|
let nameLen = aliasName.length + 2 // We're doing a +2 here because of the `@` and the trailing whitespace
|
||||||
let position = 0;
|
let position = 0;
|
||||||
let text = ""
|
let text = ""
|
||||||
|
const spanPlusAlias = `${Constants.mentionSpanTag}@${aliasName}</span> `
|
||||||
if (currentText === "@") {
|
if (currentText === "@") {
|
||||||
position = nameLen
|
position = nameLen
|
||||||
text = "@" + aliasName + " "
|
text = spanPlusAlias
|
||||||
} else {
|
} else {
|
||||||
let left = currentText.substring(0, lastAtPosition)
|
let left = currentText.substring(0, lastAtPosition)
|
||||||
let right = currentText.substring(hasEmoji ? lastCursorPosition + 2 : lastCursorPosition)
|
let right = currentText.substring(hasEmoji ? lastCursorPosition + 2 : lastCursorPosition)
|
||||||
text = `${left} @${aliasName} ${right}`
|
text = `${left} ${spanPlusAlias}${right}`
|
||||||
}
|
}
|
||||||
|
|
||||||
messageInputField.text = hasEmoji ? Emoji.parse(text) : text
|
messageInputField.text = parseBackText(text)
|
||||||
messageInputField.cursorPosition = lastAtPosition + aliasName.length + 2
|
messageInputField.cursorPosition = lastAtPosition + aliasName.length + 2
|
||||||
|
if (messageInputField.cursorPosition === 0) {
|
||||||
|
// It reset to 0 for some reason, go back to the end
|
||||||
|
messageInputField.cursorPosition = messageInputField.length
|
||||||
|
}
|
||||||
|
|
||||||
suggestionsBox.suggestionsModel.clear()
|
suggestionsBox.suggestionsModel.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue