diff --git a/imports/NeoChat/Component/ChatTextInput.qml b/imports/NeoChat/Component/ChatTextInput.qml index 9057703b0..7422411a7 100644 --- a/imports/NeoChat/Component/ChatTextInput.qml +++ b/imports/NeoChat/Component/ChatTextInput.qml @@ -133,6 +133,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 @@ -437,13 +438,18 @@ 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() { // Qt wraps lines so we need to use a small hack // to remove the wrapped lines but not break the empty // lines. - const updatedText = inputField.text.trim() - .replace(/@([^: ]*):([^ ]*\.[^ ]*)/, "[@$1:$2](https://matrix.to/#/@$1:$2)"); - documentHandler.postMessage(updatedText, attachmentPath, replyEventID); + documentHandler.postMessage(inputField.text.trim(), attachmentPath, replyEventID, + inputField.userAutocompleted); clearAttachment(); currentRoom.markAllMessagesAsRead(); clear(); @@ -454,6 +460,9 @@ ToolBar { function autoComplete() { documentHandler.replaceAutoComplete(autoCompleteListView.currentItem.displayText) + if (!autoCompleteListView.currentItem.isEmoji) { + inputField.userAutocompleted[autoCompleteListView.currentItem.displayText] = autoCompleteListView.currentItem.userId; + } } } @@ -543,6 +552,7 @@ ToolBar { function clear() { inputField.clear() + inputField.userAutocompleted = {}; } function clearReply() { diff --git a/src/chatdocumenthandler.cpp b/src/chatdocumenthandler.cpp index b9fabf82d..9a267ecc3 100644 --- a/src/chatdocumenthandler.cpp +++ b/src/chatdocumenthandler.cpp @@ -167,7 +167,8 @@ QVariantMap ChatDocumentHandler::getAutocompletionInfo() }; } -void ChatDocumentHandler::postMessage(const QString &text, const QString &attachementPath, const QString &replyEventId) const +void ChatDocumentHandler::postMessage(const QString &text, const QString &attachementPath, + const QString &replyEventId, const QVariantMap usernames) const { if (!m_room || !m_document) { return; @@ -177,6 +178,13 @@ void ChatDocumentHandler::postMessage(const QString &text, const QString &attach cleanedText = cleanedText.trimmed(); + 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); } @@ -200,7 +208,7 @@ void ChatDocumentHandler::postMessage(const QString &text, const QString &attach for (int i = 0; i < cleanedText.length(); i++) { rainbowText = rainbowText % QStringLiteral("" % cleanedText.at(i) % ""; } - m_room->postHtmlMessage(cleanedText, rainbowText, messageEventType, replyEventId); + m_room->postHtmlMessage(text, rainbowText, messageEventType, replyEventId); return; } diff --git a/src/chatdocumenthandler.h b/src/chatdocumenthandler.h index 5e7c413e6..bc9bb449e 100644 --- a/src/chatdocumenthandler.h +++ b/src/chatdocumenthandler.h @@ -51,7 +51,7 @@ public: [[nodiscard]] NeoChatRoom *room() const; void setRoom(NeoChatRoom *room); - Q_INVOKABLE void postMessage(const QString &text, const QString &attachementPath, const QString &replyEventId) const; + Q_INVOKABLE void postMessage(const QString &text, const QString &attachementPath, const QString &replyEventId, const QVariantMap usernames) const; /// This function will look at the current QTextCursor and determine if there /// is the posibility to autocomplete it.