diff --git a/imports/NeoChat/Component/Timeline/TextDelegate.qml b/imports/NeoChat/Component/Timeline/TextDelegate.qml index 37b08b962..4e40d96cd 100644 --- a/imports/NeoChat/Component/Timeline/TextDelegate.qml +++ b/imports/NeoChat/Component/Timeline/TextDelegate.qml @@ -12,9 +12,11 @@ TextEdit { id: contentLabel readonly property var isEmoji: /^()?(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+(<\/span>)?$/ + readonly property var hasSpoiler: /data-mx-spoiler/g property bool isEmote: false property string textMessage: model.display + property bool spoilerRevealed: !hasSpoiler.test(textMessage) text: "" + (isEmote ? "* " + author.displayName + " " : "") + textMessage + (isEdited ? (" " + "" + i18n(" (edited)") + "") : "") color: Kirigami.Theme.textColor @@ -55,7 +63,11 @@ a{ MouseArea { anchors.fill: parent - acceptedButtons: Qt.NoButton - cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor + acceptedButtons: spoilerRevealed ? Qt.NoButton : Qt.LeftButton + cursorShape: (parent.hoveredLink || !spoilerRevealed) ? Qt.PointingHandCursor : Qt.IBeamCursor + + TapHandler { + onTapped: spoilerRevealed = true + } } } diff --git a/src/neochatroom.cpp b/src/neochatroom.cpp index e3d98d655..6acead447 100644 --- a/src/neochatroom.cpp +++ b/src/neochatroom.cpp @@ -147,6 +147,19 @@ const RoomMessageEvent *NeoChatRoom::lastEvent(bool ignoreStateEvent) const return nullptr; } +bool NeoChatRoom::lastEventIsSpoiler() const +{ + if (auto event = lastEvent()) { + if (auto e = eventCast(event)) { + if (e->hasTextContent() && e->content() && e->mimeType().name() == "text/html") { + auto htmlBody = static_cast(e->content())->body; + return htmlBody.contains("data-mx-spoiler"); + } + } + } + return false; +} + QString NeoChatRoom::lastEventToString() const { if (auto event = lastEvent()) { diff --git a/src/neochatroom.h b/src/neochatroom.h index 4feab4dce..bf8ca9f45 100644 --- a/src/neochatroom.h +++ b/src/neochatroom.h @@ -47,8 +47,15 @@ public: /// Convenient way to get the last event but in a string format. /// /// \see lastEvent + /// \see lastEventIsSpoiler [[nodiscard]] QString lastEventToString() const; + /// Convenient way to check if the last event looks like it has spoilers. + /// + /// \see lastEvent + /// \see lastEventToString + [[nodiscard]] bool lastEventIsSpoiler() const; + /// Convenient way to get the QDateTime of the last event. /// /// \see lastEvent diff --git a/src/roomlistmodel.cpp b/src/roomlistmodel.cpp index c35e96a5b..9e84c825e 100644 --- a/src/roomlistmodel.cpp +++ b/src/roomlistmodel.cpp @@ -364,6 +364,9 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const return room->highlightCount(); } if (role == LastEventRole) { + if (room->lastEventIsSpoiler()) { + return QString(); + } return room->lastEventToString(); } if (role == LastActiveTimeRole) {