From 5d2139471a542a30724d481dc567386ac1589de2 Mon Sep 17 00:00:00 2001 From: James Graham Date: Fri, 23 Aug 2024 14:56:01 +0000 Subject: [PATCH] MessageEditComponent Updates Rename MessageEditComponent to ChatBarComponent in preparation for also using it with threads and cleanup. --- src/chatbar/ChatBar.qml | 3 +- src/chatbarcache.cpp | 10 +++ src/chatbarcache.h | 11 +++- src/models/messagecontentmodel.cpp | 1 + src/timeline/CMakeLists.txt | 2 +- ...EditComponent.qml => ChatBarComponent.qml} | 65 ++++++++++--------- src/timeline/MessageComponentChooser.qml | 3 +- 7 files changed, 57 insertions(+), 38 deletions(-) rename src/timeline/{MessageEditComponent.qml => ChatBarComponent.qml} (74%) diff --git a/src/chatbar/ChatBar.qml b/src/chatbar/ChatBar.qml index 10e002557..2ee4fb258 100644 --- a/src/chatbar/ChatBar.qml +++ b/src/chatbar/ChatBar.qml @@ -395,8 +395,7 @@ QQC2.Control { repeatTimer.stop(); root.currentRoom.markAllMessagesAsRead(); textField.clear(); - _private.chatBarCache.replyId = ""; - _private.chatBarCache.threadId = ""; + _private.chatBarCache.clearRelations(); messageSent(); } diff --git a/src/chatbarcache.cpp b/src/chatbarcache.cpp index a0a6981dc..f027ec67e 100644 --- a/src/chatbarcache.cpp +++ b/src/chatbarcache.cpp @@ -160,6 +160,16 @@ void ChatBarCache::setAttachmentPath(const QString &attachmentPath) Q_EMIT relationIdChanged(oldEventId, m_relationId); } +void ChatBarCache::clearRelations() +{ + const auto oldEventId = std::exchange(m_relationId, QString()); + m_threadId = QString(); + m_attachmentPath = QString(); + Q_EMIT relationIdChanged(oldEventId, m_relationId); + Q_EMIT threadIdChanged(); + Q_EMIT attachmentPathChanged(); +} + QList *ChatBarCache::mentions() { return &m_mentions; diff --git a/src/chatbarcache.h b/src/chatbarcache.h index 3d3ff0777..02304711b 100644 --- a/src/chatbarcache.h +++ b/src/chatbarcache.h @@ -33,7 +33,7 @@ struct Mention { * A class to cache data from a chat bar. * * A chat bar can be anything that allows users to compose or edit message, it doesn't - * necessarily have to use the ChatBar component, e.g. MessageEditComponent. + * necessarily have to use the ChatBar component, e.g. ChatBarComponent. * * This object is intended to allow the current contents of a chat bar to be cached * between different rooms, i.e. there is an expectation that each NeoChatRoom could @@ -43,7 +43,7 @@ struct Mention { * as it's parent. This is necessary for certain functions which need to get * relevant room information. * - * @sa ChatBar, MessageEditComponent, NeoChatRoom + * @sa ChatBar, ChatBarComponent, NeoChatRoom */ class ChatBarCache : public QObject { @@ -165,6 +165,13 @@ public: QString attachmentPath() const; void setAttachmentPath(const QString &attachmentPath); + /** + * @brief Clear all relations in the cache. + * + * This includes relation ID, thread root ID and attachment path. + */ + Q_INVOKABLE void clearRelations(); + /** * @brief Retrieve the mentions for the current chat bar text. */ diff --git a/src/models/messagecontentmodel.cpp b/src/models/messagecontentmodel.cpp index 24633076d..f579a7bf3 100644 --- a/src/models/messagecontentmodel.cpp +++ b/src/models/messagecontentmodel.cpp @@ -93,6 +93,7 @@ void MessageContentModel::initializeModel() if (m_eventId == newEvent->id()) { beginResetModel(); intiializeEvent(newEvent); + resetContent(); endResetModel(); } } diff --git a/src/timeline/CMakeLists.txt b/src/timeline/CMakeLists.txt index 694bd5957..001307bfa 100644 --- a/src/timeline/CMakeLists.txt +++ b/src/timeline/CMakeLists.txt @@ -23,6 +23,7 @@ ecm_add_qml_module(timeline GENERATE_PLUGIN_SOURCE ReplyMessageComponentChooser.qml AuthorComponent.qml AudioComponent.qml + ChatBarComponent.qml CodeComponent.qml EncryptedComponent.qml FileComponent.qml @@ -40,7 +41,6 @@ ecm_add_qml_module(timeline GENERATE_PLUGIN_SOURCE LiveLocationComponent.qml LoadComponent.qml LocationComponent.qml - MessageEditComponent.qml MimeComponent.qml PdfPreviewComponent.qml PollComponent.qml diff --git a/src/timeline/MessageEditComponent.qml b/src/timeline/ChatBarComponent.qml similarity index 74% rename from src/timeline/MessageEditComponent.qml rename to src/timeline/ChatBarComponent.qml index 7d0efbd85..89e8dcbaf 100644 --- a/src/timeline/MessageEditComponent.qml +++ b/src/timeline/ChatBarComponent.qml @@ -11,7 +11,7 @@ import org.kde.neochat import org.kde.neochat.chatbar /** - * @brief A component to show an edit text field for a text message being edited. + * @brief A component to show a chat bar in a message bubble. */ QQC2.TextArea { id: root @@ -20,10 +20,12 @@ QQC2.TextArea { * @brief The NeoChatRoom the delegate is being displayed in. */ required property NeoChatRoom room - onRoomChanged: { - _private.chatBarCache = room.editCache; - _private.chatBarCache.relationIdChanged.connect(_private.updateEditText()); - } + + /** + * @brief The ChatBarCache to use. + */ + required property ChatBarCache chatBarCache + onChatBarCacheChanged: documentHandler.chatBarCache = chatBarCache /** * @brief The ActionsHandler object to use. @@ -33,27 +35,28 @@ QQC2.TextArea { */ required property ActionsHandler actionsHandler - property var minimumHeight: editButtons.height + topPadding + bottomPadding - property var preferredWidth: editTextMetrics.advanceWidth + rightPadding + Kirigami.Units.smallSpacing + Kirigami.Units.gridUnit - /** * @brief The maximum width that the bubble's content can be. */ property real maxContentWidth: -1 Layout.fillWidth: true + Layout.preferredWidth: textMetrics.advanceWidth + rightPadding + Kirigami.Units.smallSpacing + Kirigami.Units.gridUnit Layout.maximumWidth: root.maxContentWidth + Layout.minimumHeight: chatButtons.height + topPadding + bottomPadding - Component.onCompleted: _private.updateEditText() + Component.onCompleted: _private.updateText() - rightPadding: editButtons.width + editButtons.anchors.rightMargin * 2 + topPadding: Kirigami.Units.smallSpacing + bottomPadding: Kirigami.Units.smallSpacing + rightPadding: chatButtons.width + chatButtons.anchors.rightMargin * 2 color: Kirigami.Theme.textColor verticalAlignment: TextEdit.AlignVCenter wrapMode: TextEdit.Wrap onTextChanged: { - _private.chatBarCache.text = text; + root.chatBarCache.text = text; } Keys.onEnterPressed: { @@ -62,7 +65,7 @@ QQC2.TextArea { } else if (event.modifiers & Qt.ShiftModifier) { root.insert(cursorPosition, "\n"); } else { - root.postEdit(); + _private.post(); } } Keys.onReturnPressed: { @@ -71,7 +74,7 @@ QQC2.TextArea { } else if (event.modifiers & Qt.ShiftModifier) { root.insert(cursorPosition, "\n"); } else { - root.postEdit(); + _private.post(); } } Keys.onTabPressed: { @@ -88,11 +91,11 @@ QQC2.TextArea { } /** - * This is anchored like this so that control expands properly as the edited + * This is anchored like this so that control expands properly as the * text grows in length. */ RowLayout { - id: editButtons + id: chatButtons anchors.verticalCenter: root.verticalCenter anchors.right: root.right anchors.rightMargin: Kirigami.Units.smallSpacing @@ -100,10 +103,10 @@ QQC2.TextArea { QQC2.ToolButton { display: QQC2.AbstractButton.IconOnly action: Kirigami.Action { - text: i18nc("@action:button", "Confirm edit") - icon.name: "checkmark" + text: root.chatBarCache.isEditing ? i18nc("@action:button", "Confirm edit") : i18nc("@action:button", "Post message in thread") + icon.name: "document-send" onTriggered: { - root.postEdit(); + _private.post(); } } QQC2.ToolTip.text: text @@ -112,10 +115,10 @@ QQC2.TextArea { QQC2.ToolButton { display: QQC2.AbstractButton.IconOnly action: Kirigami.Action { - text: i18nc("@action:button", "Cancel edit") + text: i18nc("@action:button", "Cancel") icon.name: "dialog-close" onTriggered: { - _private.chatBarCache.editId = ""; + root.chatBarCache.editId = ""; } shortcut: "Escape" } @@ -155,30 +158,28 @@ QQC2.TextArea { } TextMetrics { - id: editTextMetrics + id: textMetrics text: root.text } - function postEdit() { - root.actionsHandler.handleMessageEvent(_private.chatBarCache); - root.clear(); - _private.chatBarCache.editId = ""; - } - QtObject { id: _private - property ChatBarCache chatBarCache - onChatBarCacheChanged: documentHandler.chatBarCache = chatBarCache - function updateEditText() { + function updateText() { // This could possibly be undefined due to some esoteric QtQuick issue. Referencing it somewhere in JS is enough. documentHandler.document; if (chatBarCache?.isEditing && chatBarCache.relationMessage.length > 0) { root.text = chatBarCache.relationMessage; - chatBarCache.updateMentions(root.textDocument, documentHandler); + root.chatBarCache.updateMentions(root.textDocument, documentHandler); root.forceActiveFocus(); - root.cursorPosition = root.length; + root.cursorPosition = root.text.length; } } + + function post() { + root.actionsHandler.handleMessageEvent(root.chatBarCache); + root.clear(); + root.chatBarCache.clearRelations(); + } } } diff --git a/src/timeline/MessageComponentChooser.qml b/src/timeline/MessageComponentChooser.qml index 6d777e591..0bc7cf081 100644 --- a/src/timeline/MessageComponentChooser.qml +++ b/src/timeline/MessageComponentChooser.qml @@ -206,8 +206,9 @@ DelegateChooser { DelegateChoice { roleValue: MessageComponentType.Edit - delegate: MessageEditComponent { + delegate: ChatBarComponent { room: root.room + chatBarCache: room.editCache actionsHandler: root.actionsHandler maxContentWidth: root.maxContentWidth }