Add button to thread to reply

![image](/uploads/bf2b6857f797480b429db02c5d01a4f7/image.png){width=254 height=147}
This commit is contained in:
James Graham
2024-12-24 17:14:00 +00:00
parent 0f79c04d93
commit fe7cf0a595
9 changed files with 77 additions and 10 deletions

View File

@@ -53,6 +53,7 @@ public:
LinkPreview, /**< A preview of a URL in the message. */
LinkPreviewLoad, /**< A loading dialog for a link preview. */
ChatBar, /**< A text edit for editing a message. */
ReplyButton, /**< A button to reply in the current thread. */
Verification, /**< A user verification session start message. */
Loading, /**< The component is loading. */
Other, /**< Anything that cannot be classified as another type. */

View File

@@ -405,6 +405,7 @@ QHash<int, QByteArray> MessageContentModel::roleNames() const
roles[ReplyEventIdRole] = "replyEventId";
roles[ReplyAuthorRole] = "replyAuthor";
roles[ReplyContentModelRole] = "replyContentModel";
roles[ThreadRootRole] = "threadRoot";
roles[LinkPreviewerRole] = "linkPreviewer";
roles[ChatBarCacheRole] = "chatBarCache";
return roles;

View File

@@ -62,6 +62,8 @@ public:
ReplyAuthorRole, /**< The author of the event that was replied to. */
ReplyContentModelRole, /**< The MessageContentModel for the reply event. */
ThreadRootRole, /**< The thread root event ID for the event. */
LinkPreviewerRole, /**< The link preview details. */
ChatBarCacheRole, /**< The ChatBarCache to use. */
};

View File

@@ -178,8 +178,14 @@ QVariant ThreadChatBarModel::data(const QModelIndex &idx, int role) const
return {};
}
const auto threadModel = dynamic_cast<ThreadModel *>(parent());
if (threadModel == nullptr) {
qWarning() << "ThreadChatBarModel created with incorrect parent, a ThreadModel must be set as the parent on creation.";
return {};
}
if (role == ComponentTypeRole) {
return MessageComponentType::ChatBar;
return m_room->threadCache()->threadId() == threadModel->threadRootId() ? MessageComponentType::ChatBar : MessageComponentType::ReplyButton;
}
if (role == ChatBarCacheRole) {
if (m_room == nullptr) {
@@ -187,20 +193,16 @@ QVariant ThreadChatBarModel::data(const QModelIndex &idx, int role) const
}
return QVariant::fromValue<ChatBarCache *>(m_room->threadCache());
}
if (role == ThreadRootRole) {
return threadModel->threadRootId();
}
return {};
}
int ThreadChatBarModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
if (m_room == nullptr) {
return 0;
}
const auto threadModel = dynamic_cast<ThreadModel *>(this->parent());
if (threadModel != nullptr) {
return m_room->threadCache()->threadId() == threadModel->threadRootId() ? 1 : 0;
}
return 0;
return 1;
}
QHash<int, QByteArray> ThreadChatBarModel::roleNames() const
@@ -208,6 +210,7 @@ QHash<int, QByteArray> ThreadChatBarModel::roleNames() const
return {
{ComponentTypeRole, "componentType"},
{ChatBarCacheRole, "chatBarCache"},
{ThreadRootRole, "threadRoot"},
};
}

View File

@@ -41,6 +41,7 @@ public:
enum Roles {
ComponentTypeRole = MessageContentModel::ComponentTypeRole, /**< The type of component to visualise the message. */
ChatBarCacheRole = MessageContentModel::ChatBarCacheRole, /**< The ChatBarCache to use. */
ThreadRootRole = MessageContentModel::ThreadRootRole, /**< The thread root event ID for the thread. */
};
Q_ENUM(Roles)

View File

@@ -44,7 +44,7 @@ QQC2.Control {
leftPadding: 0
rightPadding: 0
visible: (root.hovered || root.showActions || showActionsTimer.running) && !Kirigami.Settings.isMobile
visible: (root.hovered || root.showActions || showActionsTimer.running) && !Kirigami.Settings.isMobile && (!root.delegate.isThreaded || !NeoChatConfig.threads)
onVisibleChanged: {
if (visible) {
// HACK: delay disapearing by 200ms, otherwise this can create some glitches

View File

@@ -46,6 +46,7 @@ ecm_add_qml_module(timeline GENERATE_PLUGIN_SOURCE
PollComponent.qml
QuoteComponent.qml
ReplyAuthorComponent.qml
ReplyButtonComponent.qml
ReplyComponent.qml
StateComponent.qml
TextComponent.qml

View File

@@ -210,6 +210,14 @@ DelegateChooser {
}
}
DelegateChoice {
roleValue: MessageComponentType.ReplyButton
delegate: ReplyButtonComponent {
room: root.room
maxContentWidth: root.maxContentWidth
}
}
DelegateChoice {
roleValue: MessageComponentType.Verification
delegate: MimeComponent {

View File

@@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
// 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.delegates as Delegates
import org.kde.neochat
import org.kde.neochat.chatbar
/**
* @brief A component to show a reply button for threads in a message bubble.
*/
Delegates.RoundedItemDelegate {
id: root
/**
* @brief The NeoChatRoom the delegate is being displayed in.
*/
required property NeoChatRoom room
/**
* @brief The thread root ID.
*/
required property string threadRoot
/**
* @brief The maximum width that the bubble's content can be.
*/
property real maxContentWidth: -1
Layout.fillWidth: true
Layout.maximumWidth: root.maxContentWidth
leftInset: 0
rightInset: 0
icon.name: "mail-reply-custom"
text: i18nc("@action:button", "Reply")
onClicked: {
root.room.threadCache.replyId = "";
root.room.threadCache.threadId = root.threadRoot;
root.room.mainCache.clearRelations();
root.room.editCache.clearRelations();
}
}