diff --git a/ui/app/AppLayouts/Chat/ChatColumn.qml b/ui/app/AppLayouts/Chat/ChatColumn.qml index 384be27736..c3fc021e91 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn.qml @@ -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 diff --git a/ui/app/AppLayouts/Chat/ChatColumn/SuggestionBox.qml b/ui/app/AppLayouts/Chat/ChatColumn/SuggestionBox.qml index b94a1efbed..9026af5dca 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/SuggestionBox.qml +++ b/ui/app/AppLayouts/Chat/ChatColumn/SuggestionBox.qml @@ -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) } } } diff --git a/ui/shared/status/StatusChatInput.qml b/ui/shared/status/StatusChatInput.qml index ab5ff0acba..1112f1d628 100644 --- a/ui/shared/status/StatusChatInput.qml +++ b/ui/shared/status/StatusChatInput.qml @@ -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