From 4bf65339f8ba805ad6445177047a253b298d13d4 Mon Sep 17 00:00:00 2001 From: James Graham Date: Sat, 8 Apr 2023 20:58:44 +0000 Subject: [PATCH] Texthandler edited Move the handling of adding whether the message has been edited to texthandler. --- autotests/texthandlertest.cpp | 50 ++++++++++++++++++- src/models/messageeventmodel.cpp | 9 ---- src/models/messageeventmodel.h | 1 - src/qml/Component/Timeline/ReplyComponent.qml | 1 - src/qml/Component/Timeline/RichLabel.qml | 3 +- src/texthandler.cpp | 28 +++++++++++ src/texthandler.h | 5 +- 7 files changed, 81 insertions(+), 16 deletions(-) diff --git a/autotests/texthandlertest.cpp b/autotests/texthandlertest.cpp index df97c51da..9e48b0358 100644 --- a/autotests/texthandlertest.cpp +++ b/autotests/texthandlertest.cpp @@ -60,6 +60,8 @@ private Q_SLOTS: void receiveRichMxcUrl(); void receiveRichPlainUrl(); void receiveRichEmote(); + void receiveRichEdited_data(); + void receiveRichEdited(); }; #ifdef QUOTIENT_07 @@ -147,7 +149,7 @@ void TextHandlerTest::initTestCase() "sender": "@example:example.org", "type": "m.room.message", "unsigned": { - "age": 1235 + "age": 1232 } }, { @@ -163,7 +165,28 @@ void TextHandlerTest::initTestCase() "sender": "@example:example.org", "type": "m.room.message", "unsigned": { - "age": 1236 + "age": 1231 + } + }, + { + "content": { + "body": "tested", + "msgtype": "m.text" + }, + "event_id": "$zrCiBxBnqqTn0Z5FY78qSZAszno_w8nJJXzfBULG-3E", + "origin_server_ts": 1680948575928, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "sender": "@example:example.org", + "type": "m.room.message", + "unsigned": { + "age": 1747776, + "m.relations": { + "m.replace": { + "event_id": "$UX0PlpyI7vYO32iHMuuYEP7ECMh4sX3XLGiB2SwM4mQ", + "origin_server_ts": 1680948580992, + "sender": "@example:example.org" + } + } } } ], @@ -529,5 +552,28 @@ void TextHandlerTest::receiveRichEmote() QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(1).get()), testOutputString); } +void TextHandlerTest::receiveRichEdited_data() +{ + QTest::addColumn("testInputString"); + QTest::addColumn("testOutputString"); + + QTest::newRow("basic") << QStringLiteral("Edited") << QStringLiteral("Edited (edited)"); + QTest::newRow("multiple paragraphs") << QStringLiteral("

Edited

\n

Edited

") + << QStringLiteral("

Edited

\n

Edited (edited)

"); + QTest::newRow("blockquote") << QStringLiteral("
Edited
") + << QStringLiteral("
Edited

(edited)

"); +} + +void TextHandlerTest::receiveRichEdited() +{ + QFETCH(QString, testInputString); + QFETCH(QString, testOutputString); + + TextHandler testTextHandler; + testTextHandler.setData(testInputString); + + QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(2).get()), testOutputString); +} + QTEST_MAIN(TextHandlerTest) #include "texthandlertest.moc" diff --git a/src/models/messageeventmodel.cpp b/src/models/messageeventmodel.cpp index f79d07026..11938aea5 100644 --- a/src/models/messageeventmodel.cpp +++ b/src/models/messageeventmodel.cpp @@ -57,7 +57,6 @@ QHash MessageEventModel::roleNames() const roles[ReadMarkersStringRole] = "readMarkersString"; roles[ShowReadMarkersRole] = "showReadMarkers"; roles[ReactionRole] = "reaction"; - roles[IsEditedRole] = "isEdited"; roles[SourceRole] = "source"; roles[MimeTypeRole] = "mimeType"; roles[FormattedBodyRole] = "formattedBody"; @@ -662,14 +661,6 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const return EventStatus::Normal; } - if (role == IsEditedRole) { - if (auto e = eventCast(&evt)) { - return !e->unsignedJson().isEmpty() && e->unsignedJson().contains("m.relations") - && e->unsignedJson()["m.relations"].toObject().contains("m.replace"); - } - return false; - } - if (role == EventIdRole) { return !evt.id().isEmpty() ? evt.id() : evt.transactionId(); } diff --git a/src/models/messageeventmodel.h b/src/models/messageeventmodel.h index 7f6ba3816..5122bc380 100644 --- a/src/models/messageeventmodel.h +++ b/src/models/messageeventmodel.h @@ -63,7 +63,6 @@ public: ShowReadMarkersRole, /**< bool with whether there are any other user read markers to be shown. */ ReactionRole, - IsEditedRole, SourceRole, MediaUrlRole, // For debugging diff --git a/src/qml/Component/Timeline/ReplyComponent.qml b/src/qml/Component/Timeline/ReplyComponent.qml index 476049143..deb60e90b 100644 --- a/src/qml/Component/Timeline/ReplyComponent.qml +++ b/src/qml/Component/Timeline/ReplyComponent.qml @@ -96,7 +96,6 @@ Item { RichLabel { textMessage: reply.display textFormat: Text.RichText - isReplyLabel: true HoverHandler { enabled: !hoveredLink diff --git a/src/qml/Component/Timeline/RichLabel.qml b/src/qml/Component/Timeline/RichLabel.qml index c87259048..b7842b559 100644 --- a/src/qml/Component/Timeline/RichLabel.qml +++ b/src/qml/Component/Timeline/RichLabel.qml @@ -14,7 +14,6 @@ TextEdit { readonly property var isEmoji: /^()?(\u00a9|\u00ae|[\u20D0-\u2fff]|[\u3190-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+(<\/span>)?$/ readonly property var hasSpoiler: /data-mx-spoiler/g - property bool isReplyLabel: false property string textMessage: model.display property bool spoilerRevealed: !hasSpoiler.test(textMessage) @@ -59,7 +58,7 @@ a{ background: " + Kirigami.Theme.textColor + "; } " : "") + " -" + textMessage + (isEdited && !contentLabel.isReplyLabel ? (" " + "" + i18n(" (edited)") + "") : "") +" + textMessage color: Kirigami.Theme.textColor selectedTextColor: Kirigami.Theme.highlightedTextColor diff --git a/src/texthandler.cpp b/src/texthandler.cpp index 717e15784..fdcef9810 100644 --- a/src/texthandler.cpp +++ b/src/texthandler.cpp @@ -7,10 +7,13 @@ #include #include +#include #include #include +#include + static const QStringList allowedTags = { QStringLiteral("font"), QStringLiteral("del"), QStringLiteral("h1"), QStringLiteral("h2"), QStringLiteral("h3"), QStringLiteral("h4"), QStringLiteral("h5"), QStringLiteral("h6"), QStringLiteral("blockquote"), QStringLiteral("p"), QStringLiteral("a"), QStringLiteral("ul"), @@ -150,6 +153,31 @@ QString TextHandler::handleRecieveRichText(Qt::TextFormat inputFormat, const Neo } } + if (auto e = eventCast(event)) { + bool isEdited = + !e->unsignedJson().isEmpty() && e->unsignedJson().contains("m.relations") && e->unsignedJson()["m.relations"].toObject().contains("m.replace"); + if (isEdited) { + Kirigami::PlatformTheme *theme = static_cast(qmlAttachedPropertiesObject(this, true)); + + QString editTextColor; + if (theme != nullptr) { + editTextColor = theme->disabledTextColor().name(); + } else { + editTextColor = QStringLiteral("#000000"); + } + QString editedString = QStringLiteral(" (edited)"); + if (outputString.endsWith(QStringLiteral("

"))) { + outputString.insert(outputString.length() - 4, editedString); + } else if (outputString.endsWith(QStringLiteral("")) || outputString.endsWith(QStringLiteral("")) + || outputString.endsWith(QStringLiteral("")) || outputString.endsWith(QStringLiteral("")) + || outputString.endsWith(QStringLiteral(""))) { + outputString.append("

" + editedString + "

"); + } else { + outputString.append(editedString); + } + } + } + /** * Replace with * Note: is still not a valid tag for the message from the server. We diff --git a/src/texthandler.h b/src/texthandler.h index dc0440fa0..b16e2cfa4 100644 --- a/src/texthandler.h +++ b/src/texthandler.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include #include @@ -39,8 +40,10 @@ static const QRegularExpression mxId(QStringLiteral(R"((^|[][[:space:](){}`'";]) * be present as per the matrix spec * (https://spec.matrix.org/v1.5/client-server-api/#mroommessage-msgtypes). */ -class TextHandler +class TextHandler : public QObject { + Q_OBJECT + public: /** * @brief List of token types