From 8b63c18f659b8401d91e08e2c58252ae9506e7e6 Mon Sep 17 00:00:00 2001 From: James Graham Date: Sat, 20 Apr 2024 15:38:31 +0200 Subject: [PATCH] Implement devtoool to show hidden timeline messages --- src/devtools/DebugOptions.qml | 6 ++ src/models/messagefiltermodel.cpp | 19 +++++-- src/models/messagefiltermodel.h | 2 + src/neochatconfig.kcfg | 4 ++ src/timeline/CMakeLists.txt | 1 + src/timeline/EventDelegate.qml | 13 ++++- src/timeline/HiddenDelegate.qml | 94 +++++++++++++++++++++++++++++++ 7 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 src/timeline/HiddenDelegate.qml diff --git a/src/devtools/DebugOptions.qml b/src/devtools/DebugOptions.qml index fe2feb572..5acf87d6a 100644 --- a/src/devtools/DebugOptions.qml +++ b/src/devtools/DebugOptions.qml @@ -15,6 +15,12 @@ FormCard.FormCardPage { FormCard.FormCard { Layout.topMargin: Kirigami.Units.largeSpacing + FormCard.FormCheckDelegate { + text: i18nc("@option:check", "Show hidden events in the timeline") + checked: Config.showAllEvents + + onToggled: Config.showAllEvents = checked + } FormCard.FormCheckDelegate { id: roomAccountDataVisibleCheck text: i18nc("@option:check Enable the matrix 'threads' feature", "Always allow device verification") diff --git a/src/models/messagefiltermodel.cpp b/src/models/messagefiltermodel.cpp index e75f98038..b1fe0f400 100644 --- a/src/models/messagefiltermodel.cpp +++ b/src/models/messagefiltermodel.cpp @@ -36,6 +36,14 @@ MessageFilterModel::MessageFilterModel(QObject *parent, TimelineModel *sourceMod } bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + if (NeoChatConfig::self()->showAllEvents()) { + return true; + } + return eventIsVisible(sourceRow, sourceParent); +} + +bool MessageFilterModel::eventIsVisible(int sourceRow, const QModelIndex &sourceParent) const { const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); @@ -59,9 +67,8 @@ bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour // Don't show state events that are not the first in a consecutive group on the // same day as they will be grouped as a single delegate. const bool notLastRow = sourceRow < sourceModel()->rowCount() - 1; - const bool previousEventIsState = notLastRow - ? sourceModel()->data(sourceModel()->index(sourceRow + 1, 0), MessageEventModel::DelegateTypeRole) == DelegateType::State - : false; + const bool previousEventIsState = + notLastRow ? sourceModel()->data(sourceModel()->index(sourceRow + 1, 0), MessageEventModel::DelegateTypeRole) == DelegateType::State : false; const bool newDay = sourceModel()->data(sourceModel()->index(sourceRow, 0), MessageEventModel::ShowSectionRole).toBool(); if (eventType == DelegateType::State && notLastRow && previousEventIsState && !newDay) { return false; @@ -72,7 +79,11 @@ bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour QVariant MessageFilterModel::data(const QModelIndex &index, int role) const { - if (role == AggregateDisplayRole) { + if (role == MessageEventModel::DelegateTypeRole) { + if (!eventIsVisible(index.row(), index.parent())) { + return DelegateType::Other; + } + } else if (role == AggregateDisplayRole) { return aggregateEventToString(mapToSource(index).row()); } else if (role == StateEventsRole) { return stateEventsList(mapToSource(index).row()); diff --git a/src/models/messagefiltermodel.h b/src/models/messagefiltermodel.h index 87a50a3a0..3b4896eff 100644 --- a/src/models/messagefiltermodel.h +++ b/src/models/messagefiltermodel.h @@ -60,6 +60,8 @@ public: [[nodiscard]] QHash roleNames() const override; private: + bool eventIsVisible(int sourceRow, const QModelIndex &sourceParent) const; + /** * @brief Aggregation of the text of consecutive state events starting at row. * diff --git a/src/neochatconfig.kcfg b/src/neochatconfig.kcfg index 039a6b6b6..d7417cf05 100644 --- a/src/neochatconfig.kcfg +++ b/src/neochatconfig.kcfg @@ -157,6 +157,10 @@ + + + false + false diff --git a/src/timeline/CMakeLists.txt b/src/timeline/CMakeLists.txt index 9c8cdbf4a..c3a46c733 100644 --- a/src/timeline/CMakeLists.txt +++ b/src/timeline/CMakeLists.txt @@ -8,6 +8,7 @@ qt_add_qml_module(timeline QML_FILES EventDelegate.qml TimelineDelegate.qml + HiddenDelegate.qml MessageDelegate.qml LoadingDelegate.qml ReadMarkerDelegate.qml diff --git a/src/timeline/EventDelegate.qml b/src/timeline/EventDelegate.qml index f52a9773a..910f27bfb 100644 --- a/src/timeline/EventDelegate.qml +++ b/src/timeline/EventDelegate.qml @@ -50,6 +50,17 @@ DelegateChooser { DelegateChoice { roleValue: DelegateType.Other - delegate: Item {} + delegate: Config.showAllEvents ? hiddenDelegate : emptyDelegate + + Component { + id: hiddenDelegate + HiddenDelegate { + room: root.room + } + } + Component { + id: emptyDelegate + Item {} + } } } diff --git a/src/timeline/HiddenDelegate.qml b/src/timeline/HiddenDelegate.qml new file mode 100644 index 000000000..d0836514e --- /dev/null +++ b/src/timeline/HiddenDelegate.qml @@ -0,0 +1,94 @@ +// SPDX-FileCopyrightText: 2024 James Graham +// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL + +import QtQuick +import QtQuick.Controls as QQC2 +import QtQuick.Layouts + +import org.kde.kirigami as Kirigami +import org.kde.kirigamiaddons.components as KirigamiComponents + +import org.kde.neochat + +TimelineDelegate { + id: root + + /** + * @brief The NeoChatRoom the delegate is being displayed in. + */ + required property NeoChatRoom room + + /** + * @brief The matrix ID of the message event. + */ + required property string eventId + + /** + * @brief The message author. + * + * This should consist of the following: + * - id - The matrix ID of the author. + * - isLocalUser - Whether the author is the local user. + * - avatarSource - The mxc URL for the author's avatar in the current room. + * - avatarMediaId - The media ID of the author's avatar. + * - avatarUrl - The mxc URL for the author's avatar. + * - displayName - The display name of the author. + * - display - The name of the author. + * - color - The color for the author. + * - object - The Quotient::User object for the author. + * + * @sa Quotient::User + */ + required property var author + + contentItem: QQC2.Control { + id: contentControl + contentItem: RowLayout { + KirigamiComponents.Avatar { + Layout.leftMargin: Kirigami.Units.largeSpacing * 1.5 + implicitWidth: Kirigami.Units.iconSizes.small + implicitHeight: Kirigami.Units.iconSizes.small + + name: root.author.displayName + source: root.author.avatarSource + color: root.author.color + } + QQC2.Label { + text: root.author.displayName + " : " + root.eventId + color: Kirigami.Theme.disabledTextColor + verticalAlignment: Text.AlignVCenter + } + Kirigami.Icon { + implicitWidth: Kirigami.Units.iconSizes.small + implicitHeight: Kirigami.Units.iconSizes.small + source: "view-hidden" + } + } + + TapHandler { + acceptedButtons: Qt.RightButton + onTapped: _private.showMessageMenu() + } + + TapHandler { + acceptedButtons: Qt.LeftButton + onLongPressed: _private.showMessageMenu() + } + + background: Rectangle { + color: Kirigami.Theme.backgroundColor + radius: Kirigami.Units.smallSpacing + border { + width: contentControl.hovered ? 1 : 0 + color: Kirigami.Theme.highlightColor + } + } + } + + QtObject { + id: _private + function showMessageMenu() { + RoomManager.viewEventMenu(root.eventId, root.room, ""); + } + } +}