From be3b5cdb8a3f6e3bfab21eb2008a4b0aa8928228 Mon Sep 17 00:00:00 2001 From: James Graham Date: Fri, 7 Apr 2023 19:03:04 +0000 Subject: [PATCH] Handle emotes in texthander This moves the code to add the emote user pill into texthandler removing the now redundant checks from the message delegates. --- autotests/texthandlertest.cpp | 33 ++++++++++++++++++- src/qml/Component/Timeline/EventDelegate.qml | 4 +-- .../Component/Timeline/MessageDelegate.qml | 2 -- src/qml/Component/Timeline/RichLabel.qml | 3 +- .../Component/Timeline/TimelineContainer.qml | 3 +- src/texthandler.cpp | 16 +++++++++ 6 files changed, 51 insertions(+), 10 deletions(-) diff --git a/autotests/texthandlertest.cpp b/autotests/texthandlertest.cpp index 2d2eed630..df97c51da 100644 --- a/autotests/texthandlertest.cpp +++ b/autotests/texthandlertest.cpp @@ -59,6 +59,7 @@ private Q_SLOTS: void receiveRichtextIn(); void receiveRichMxcUrl(); void receiveRichPlainUrl(); + void receiveRichEmote(); }; #ifdef QUOTIENT_07 @@ -148,6 +149,22 @@ void TextHandlerTest::initTestCase() "unsigned": { "age": 1235 } + }, + { + "content": { + "body": "/me This is an emote.", + "format": "org.matrix.custom.html", + "formatted_body": "This is an emote.", + "msgtype": "m.emote" + }, + "event_id": "$153273582443PhrSn:example.org", + "origin_server_ts": 1532735824654, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "sender": "@example:example.org", + "type": "m.room.message", + "unsigned": { + "age": 1236 + } } ], "limited": true, @@ -439,7 +456,7 @@ void TextHandlerTest::receiveRichMxcUrl() TextHandler testTextHandler; testTextHandler.setData(testInputString); - QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().back().get()), testOutputString); + QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(0).get()), testOutputString); } #endif @@ -498,5 +515,19 @@ void TextHandlerTest::receiveRichPlainUrl() QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringMxId); } +// Test that user pill is add to an emote message. +// N.B. The second message in the test timeline is marked as an emote. +void TextHandlerTest::receiveRichEmote() +{ + const QString testInputString = QStringLiteral("This is an emote."); + const QString testOutputString = + QStringLiteral("* @example:example.org This is an emote."); + + TextHandler testTextHandler; + testTextHandler.setData(testInputString); + + QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(1).get()), testOutputString); +} + QTEST_MAIN(TextHandlerTest) #include "texthandlertest.moc" diff --git a/src/qml/Component/Timeline/EventDelegate.qml b/src/qml/Component/Timeline/EventDelegate.qml index e2f1605da..eb4c9d41f 100644 --- a/src/qml/Component/Timeline/EventDelegate.qml +++ b/src/qml/Component/Timeline/EventDelegate.qml @@ -20,9 +20,7 @@ DelegateChooser { DelegateChoice { roleValue: MessageEventModel.Emote - delegate: MessageDelegate { - isEmote: true - } + delegate: MessageDelegate {} } DelegateChoice { diff --git a/src/qml/Component/Timeline/MessageDelegate.qml b/src/qml/Component/Timeline/MessageDelegate.qml index 5574c2778..52b4849d3 100644 --- a/src/qml/Component/Timeline/MessageDelegate.qml +++ b/src/qml/Component/Timeline/MessageDelegate.qml @@ -13,7 +13,6 @@ import org.kde.neochat 1.0 TimelineContainer { id: messageDelegate - property bool isEmote: false onOpenContextMenu: openMessageContext(model, label.selectedText, Controller.plainText(label.textDocument)) innerObject: ColumnLayout { @@ -22,7 +21,6 @@ TimelineContainer { id: label Layout.fillWidth: true visible: currentRoom.chatBoxEditId !== model.eventId - isEmote: messageDelegate.isEmote } Loader { Layout.fillWidth: true diff --git a/src/qml/Component/Timeline/RichLabel.qml b/src/qml/Component/Timeline/RichLabel.qml index db19f9702..c87259048 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 isEmote: false property bool isReplyLabel: false property string textMessage: model.display property bool spoilerRevealed: !hasSpoiler.test(textMessage) @@ -60,7 +59,7 @@ a{ background: " + Kirigami.Theme.textColor + "; } " : "") + " -" + (isEmote ? "* " + author.displayName + " " : "") + textMessage + (isEdited && !contentLabel.isReplyLabel ? (" " + "" + i18n(" (edited)") + "") : "") +" + textMessage + (isEdited && !contentLabel.isReplyLabel ? (" " + "" + i18n(" (edited)") + "") : "") color: Kirigami.Theme.textColor selectedTextColor: Kirigami.Theme.highlightedTextColor diff --git a/src/qml/Component/Timeline/TimelineContainer.qml b/src/qml/Component/Timeline/TimelineContainer.qml index 37c3820bf..300cc8a09 100644 --- a/src/qml/Component/Timeline/TimelineContainer.qml +++ b/src/qml/Component/Timeline/TimelineContainer.qml @@ -21,7 +21,6 @@ ColumnLayout { default property alias innerObject : column.children property Item hoverComponent: hoverActions ?? null - property bool isEmote: false property bool cardBackground: true property bool showUserMessageOnRight: Config.showLocalMessagesOnRight && model.author.isLocalUser && !Config.compactLayout property bool isHighlighted: model.isHighlighted || isTemporaryHighlighted @@ -212,7 +211,7 @@ ColumnLayout { id: rowLayout spacing: Kirigami.Units.smallSpacing - visible: model.showAuthor && !isEmote + visible: model.showAuthor QQC2.Label { id: nameLabel diff --git a/src/texthandler.cpp b/src/texthandler.cpp index 25a9f4eed..717e15784 100644 --- a/src/texthandler.cpp +++ b/src/texthandler.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -134,6 +135,21 @@ QString TextHandler::handleRecieveRichText(Qt::TextFormat inputFormat, const Neo nextTokenType(); } + // If the message is an emote add the user pill to the front of the message. + if (event != nullptr) { + auto e = eventCast(event); + if (e->msgtype() == Quotient::MessageEventType::Emote) { + auto author = static_cast(room->user(e->senderId())); + QString emoteString = QStringLiteral("* senderId() + QStringLiteral("\" style=\"color:") + + author->color().name() + QStringLiteral("\">") + author->displayname(room) + QStringLiteral(" "); + if (outputString.startsWith(QStringLiteral("

"))) { + outputString.insert(3, emoteString); + } else { + outputString.prepend(emoteString); + } + } + } + /** * Replace with * Note: is still not a valid tag for the message from the server. We