From 1821d9fc0492517e3a1dd9c6aecfd4ee3c745c6f Mon Sep 17 00:00:00 2001 From: James Graham Date: Sun, 15 Sep 2024 08:39:22 +0000 Subject: [PATCH] Move reply pane to use MessageContentModel Move reply pane to use MessageContentModel. This means the reply pane component is no longer required. This commit also limits the size of code and image componets in a reply to keep them from getting too huge. --- autotests/chatbarcachetest.cpp | 12 +-- src/chatbar/CMakeLists.txt | 1 - src/chatbar/ChatBar.qml | 34 +++++-- src/chatbar/ReplyPane.qml | 98 ------------------- src/chatbarcache.cpp | 29 +++++- src/chatbarcache.h | 16 ++- src/timeline/ReplyComponent.qml | 2 + src/timeline/ReplyMessageComponentChooser.qml | 4 + 8 files changed, 80 insertions(+), 116 deletions(-) delete mode 100644 src/chatbar/ReplyPane.qml diff --git a/autotests/chatbarcachetest.cpp b/autotests/chatbarcachetest.cpp index fbfa00838..839b2dba4 100644 --- a/autotests/chatbarcachetest.cpp +++ b/autotests/chatbarcachetest.cpp @@ -51,7 +51,7 @@ void ChatBarCacheTest::empty() QCOMPARE(chatBarCache->replyId(), QString()); QCOMPARE(chatBarCache->isEditing(), false); QCOMPARE(chatBarCache->editId(), QString()); - QCOMPARE(chatBarCache->relationUser(), room->member(QString())); + QCOMPARE(chatBarCache->relationAuthor(), room->member(QString())); QCOMPARE(chatBarCache->relationMessage(), QString()); QCOMPARE(chatBarCache->attachmentPath(), QString()); } @@ -65,7 +65,7 @@ void ChatBarCacheTest::noRoom() // ChatBarCache has no parent. QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation."); - QCOMPARE(chatBarCache->relationUser(), Quotient::RoomMember()); + QCOMPARE(chatBarCache->relationAuthor(), Quotient::RoomMember()); QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation."); QCOMPARE(chatBarCache->relationMessage(), QString()); @@ -81,7 +81,7 @@ void ChatBarCacheTest::badParent() // ChatBarCache has no parent. QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with incorrect parent, a NeoChatRoom must be set as the parent on creation."); - QCOMPARE(chatBarCache->relationUser(), Quotient::RoomMember()); + QCOMPARE(chatBarCache->relationAuthor(), Quotient::RoomMember()); QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with incorrect parent, a NeoChatRoom must be set as the parent on creation."); QCOMPARE(chatBarCache->relationMessage(), QString()); @@ -99,7 +99,7 @@ void ChatBarCacheTest::reply() QCOMPARE(chatBarCache->replyId(), QLatin1String("$153456789:example.org")); QCOMPARE(chatBarCache->isEditing(), false); QCOMPARE(chatBarCache->editId(), QString()); - QCOMPARE(chatBarCache->relationUser(), room->member(QLatin1String("@example:example.org"))); + QCOMPARE(chatBarCache->relationAuthor(), room->member(QLatin1String("@example:example.org"))); QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message")); QCOMPARE(chatBarCache->attachmentPath(), QString()); } @@ -121,7 +121,7 @@ void ChatBarCacheTest::edit() QCOMPARE(chatBarCache->replyId(), QString()); QCOMPARE(chatBarCache->isEditing(), true); QCOMPARE(chatBarCache->editId(), QLatin1String("$153456789:example.org")); - QCOMPARE(chatBarCache->relationUser(), room->member(QLatin1String("@example:example.org"))); + QCOMPARE(chatBarCache->relationAuthor(), room->member(QLatin1String("@example:example.org"))); QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message")); QCOMPARE(chatBarCache->attachmentPath(), QString()); } @@ -138,7 +138,7 @@ void ChatBarCacheTest::attachment() QCOMPARE(chatBarCache->replyId(), QString()); QCOMPARE(chatBarCache->isEditing(), false); QCOMPARE(chatBarCache->editId(), QString()); - QCOMPARE(chatBarCache->relationUser(), room->member(QString())); + QCOMPARE(chatBarCache->relationAuthor(), room->member(QString())); QCOMPARE(chatBarCache->relationMessage(), QString()); QCOMPARE(chatBarCache->attachmentPath(), QLatin1String("some/path")); } diff --git a/src/chatbar/CMakeLists.txt b/src/chatbar/CMakeLists.txt index d977fbfa1..89a65c95d 100644 --- a/src/chatbar/CMakeLists.txt +++ b/src/chatbar/CMakeLists.txt @@ -11,7 +11,6 @@ ecm_add_qml_module(chatbar GENERATE_PLUGIN_SOURCE CompletionMenu.qml EmojiDelegate.qml EmojiGrid.qml - ReplyPane.qml PieProgressBar.qml EmojiPicker.qml EmojiDialog.qml diff --git a/src/chatbar/ChatBar.qml b/src/chatbar/ChatBar.qml index 2ee4fb258..093cd50e7 100644 --- a/src/chatbar/ChatBar.qml +++ b/src/chatbar/ChatBar.qml @@ -175,6 +175,7 @@ QQC2.Control { Layout.fillWidth: true Layout.margins: Kirigami.Units.largeSpacing + Layout.preferredHeight: active ? item.implicitHeight : 0 active: visible visible: root.currentRoom.mainCache.replyId.length > 0 || root.currentRoom.mainCache.attachmentPath.length > 0 @@ -361,15 +362,32 @@ QQC2.Control { Component { id: replyPane - ReplyPane { - userName: _private.chatBarCache.relationUser.displayName - userColor: _private.chatBarCache.relationUser.color - userAvatar: _private.chatBarCache.relationUser.avatarUrl - text: _private.chatBarCache.relationMessage + Item { + implicitWidth: replyComponent.implicitWidth + implicitHeight: replyComponent.implicitHeight + ReplyComponent { + id: replyComponent + replyEventId: _private.chatBarCache.replyId + replyAuthor: _private.chatBarCache.relationAuthor + replyContentModel: _private.chatBarCache.relationEventContentModel + maxContentWidth: paneLoader.item.width + } + QQC2.Button { + id: cancelButton - onCancel: { - _private.chatBarCache.replyId = ""; - _private.chatBarCache.attachmentPath = ""; + anchors.top: parent.top + anchors.right: parent.right + + display: QQC2.AbstractButton.IconOnly + text: i18nc("@action:button", "Cancel reply") + icon.name: "dialog-close" + onClicked: { + _private.chatBarCache.replyId = ""; + _private.chatBarCache.attachmentPath = ""; + } + QQC2.ToolTip.text: text + QQC2.ToolTip.visible: hovered + QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay } } } diff --git a/src/chatbar/ReplyPane.qml b/src/chatbar/ReplyPane.qml deleted file mode 100644 index 36673b272..000000000 --- a/src/chatbar/ReplyPane.qml +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Carl Schwan -// SPDX-FileCopyrightText: 2020 Noah Davis -// SPDX-License-Identifier: GPL-2.0-or-later - -import QtQuick -import QtQuick.Layouts -import QtQuick.Controls as QQC2 - -import org.kde.kirigami as Kirigami -import org.kde.kirigamiaddons.labs.components as KirigamiComponents - -import org.kde.neochat - -RowLayout { - id: root - - property string userName - property color userColor - property url userAvatar: "" - property var text - - signal cancel - - Rectangle { - id: verticalBorder - - Layout.fillHeight: true - - implicitWidth: Kirigami.Units.smallSpacing - color: userColor - } - ColumnLayout { - RowLayout { - KirigamiComponents.Avatar { - id: replyAvatar - - implicitWidth: Kirigami.Units.iconSizes.small - implicitHeight: Kirigami.Units.iconSizes.small - - source: userAvatar - name: userName - color: userColor - } - QQC2.Label { - Layout.fillWidth: true - Layout.alignment: Qt.AlignLeft - - color: userColor - text: userName - elide: Text.ElideRight - } - } - QQC2.TextArea { - id: textArea - - Layout.fillWidth: true - - leftPadding: 0 - rightPadding: 0 - topPadding: 0 - bottomPadding: 0 - text: "" + replyTextMetrics.elidedText - selectByMouse: true - selectByKeyboard: true - readOnly: true - wrapMode: TextEdit.Wrap - textFormat: TextEdit.RichText - background: Item {} - HoverHandler { - cursorShape: textArea.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor - } - - TextMetrics { - id: replyTextMetrics - - text: root.text - font: textArea.font - elide: Qt.ElideRight - elideWidth: textArea.width * 2 - Kirigami.Units.smallSpacing * 2 - } - } - } - QQC2.ToolButton { - id: cancelButton - - Layout.alignment: Qt.AlignVCenter - - display: QQC2.AbstractButton.IconOnly - text: i18nc("@action:button", "Cancel reply") - icon.name: "dialog-close" - onClicked: { - root.cancel(); - } - QQC2.ToolTip.text: text - QQC2.ToolTip.visible: hovered - QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay - } -} diff --git a/src/chatbarcache.cpp b/src/chatbarcache.cpp index 66f7cdda3..08c33c15a 100644 --- a/src/chatbarcache.cpp +++ b/src/chatbarcache.cpp @@ -7,6 +7,7 @@ #include "chatdocumenthandler.h" #include "eventhandler.h" +#include "messagecontentmodel.h" #include "neochatroom.h" ChatBarCache::ChatBarCache(QObject *parent) @@ -53,6 +54,7 @@ void ChatBarCache::setReplyId(const QString &replyId) m_relationType = Reply; } m_attachmentPath = QString(); + delete m_relationContentModel; Q_EMIT relationIdChanged(oldEventId, m_relationId); Q_EMIT attachmentPathChanged(); } @@ -82,11 +84,12 @@ void ChatBarCache::setEditId(const QString &editId) m_relationType = Edit; } m_attachmentPath = QString(); + delete m_relationContentModel; Q_EMIT relationIdChanged(oldEventId, m_relationId); Q_EMIT attachmentPathChanged(); } -Quotient::RoomMember ChatBarCache::relationUser() const +Quotient::RoomMember ChatBarCache::relationAuthor() const { if (parent() == nullptr) { qWarning() << "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation."; @@ -124,6 +127,28 @@ QString ChatBarCache::relationMessage() const return {}; } +MessageContentModel *ChatBarCache::relationEventContentModel() +{ + if (parent() == nullptr) { + qWarning() << "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation."; + return nullptr; + } + if (m_relationId.isEmpty()) { + return nullptr; + } + if (m_relationContentModel != nullptr) { + return m_relationContentModel; + } + + auto room = dynamic_cast(parent()); + if (room == nullptr) { + qWarning() << "ChatBarCache created with incorrect parent, a NeoChatRoom must be set as the parent on creation."; + return nullptr; + } + m_relationContentModel = new MessageContentModel(room, m_relationId, true); + return m_relationContentModel; +} + bool ChatBarCache::isThreaded() const { return !m_threadId.isEmpty(); @@ -156,6 +181,7 @@ void ChatBarCache::setAttachmentPath(const QString &attachmentPath) m_attachmentPath = attachmentPath; m_relationType = None; const auto oldEventId = std::exchange(m_relationId, QString()); + delete m_relationContentModel; Q_EMIT attachmentPathChanged(); Q_EMIT relationIdChanged(oldEventId, m_relationId); } @@ -165,6 +191,7 @@ void ChatBarCache::clearRelations() const auto oldEventId = std::exchange(m_relationId, QString()); const auto oldThreadId = std::exchange(m_threadId, QString()); m_attachmentPath = QString(); + delete m_relationContentModel; Q_EMIT relationIdChanged(oldEventId, m_relationId); Q_EMIT threadIdChanged(oldThreadId, m_threadId); Q_EMIT attachmentPathChanged(); diff --git a/src/chatbarcache.h b/src/chatbarcache.h index 7278af5b3..7c32392b5 100644 --- a/src/chatbarcache.h +++ b/src/chatbarcache.h @@ -8,6 +8,8 @@ #include #include +#include "models/messagecontentmodel.h" + class ChatDocumentHandler; namespace Quotient @@ -100,7 +102,7 @@ class ChatBarCache : public QObject * * @sa Quotient::RoomMember */ - Q_PROPERTY(Quotient::RoomMember relationUser READ relationUser NOTIFY relationIdChanged) + Q_PROPERTY(Quotient::RoomMember relationAuthor READ relationAuthor NOTIFY relationIdChanged) /** * @brief The content of the related message. @@ -109,6 +111,13 @@ class ChatBarCache : public QObject */ Q_PROPERTY(QString relationMessage READ relationMessage NOTIFY relationIdChanged) + /** + * @brief The MessageContentModel for the related message. + * + * Will be nullptr if no related message. + */ + Q_PROPERTY(MessageContentModel *relationEventContentModel READ relationEventContentModel NOTIFY relationIdChanged) + /** * @brief Whether the chat bar is replying in a thread. */ @@ -154,9 +163,10 @@ public: QString editId() const; void setEditId(const QString &editId); - Quotient::RoomMember relationUser() const; + Quotient::RoomMember relationAuthor() const; QString relationMessage() const; + MessageContentModel *relationEventContentModel(); bool isThreaded() const; QString threadId() const; @@ -206,4 +216,6 @@ private: QString m_attachmentPath = QString(); QList m_mentions; QString m_savedText; + + QPointer m_relationContentModel; }; diff --git a/src/timeline/ReplyComponent.qml b/src/timeline/ReplyComponent.qml index 73172b064..fa23ff19e 100644 --- a/src/timeline/ReplyComponent.qml +++ b/src/timeline/ReplyComponent.qml @@ -53,6 +53,8 @@ RowLayout { */ signal replyClicked(string eventID) + Layout.fillWidth: true + spacing: Kirigami.Units.largeSpacing Rectangle { diff --git a/src/timeline/ReplyMessageComponentChooser.qml b/src/timeline/ReplyMessageComponentChooser.qml index 0e41e637c..7fca5aa9b 100644 --- a/src/timeline/ReplyMessageComponentChooser.qml +++ b/src/timeline/ReplyMessageComponentChooser.qml @@ -5,6 +5,8 @@ import QtQuick import QtQuick.Layouts import Qt.labs.qmlmodels +import org.kde.kirigami as Kirigami + import org.kde.neochat /** @@ -60,6 +62,7 @@ DelegateChooser { MediaSizeHelper { id: mediaSizeHelper contentMaxWidth: root.maxContentWidth + contentMaxHeight: Kirigami.Units.gridUnit * 5 mediaWidth: image.mediaInfo.width ?? 0 mediaHeight: image.mediaInfo.height ?? 0 } @@ -81,6 +84,7 @@ DelegateChooser { DelegateChoice { roleValue: MessageComponentType.Code delegate: CodeComponent { + Layout.maximumHeight: Kirigami.Units.gridUnit * 5 maxContentWidth: root.maxContentWidth MouseArea {