diff --git a/imports/NeoChat/Component/ChatTextInput.qml b/imports/NeoChat/Component/ChatTextInput.qml index 27a100b10..29249dc3c 100644 --- a/imports/NeoChat/Component/ChatTextInput.qml +++ b/imports/NeoChat/Component/ChatTextInput.qml @@ -138,6 +138,7 @@ ToolBar { keyNavigationWraps: true delegate: Control { + readonly property string userId: modelData.id ?? "" readonly property string displayText: modelData.displayName ?? modelData.unicode readonly property bool isEmoji: modelData.unicode != null readonly property bool highlighted: autoCompleteListView.currentIndex == index @@ -468,9 +469,14 @@ ToolBar { autoCompleteEndPosition = cursorPosition } + // store each user we autoComplete here, this will be helpful later to generate + // the matrix.to links. + // This use an hack to define: https://doc.qt.io/qt-5/qml-var.html#property-value-initialization-semantics + property var userAutocompleted: ({}) + function postMessage() { roomManager.actionsHandler.postMessage(inputField.text.trim(), attachmentPath, - replyEventID, editEventId); + replyEventID, editEventId, inputField.userAutocompleted); clearAttachment(); currentRoom.markAllMessagesAsRead(); clear(); @@ -481,6 +487,10 @@ ToolBar { function autoComplete() { documentHandler.replaceAutoComplete(autoCompleteListView.currentItem.displayText) + // Unfortunally it doesn't + if (!autoCompleteListView.currentItem.isEmoji) { + inputField.userAutocompleted[autoCompleteListView.currentItem.displayText] = autoCompleteListView.currentItem.userId; + } } } } @@ -573,6 +583,7 @@ ToolBar { function clear() { inputField.clear() + inputField.userAutocompleted = {}; } function clearEditReply() { diff --git a/src/actionshandler.cpp b/src/actionshandler.cpp index a7fe9410e..6bf18ec24 100644 --- a/src/actionshandler.cpp +++ b/src/actionshandler.cpp @@ -159,12 +159,17 @@ void ActionsHandler::createRoom(const QString &name, const QString &topic) } void ActionsHandler::postMessage(const QString &text, - const QString &attachementPath, const QString &replyEventId, const QString &editEventId) + const QString &attachementPath, const QString &replyEventId, const QString &editEventId, + const QVariantMap usernames) { QString rawText = text; QString cleanedText = text; - cleanedText = cleanedText.replace(QRegularExpression("@([^: ]*):([^ ]*\\.[^ ]*)"), - "[@$1:$2](https://matrix.to/#/@$1:$2)"); + + for (const auto username : usernames.keys()) { + const auto replacement = usernames.value(username); + cleanedText = cleanedText.replace(username, + "[" + username + "](https://matrix.to/#/" + replacement.toString() + ")"); + } if (attachementPath.length() > 0) { m_room->uploadFile(attachementPath, cleanedText); diff --git a/src/actionshandler.h b/src/actionshandler.h index caf80f695..9df180920 100644 --- a/src/actionshandler.h +++ b/src/actionshandler.h @@ -70,7 +70,8 @@ public Q_SLOTS: /// /// This also interprets commands if any. void postMessage(const QString &text, const QString &attachementPath, - const QString &replyEventId, const QString &editEventId); + const QString &replyEventId, const QString &editEventId, + const QVariantMap usernames); private: Connection *m_connection = nullptr; diff --git a/src/neochatroom.cpp b/src/neochatroom.cpp index 4f13ba749..d7d1839d4 100644 --- a/src/neochatroom.cpp +++ b/src/neochatroom.cpp @@ -266,7 +266,15 @@ QVariantList NeoChatRoom::getUsers(const QString &keyword) const QVariantList matchedList; for (const auto u : userList) { if (u->displayname(this).contains(keyword, Qt::CaseInsensitive)) { - matchedList.append(QVariant::fromValue(u)); + NeoChatUser user(u->id(), u->connection()); + QVariantMap userVariant { + { QStringLiteral("id"), user.id() }, + { QStringLiteral("displayName"), user.displayname(this) }, + { QStringLiteral("avatarMediaId"), user.avatarMediaId(this) }, + { QStringLiteral("color"), user.color() } + }; + + matchedList.append(QVariant::fromValue(userVariant)); } }