feat(chat): support mention auto complete anywhere inside the message

This commit is contained in:
Pascal Precht 2020-07-20 18:48:23 +02:00 committed by Iuri Matias
parent 7ca512661b
commit f2d345fe6e
3 changed files with 34 additions and 22 deletions

View File

@ -178,7 +178,6 @@ StackLayout {
}
}
Rectangle {
id: inputArea
color: Style.current.background
@ -197,8 +196,9 @@ StackLayout {
anchors.bottom: inputArea.top
anchors.left: inputArea.left
filter: chatInput.textInput.text
cursorPosition: chatInput.textInput.cursorPosition
property: "ensName, alias"
onItemSelected: function (item) {
onItemSelected: function (item, lastAtPosition, lastCursorPosition) {
let currentText = chatInput.textInput.text
let lastAt = currentText.lastIndexOf("@")
let aliasName = item[suggestionsBox.property.split(",").map(p => p.trim()).find(p => !!item[p])]
@ -206,13 +206,14 @@ StackLayout {
let position = 0;
let text = ""
if (currentText.length === 1) {
if (currentText === "@") {
position = nameLen
text = "@" + aliasName + " "
} else {
let left = currentText.slice(0, lastAt)
let left = currentText.substring(0, lastAtPosition)
let right = currentText.substring(lastCursorPosition)
text = `${left}@${aliasName} ${right}`
position = left.length + nameLen
text = left + "@" + aliasName + " "
}
chatInput.textInput.text = text

View File

@ -31,7 +31,8 @@ Rectangle {
property alias suggestionsModel: filterItem.model
property alias filter: filterItem.filter
property alias property: filterItem.property
signal itemSelected(var item)
property int cursorPosition
signal itemSelected(var item, int lastAtPosition, int lastCursorPosition)
z: parent.z + 100
@ -63,6 +64,7 @@ Rectangle {
SuggestionFilter {
id: filterItem
sourceModel: container.model
cursorPosition: container.cursorPosition
}
@ -125,7 +127,9 @@ Rectangle {
onExited: {
delegateItem.hovered = false
}
onClicked: container.itemSelected(delegateItem.suggestion)
onClicked: {
container.itemSelected(delegateItem.suggestion, filterItem.lastAtPosition, filterItem.cursorPosition)
}
}
}
}

View File

@ -6,6 +6,8 @@ Item {
property QtObject sourceModel: undefined
property string filter: ""
property int cursorPosition: 0
property int lastAtPosition: 0
property string property: ""
Connections {
@ -38,33 +40,41 @@ Item {
}
}
function isAcceptedItem(item) {
let properties = this.property.split(",")
.map(p => p.trim())
.filter(p => !!item[p])
if (properties.length == 0) {
if (properties.length === 0 || this.filter.length === 0 || this.cursorPosition === 0) {
return false
}
if (this.filter.endsWith("@")) {
return true
// Prevents suggestions to show up at all
if (this.filter.indexOf("@") === -1) {
return false
}
let lastAt = this.filter.lastIndexOf("@")
let cursorAtEnd = this.cursorPosition === this.filter.length;
let hasAtBeforeCursor = this.filter.charAt(this.cursorPosition - 1) === "@"
let hasWhiteSpaceBeforeAt = this.filter.charAt(this.cursorPosition - 2) === " "
let hasWhiteSpaceAfterAt = this.filter.charAt(this.cursorPosition) === " "
let hasWhiteSpaceBeforeCursor = this.filter.charAt(this.cursorPosition - 1) === " "
if (lastAt == -1) {
return false
if (this.filter.charAt(this.cursorPosition - 2) === "@" && hasWhiteSpaceBeforeCursor) {
return false
}
let filterWithoutAt = this.filter.substring(lastAt+1)
if (filterWithoutAt == "") {
return true
if (this.filter === "@" ||
(hasAtBeforeCursor && hasWhiteSpaceBeforeAt && hasWhiteSpaceAfterAt) ||
(this.cursorPosition === 1 && hasAtBeforeCursor && hasWhiteSpaceAfterAt) ||
(cursorAtEnd && this.filter.endsWith("@") && hasWhiteSpaceBeforeAt)) {
this.lastAtPosition = this.cursorPosition - 1;
return true
}
return !properties.every(p => item[p].toLowerCase().match(filterWithoutAt.toLowerCase()) == null)
let filterWithoutAt = this.filter.substring(lastAtPosition + 1, this.cursorPosition)
return !properties.every(p => item[p].toLowerCase().match(filterWithoutAt.toLowerCase()) === null)
}
function isFilteringPropertyOk() {
@ -74,6 +84,3 @@ Item {
return true
}
}