From 8af0ae6263d1a05d23f0b5e8948a59d3dda50c09 Mon Sep 17 00:00:00 2001 From: James Graham Date: Sat, 5 Apr 2025 20:01:07 +0000 Subject: [PATCH] Move the update mentions function to ChatDocumentHandler Move the update mentions function to `ChatDocumentHandler`, this means `ChatbarCache` no longer needs to depend on `ChatDocumentHandler` --- src/chatbarcache.cpp | 49 ------------------------------- src/chatbarcache.h | 7 ----- src/chatdocumenthandler.cpp | 40 +++++++++++++++++++++++++ src/chatdocumenthandler.h | 5 ++++ src/timeline/ChatBarComponent.qml | 2 +- 5 files changed, 46 insertions(+), 57 deletions(-) diff --git a/src/chatbarcache.cpp b/src/chatbarcache.cpp index 56ba38a8e..76ec6f975 100644 --- a/src/chatbarcache.cpp +++ b/src/chatbarcache.cpp @@ -5,7 +5,6 @@ #include -#include "chatdocumenthandler.h" #include "contentprovider.h" #include "eventhandler.h" #include "models/actionsmodel.h" @@ -218,54 +217,6 @@ QList *ChatBarCache::mentions() return &m_mentions; } -void ChatBarCache::updateMentions(QQuickTextDocument *document, ChatDocumentHandler *documentHandler) -{ - documentHandler->setDocument(document); - - if (parent() == nullptr) { - qWarning() << "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation."; - return; - } - if (m_relationId.isEmpty()) { - return; - } - auto room = dynamic_cast(parent()); - if (room == nullptr) { - qWarning() << "ChatBarCache created with incorrect parent, a NeoChatRoom must be set as the parent on creation."; - return; - } - - if (auto event = room->findInTimeline(m_relationId); event != room->historyEdge()) { - if (const auto &roomMessageEvent = &*event->viewAs()) { - // Replaces the mentions that are baked into the HTML but plaintext in the original markdown - const QRegularExpression re(uR"lit(([\S]*)<\/a>)lit"_s); - - m_mentions.clear(); - - int linkSize = 0; - auto matches = re.globalMatch(EventHandler::rawMessageBody(*roomMessageEvent)); - while (matches.hasNext()) { - const QRegularExpressionMatch match = matches.next(); - if (match.hasMatch()) { - const QString id = match.captured(1); - const QString name = match.captured(2); - - const int position = match.capturedStart(0) - linkSize; - const int end = position + name.length(); - linkSize += match.capturedLength(0) - name.length(); - - QTextCursor cursor(documentHandler->document()->textDocument()); - cursor.setPosition(position); - cursor.setPosition(end, QTextCursor::KeepAnchor); - cursor.setKeepPositionOnInsert(true); - - m_mentions.push_back(Mention{.cursor = cursor, .text = name, .start = position, .position = end, .id = id}); - } - } - } - } -} - QString ChatBarCache::savedText() const { return m_savedText; diff --git a/src/chatbarcache.h b/src/chatbarcache.h index f736b20bb..877a6aa67 100644 --- a/src/chatbarcache.h +++ b/src/chatbarcache.h @@ -10,8 +10,6 @@ #include "models/messagecontentmodel.h" -class ChatDocumentHandler; - namespace Quotient { class RoomMember; @@ -180,11 +178,6 @@ public: */ QList *mentions(); - /** - * @brief Update the mentions in @p document when editing a message. - */ - Q_INVOKABLE void updateMentions(QQuickTextDocument *document, ChatDocumentHandler *documentHandler); - /** * @brief Get the saved chat bar text. */ diff --git a/src/chatdocumenthandler.cpp b/src/chatdocumenthandler.cpp index 5ff6ab6bf..ff0946d07 100644 --- a/src/chatdocumenthandler.cpp +++ b/src/chatdocumenthandler.cpp @@ -15,6 +15,7 @@ #include #include "chatdocumenthandler_logging.h" +#include "eventhandler.h" using namespace Qt::StringLiterals; @@ -356,4 +357,43 @@ void ChatDocumentHandler::setErrorColor(const QColor &color) Q_EMIT errorColorChanged(); } +void ChatDocumentHandler::updateMentions(QQuickTextDocument *document, const QString &editId) +{ + setDocument(document); + + if (editId.isEmpty() || !m_chatBarCache || !m_room) { + return; + } + + if (auto event = m_room->findInTimeline(editId); event != m_room->historyEdge()) { + if (const auto &roomMessageEvent = &*event->viewAs()) { + // Replaces the mentions that are baked into the HTML but plaintext in the original markdown + const QRegularExpression re(uR"lit(([\S]*)<\/a>)lit"_s); + + m_chatBarCache->mentions()->clear(); + + int linkSize = 0; + auto matches = re.globalMatch(EventHandler::rawMessageBody(*roomMessageEvent)); + while (matches.hasNext()) { + const QRegularExpressionMatch match = matches.next(); + if (match.hasMatch()) { + const QString id = match.captured(1); + const QString name = match.captured(2); + + const int position = match.capturedStart(0) - linkSize; + const int end = position + name.length(); + linkSize += match.capturedLength(0) - name.length(); + + QTextCursor cursor(this->document()->textDocument()); + cursor.setPosition(position); + cursor.setPosition(end, QTextCursor::KeepAnchor); + cursor.setKeepPositionOnInsert(true); + + pushMention(Mention{.cursor = cursor, .text = name, .start = position, .position = end, .id = id}); + } + } + } + } +} + #include "moc_chatdocumenthandler.cpp" diff --git a/src/chatdocumenthandler.h b/src/chatdocumenthandler.h index 34374458c..43c661787 100644 --- a/src/chatdocumenthandler.h +++ b/src/chatdocumenthandler.h @@ -141,6 +141,11 @@ public: [[nodiscard]] QColor errorColor() const; void setErrorColor(const QColor &color); + /** + * @brief Update the mentions in @p document when editing a message. + */ + Q_INVOKABLE void updateMentions(QQuickTextDocument *document, const QString &editId); + Q_SIGNALS: void documentChanged(); void cursorPositionChanged(); diff --git a/src/timeline/ChatBarComponent.qml b/src/timeline/ChatBarComponent.qml index 54ddc4271..4c58ff5bf 100644 --- a/src/timeline/ChatBarComponent.qml +++ b/src/timeline/ChatBarComponent.qml @@ -261,7 +261,7 @@ QQC2.Control { documentHandler.document; if (chatBarCache?.isEditing && chatBarCache.relationMessage.length > 0) { textArea.text = chatBarCache.relationMessage; - root.chatBarCache.updateMentions(textArea.textDocument, documentHandler); + documentHandler.updateMentions(textArea.textDocument, chatBarCache.editId); textArea.forceActiveFocus(); textArea.cursorPosition = textArea.text.length; }