feat(mentions): show mentions ordered by how it matches the filter

Fixes #2543
This commit is contained in:
Jonathan Rainville 2021-07-07 16:23:05 -04:00 committed by Iuri Matias
parent e3c09a9631
commit 4277a6e7f4
3 changed files with 62 additions and 38 deletions

View File

@ -31,6 +31,13 @@ Rectangle {
property Item delegate property Item delegate
property alias suggestionsModel: filterItem.model property alias suggestionsModel: filterItem.model
property alias filter: filterItem.filter property alias filter: filterItem.filter
property string plainTextFilter: chatsModel.plainText(filter)
property string formattedPlainTextFilter: {
if (plainTextFilter.startsWith("@")) {
return plainTextFilter.substring(1).toLowerCase()
}
return plainTextFilter.toLowerCase()
}
property alias property: filterItem.property property alias property: filterItem.property
property int cursorPosition property int cursorPosition
signal itemSelected(var item, int lastAtPosition, int lastCursorPosition) signal itemSelected(var item, int lastAtPosition, int lastCursorPosition)
@ -95,7 +102,7 @@ Rectangle {
ListView { ListView {
id: listView id: listView
model: container.suggestionsModel model: mentionsListDelegate
keyNavigationEnabled: true keyNavigationEnabled: true
anchors.fill: parent anchors.fill: parent
anchors.topMargin: Style.current.halfPadding anchors.topMargin: Style.current.halfPadding
@ -108,42 +115,60 @@ Rectangle {
property var selectedItem: selectedIndex == -1 ? null : model[selectedIndex] property var selectedItem: selectedIndex == -1 ? null : model[selectedIndex]
signal suggestionClicked(var item) signal suggestionClicked(var item)
delegate: Rectangle { DelegateModelGeneralized {
id: rectangle id: mentionsListDelegate
color: listView.currentIndex === index ? Style.current.backgroundHover : Style.current.transparent lessThan: [
border.width: 0 function(left, right) {
width: parent.width if (!formattedPlainTextFilter) {
height: 42 return true
radius: Style.current.radius }
StatusImageIdenticon { const leftMatches = left[container.property.find(p => !!left[p])].toLowerCase().startsWith(formattedPlainTextFilter)
id: accountImage
width: 32
height: 32
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
source: model.identicon
}
StyledText { const rightMatches = right[container.property.find(p => !!right[p])].toLowerCase().startsWith(formattedPlainTextFilter)
text: model[container.property.split(",").map(p => p.trim()).find(p => !!model[p])]
color: Style.current.textColor
anchors.verticalCenter: parent.verticalCenter
anchors.left: accountImage.right
anchors.leftMargin: Style.current.smallPadding
font.pixelSize: 15
}
MouseArea { return leftMatches && !rightMatches
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onEntered: {
listView.currentIndex = index
} }
onClicked: { ]
container.itemSelected(model, filterItem.lastAtPosition, filterItem.cursorPosition)
model: container.suggestionsModel
delegate: Rectangle {
color: listView.currentIndex === index ? Style.current.backgroundHover : Style.current.transparent
border.width: 0
width: parent.width
height: 42
radius: Style.current.radius
StatusImageIdenticon {
id: accountImage
width: 32
height: 32
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
source: model.identicon
}
StyledText {
text: model[container.property.find(p => !!model[p])]
color: Style.current.textColor
anchors.verticalCenter: parent.verticalCenter
anchors.left: accountImage.right
anchors.leftMargin: Style.current.smallPadding
font.pixelSize: 15
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onEntered: {
listView.currentIndex = index
}
onClicked: {
container.itemSelected(model, filterItem.lastAtPosition, filterItem.cursorPosition)
}
} }
} }
} }

View File

@ -8,7 +8,7 @@ Item {
property string filter: "" property string filter: ""
property int cursorPosition: 0 property int cursorPosition: 0
property int lastAtPosition: 0 property int lastAtPosition: 0
property string property: "" property var property: ([])
Connections { Connections {
onFilterChanged: invalidateFilter() onFilterChanged: invalidateFilter()
@ -41,8 +41,7 @@ Item {
} }
function isAcceptedItem(item) { function isAcceptedItem(item) {
let properties = this.property.split(",") let properties = this.property
.map(p => p.trim())
.filter(p => !!item[p]) .filter(p => !!item[p])
if (properties.length === 0 || this.filter.length === 0 || this.cursorPosition === 0) { if (properties.length === 0 || this.filter.length === 0 || this.cursorPosition === 0) {
@ -80,7 +79,7 @@ Item {
} }
function isFilteringPropertyOk() { function isFilteringPropertyOk() {
if(this.property === undefined || this.property === "") { if(this.property === undefined || this.property.length === 0) {
return false return false
} }
return true return true

View File

@ -611,7 +611,7 @@ Rectangle {
width: messageInput.width width: messageInput.width
filter: messageInputField.text filter: messageInputField.text
cursorPosition: messageInputField.cursorPosition cursorPosition: messageInputField.cursorPosition
property: "ensName, localNickname, alias" property: ["ensName", "localNickname", "alias"]
onItemSelected: function (item, lastAtPosition, lastCursorPosition) { onItemSelected: function (item, lastAtPosition, lastCursorPosition) {
const hasEmoji = Emoji.hasEmoji(messageInputField.text) const hasEmoji = Emoji.hasEmoji(messageInputField.text)