feat: style mention suggestions and make it work with keyboard

This commit is contained in:
Jonathan Rainville 2020-10-20 13:38:48 -04:00 committed by Iuri Matias
parent 676549cccd
commit 4371501efc
3 changed files with 92 additions and 93 deletions

View File

@ -183,42 +183,6 @@ StackLayout {
height: chatInput.height
Layout.preferredHeight: height
color: "transparent"
SuggestionBox {
id: suggestionsBox
model: suggestions
width: chatContainer.width
anchors.bottom: inputArea.top
anchors.left: inputArea.left
filter: chatInput.textInput.text
cursorPosition: chatInput.textInput.cursorPosition
property: "ensName, alias"
onItemSelected: function (item, lastAtPosition, lastCursorPosition) {
let hasEmoji = Emoji.hasEmoji(chatInput.textInput.text)
let currentText = hasEmoji ?
chatsModel.plainText(Emoji.deparse(chatInput.textInput.text)) :
chatsModel.plainText(chatInput.textInput.text);
let aliasName = item[suggestionsBox.property.split(",").map(p => p.trim()).find(p => !!item[p])]
aliasName = aliasName.replace(".stateofus.eth", "")
let nameLen = aliasName.length + 2 // We're doing a +2 here because of the `@` and the trailing whitespace
let position = 0;
let text = ""
if (currentText === "@") {
position = nameLen
text = "@" + aliasName + " "
} else {
let left = currentText.substring(0, lastAtPosition)
let right = currentText.substring(hasEmoji ? lastCursorPosition + 2 : lastCursorPosition)
text = `${left} @${aliasName} ${right}`
}
chatInput.textInput.text = hasEmoji ? Emoji.parse(text, "26x26") : text
chatInput.textInput.cursorPosition = lastAtPosition + aliasName.length + 2
suggestionsBox.suggestionsModel.clear()
}
}
Loader {
active: chatsModel.loadingMessages

View File

@ -34,19 +34,24 @@ Rectangle {
property alias property: filterItem.property
property int cursorPosition
signal itemSelected(var item, int lastAtPosition, int lastCursorPosition)
property alias listView: listView
function selectCurrentItem() {
container.itemSelected(listView.model.get(listView.currentIndex), filterItem.lastAtPosition, filterItem.cursorPosition)
}
z: parent.z + 100
visible: filter.length > 0 && suggestionsModel.count > 0
height: visible ? popup.height + (Style.current.padding * 2) : 0
height: Math.min(400, listView.contentHeight + Style.current.smallPadding)
opacity: visible ? 1.0 : 0
Behavior on opacity {
NumberAnimation { }
}
// --- defaults
color: Style.current.white2
radius: 16
color:Style.current.background
radius: Style.current.radius
border.width: 0
layer.enabled: true
layer.effect: DropShadow{
width: container.width
@ -69,69 +74,55 @@ Rectangle {
}
ScrollView {
id: popup
height: items.height >= 400 ? 400 : items.height
width: parent.width
anchors.centerIn: parent
ListView {
id: listView
model: container.suggestionsModel
keyNavigationEnabled: true
anchors.fill: parent
anchors.topMargin: Style.current.halfPadding
anchors.leftMargin: Style.current.halfPadding
anchors.rightMargin: Style.current.halfPadding
anchors.bottomMargin: Style.current.halfPadding
clip: true
property int selectedIndex
property var selectedItem: selectedIndex == -1 ? null : model[selectedIndex]
signal suggestionClicked(var item)
ScrollBar.vertical.policy: items.contentHeight > items.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Column {
id: items
clip: true
height: childrenRect.height
delegate: Rectangle {
id: rectangle
color: listView.currentIndex === index ? Style.current.backgroundHover : Style.current.transparent
border.width: 0
width: parent.width
Repeater {
id: repeater
model: container.suggestionsModel
delegate: Rectangle {
id: delegateItem
property var suggestion: model
property bool hovered
height: 42
radius: Style.current.radius
height: 50
width: container.width
color: hovered ? Style.current.blue : "white"
StatusImageIdenticon {
id: accountImage
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
source: model.identicon
}
StatusImageIdenticon {
id: accountImage
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
source: suggestion.identicon
}
StyledText {
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
}
Text {
id: textComponent
color: delegateItem.hovered ? Style.current.white : Style.current.black
text: suggestion[container.property.split(",").map(p => p.trim()).find(p => !!suggestion[p])]
width: parent.width
height: parent.height
anchors.left: accountImage.right
anchors.leftMargin: Style.current.padding
verticalAlignment: Text.AlignVCenter
font.pixelSize: 15
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onEntered: {
delegateItem.hovered = true
}
onExited: {
delegateItem.hovered = false
}
onClicked: {
container.itemSelected(delegateItem.suggestion, filterItem.lastAtPosition, filterItem.cursorPosition)
}
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onEntered: {
listView.currentIndex = index
}
onClicked: {
container.itemSelected(model, filterItem.lastAtPosition, filterItem.cursorPosition)
}
}
}

View File

@ -7,6 +7,7 @@ import QtQuick.Dialogs 1.3
import "../../imports"
import "../../shared"
import "../../app/AppLayouts/Chat/ChatColumn/samples"
import "../../app/AppLayouts/Chat/ChatColumn"
import "./emojiList.js" as EmojiJSON
@ -85,6 +86,11 @@ Rectangle {
event.accepted = true;
return
}
if (suggestionsBox.visible) {
suggestionsBox.selectCurrentItem();
event.accepted = true;
return
}
if (messageInputField.length < messageLimit) {
sendMsg(event);
return;
@ -98,9 +104,11 @@ Rectangle {
}
if (event.key === Qt.Key_Down) {
suggestionsBox.listView.incrementCurrentIndex()
return emojiSuggestions.listView.incrementCurrentIndex()
}
if (event.key === Qt.Key_Up) {
suggestionsBox.listView.decrementCurrentIndex()
return emojiSuggestions.listView.decrementCurrentIndex()
}
@ -342,6 +350,42 @@ Rectangle {
id: emojiSuggestions
}
SuggestionBox {
id: suggestionsBox
model: suggestions
x : messageInput.x
y: -height - Style.current.smallPadding
width: messageInput.width
filter: messageInputField.text
cursorPosition: messageInputField.cursorPosition
property: "ensName, alias"
onItemSelected: function (item, lastAtPosition, lastCursorPosition) {
let hasEmoji = Emoji.hasEmoji(messageInputField.text)
let currentText = hasEmoji ?
chatsModel.plainText(Emoji.deparse(messageInputField.text)) :
chatsModel.plainText(messageInputField.text);
let aliasName = item[suggestionsBox.property.split(",").map(p => p.trim()).find(p => !!item[p])]
aliasName = aliasName.replace(".stateofus.eth", "")
let nameLen = aliasName.length + 2 // We're doing a +2 here because of the `@` and the trailing whitespace
let position = 0;
let text = ""
if (currentText === "@") {
position = nameLen
text = "@" + aliasName + " "
} else {
let left = currentText.substring(0, lastAtPosition)
let right = currentText.substring(hasEmoji ? lastCursorPosition + 2 : lastCursorPosition)
text = `${left} @${aliasName} ${right}`
}
messageInputField.text = hasEmoji ? Emoji.parse(text, "26x26") : text
messageInputField.cursorPosition = lastAtPosition + aliasName.length + 2
suggestionsBox.suggestionsModel.clear()
}
}
StatusChatCommandsPopup {
id: chatCommandsPopup
x: 8