Move the update mentions function to ChatDocumentHandler

Move the update mentions function to `ChatDocumentHandler`, this means `ChatbarCache` no longer needs to depend on `ChatDocumentHandler`
This commit is contained in:
James Graham
2025-04-05 20:01:07 +00:00
parent 420baaaf4a
commit 8af0ae6263
5 changed files with 46 additions and 57 deletions

View File

@@ -5,7 +5,6 @@
#include <Quotient/roommember.h> #include <Quotient/roommember.h>
#include "chatdocumenthandler.h"
#include "contentprovider.h" #include "contentprovider.h"
#include "eventhandler.h" #include "eventhandler.h"
#include "models/actionsmodel.h" #include "models/actionsmodel.h"
@@ -218,54 +217,6 @@ QList<Mention> *ChatBarCache::mentions()
return &m_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<NeoChatRoom *>(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<Quotient::RoomMessageEvent>()) {
// Replaces the mentions that are baked into the HTML but plaintext in the original markdown
const QRegularExpression re(uR"lit(<a\shref="https:\/\/matrix.to\/#\/([\S]*)"\s?>([\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 QString ChatBarCache::savedText() const
{ {
return m_savedText; return m_savedText;

View File

@@ -10,8 +10,6 @@
#include "models/messagecontentmodel.h" #include "models/messagecontentmodel.h"
class ChatDocumentHandler;
namespace Quotient namespace Quotient
{ {
class RoomMember; class RoomMember;
@@ -180,11 +178,6 @@ public:
*/ */
QList<Mention> *mentions(); QList<Mention> *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. * @brief Get the saved chat bar text.
*/ */

View File

@@ -15,6 +15,7 @@
#include <Sonnet/Settings> #include <Sonnet/Settings>
#include "chatdocumenthandler_logging.h" #include "chatdocumenthandler_logging.h"
#include "eventhandler.h"
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
@@ -356,4 +357,43 @@ void ChatDocumentHandler::setErrorColor(const QColor &color)
Q_EMIT errorColorChanged(); 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<Quotient::RoomMessageEvent>()) {
// Replaces the mentions that are baked into the HTML but plaintext in the original markdown
const QRegularExpression re(uR"lit(<a\shref="https:\/\/matrix.to\/#\/([\S]*)"\s?>([\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" #include "moc_chatdocumenthandler.cpp"

View File

@@ -141,6 +141,11 @@ public:
[[nodiscard]] QColor errorColor() const; [[nodiscard]] QColor errorColor() const;
void setErrorColor(const QColor &color); 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: Q_SIGNALS:
void documentChanged(); void documentChanged();
void cursorPositionChanged(); void cursorPositionChanged();

View File

@@ -261,7 +261,7 @@ QQC2.Control {
documentHandler.document; documentHandler.document;
if (chatBarCache?.isEditing && chatBarCache.relationMessage.length > 0) { if (chatBarCache?.isEditing && chatBarCache.relationMessage.length > 0) {
textArea.text = chatBarCache.relationMessage; textArea.text = chatBarCache.relationMessage;
root.chatBarCache.updateMentions(textArea.textDocument, documentHandler); documentHandler.updateMentions(textArea.textDocument, chatBarCache.editId);
textArea.forceActiveFocus(); textArea.forceActiveFocus();
textArea.cursorPosition = textArea.text.length; textArea.cursorPosition = textArea.text.length;
} }