fix(chat/mentions) fixes in mentions behavior

Changed cursor behavior to jump over text when it
reaches a mention, either on left or right side.
Also made mention to behave as link when hovered
with mouse so that it cannot be clicked and place
cursor inside it.

Also fixed keyboard focus to navigate only in the
suggestions list when this is opened.

Closes #4423
This commit is contained in:
Alexandra Betouni 2022-02-21 21:51:41 +02:00 committed by Iuri Matias
parent 3985272037
commit 5c30daab07
3 changed files with 50 additions and 12 deletions

View File

@ -43,6 +43,7 @@ Rectangle {
property int cursorPosition
signal itemSelected(var item, int lastAtPosition, int lastCursorPosition)
property alias listView: listView
property var inputField
property bool shouldHide: false
Timer {
@ -77,6 +78,9 @@ Rectangle {
// We change it back to 0 so that it can be used to select using the keyboard
listView.currentIndex = 0
}
if (visible) {
listView.forceActiveFocus();
}
}
z: parent.z + 100
@ -122,7 +126,17 @@ Rectangle {
anchors.rightMargin: Style.current.halfPadding
anchors.bottomMargin: Style.current.halfPadding
clip: true
Keys.priority: Keys.AfterItem
Keys.forwardTo: container.inputField
Keys.onPressed: {
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
container.itemSelected(mentionsListDelegate.items.get(listView.currentIndex).model, filterItem.lastAtPosition, filterItem.cursorPosition)
} else if (event.key === Qt.Key_Escape) {
container.hide();
} else if (event.key !== Qt.Key_Up && event.key !== Qt.Key_Down) {
event.accepted = false;
}
}
property int selectedIndex
property var selectedItem: selectedIndex == -1 ? null : model[selectedIndex]
signal suggestionClicked(var item)

View File

@ -118,15 +118,17 @@ Rectangle {
}
}
property var mentionsPos: []
function insertMention(aliasName, lastAtPosition, lastCursorPosition) {
const hasEmoji = Emoji.hasEmoji(messageInputField.text)
const spanPlusAlias = `${Constants.mentionSpanTag}@${aliasName}</span> `
const spanPlusAlias = `${Constants.mentionSpanTag}@${aliasName}</a></span> `
let rightIndex = hasEmoji ? lastCursorPosition + 2 : lastCursorPosition
messageInputField.remove(lastAtPosition, rightIndex)
messageInputField.insert(lastAtPosition, spanPlusAlias)
messageInputField.cursorPosition = lastAtPosition + aliasName.length + 2
messageInputField.cursorPosition = lastAtPosition + aliasName.length + 2;
mentionsPos.push({"leftIndex":lastAtPosition, "rightIndex": (messageInputField.cursorPosition-1)});
if (messageInputField.cursorPosition === 0) {
// It reset to 0 for some reason, go back to the end
@ -161,7 +163,7 @@ Rectangle {
return false
}
function onKeyPress(event){
function onKeyPress(event) {
if (event.modifiers === Qt.NoModifier && (event.key === Qt.Key_Enter || event.key === Qt.Key_Return)) {
if (checkTextInsert()) {
event.accepted = true;
@ -225,16 +227,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()
}
if (event.key === Qt.Key_Escape) {
suggestionsBox.hide()
}
isColonPressed = (event.key === Qt.Key_Colon) && (event.modifiers & Qt.ShiftModifier);
@ -252,6 +249,21 @@ Rectangle {
suggestionsBox.hide();
}
}
if (mentionsPos.length > 0) {
for (var i = 0; i < mentionsPos.length; i++) {
if ((messageInputField.cursorPosition === mentionsPos[i].leftIndex) && (event.key === Qt.Key_Right)) {
messageInputField.cursorPosition = mentionsPos[i].rightIndex;
} else if ((messageInputField.cursorPosition === mentionsPos[i].rightIndex)) {
if ((event.key === Qt.Key_Backspace || event.key === Qt.Key_Delete)) {
messageInputField.remove(mentionsPos[i].rightIndex, mentionsPos[i].leftIndex);
mentionsPos.pop(i);
} else if (event.key === Qt.Key_Left) {
messageInputField.cursorPosition = mentionsPos[i].leftIndex;
}
}
}
}
}
function wrapSelection(wrapWith) {
@ -646,11 +658,18 @@ Rectangle {
filter: messageInputField.text
cursorPosition: messageInputField.cursorPosition
property: ["name", "nickname", "ensName", "alias"]
inputField: messageInputField
onItemSelected: function (item, lastAtPosition, lastCursorPosition) {
messageInputField.forceActiveFocus();
let name = item.name.replace("@", "")
insertMention(name, lastAtPosition, lastCursorPosition)
suggestionsBox.suggestionsModel.clear()
}
onVisibleChanged: {
if (!visible) {
messageInputField.forceActiveFocus();
}
}
}
ChatCommandsPopup {
@ -949,7 +968,12 @@ Rectangle {
StatusSyntaxHighlighter {
quickTextDocument: messageInputField.textDocument
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
enabled: parent.hoveredLink
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
StatusTextFormatMenu {
id: textFormatMenu

View File

@ -178,7 +178,7 @@ QtObject {
readonly property var acceptedImageExtensions: [".png", ".jpg", ".jpeg", ".svg", ".gif"]
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};">`
readonly property string mentionSpanTag: `<span style="color:${Style.current.mentionColor}; background-color: ${Style.current.mentionBgColor};"><a style="text-decoration:none" href='http://'>`
readonly property string ens_taken: "taken"
readonly property string ens_taken_custom: "taken-custom"