Add button to thread to reply
{width=254 height=147}
This commit is contained in:
@@ -53,6 +53,7 @@ public:
|
|||||||
LinkPreview, /**< A preview of a URL in the message. */
|
LinkPreview, /**< A preview of a URL in the message. */
|
||||||
LinkPreviewLoad, /**< A loading dialog for a link preview. */
|
LinkPreviewLoad, /**< A loading dialog for a link preview. */
|
||||||
ChatBar, /**< A text edit for editing a message. */
|
ChatBar, /**< A text edit for editing a message. */
|
||||||
|
ReplyButton, /**< A button to reply in the current thread. */
|
||||||
Verification, /**< A user verification session start message. */
|
Verification, /**< A user verification session start message. */
|
||||||
Loading, /**< The component is loading. */
|
Loading, /**< The component is loading. */
|
||||||
Other, /**< Anything that cannot be classified as another type. */
|
Other, /**< Anything that cannot be classified as another type. */
|
||||||
|
|||||||
@@ -405,6 +405,7 @@ QHash<int, QByteArray> MessageContentModel::roleNames() const
|
|||||||
roles[ReplyEventIdRole] = "replyEventId";
|
roles[ReplyEventIdRole] = "replyEventId";
|
||||||
roles[ReplyAuthorRole] = "replyAuthor";
|
roles[ReplyAuthorRole] = "replyAuthor";
|
||||||
roles[ReplyContentModelRole] = "replyContentModel";
|
roles[ReplyContentModelRole] = "replyContentModel";
|
||||||
|
roles[ThreadRootRole] = "threadRoot";
|
||||||
roles[LinkPreviewerRole] = "linkPreviewer";
|
roles[LinkPreviewerRole] = "linkPreviewer";
|
||||||
roles[ChatBarCacheRole] = "chatBarCache";
|
roles[ChatBarCacheRole] = "chatBarCache";
|
||||||
return roles;
|
return roles;
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ public:
|
|||||||
ReplyAuthorRole, /**< The author of the event that was replied to. */
|
ReplyAuthorRole, /**< The author of the event that was replied to. */
|
||||||
ReplyContentModelRole, /**< The MessageContentModel for the reply event. */
|
ReplyContentModelRole, /**< The MessageContentModel for the reply event. */
|
||||||
|
|
||||||
|
ThreadRootRole, /**< The thread root event ID for the event. */
|
||||||
|
|
||||||
LinkPreviewerRole, /**< The link preview details. */
|
LinkPreviewerRole, /**< The link preview details. */
|
||||||
ChatBarCacheRole, /**< The ChatBarCache to use. */
|
ChatBarCacheRole, /**< The ChatBarCache to use. */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -178,8 +178,14 @@ QVariant ThreadChatBarModel::data(const QModelIndex &idx, int role) const
|
|||||||
return {};
|
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) {
|
if (role == ComponentTypeRole) {
|
||||||
return MessageComponentType::ChatBar;
|
return m_room->threadCache()->threadId() == threadModel->threadRootId() ? MessageComponentType::ChatBar : MessageComponentType::ReplyButton;
|
||||||
}
|
}
|
||||||
if (role == ChatBarCacheRole) {
|
if (role == ChatBarCacheRole) {
|
||||||
if (m_room == nullptr) {
|
if (m_room == nullptr) {
|
||||||
@@ -187,20 +193,16 @@ QVariant ThreadChatBarModel::data(const QModelIndex &idx, int role) const
|
|||||||
}
|
}
|
||||||
return QVariant::fromValue<ChatBarCache *>(m_room->threadCache());
|
return QVariant::fromValue<ChatBarCache *>(m_room->threadCache());
|
||||||
}
|
}
|
||||||
|
if (role == ThreadRootRole) {
|
||||||
|
return threadModel->threadRootId();
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
int ThreadChatBarModel::rowCount(const QModelIndex &parent) const
|
int ThreadChatBarModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent)
|
Q_UNUSED(parent)
|
||||||
if (m_room == nullptr) {
|
return 1;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const auto threadModel = dynamic_cast<ThreadModel *>(this->parent());
|
|
||||||
if (threadModel != nullptr) {
|
|
||||||
return m_room->threadCache()->threadId() == threadModel->threadRootId() ? 1 : 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, QByteArray> ThreadChatBarModel::roleNames() const
|
QHash<int, QByteArray> ThreadChatBarModel::roleNames() const
|
||||||
@@ -208,6 +210,7 @@ QHash<int, QByteArray> ThreadChatBarModel::roleNames() const
|
|||||||
return {
|
return {
|
||||||
{ComponentTypeRole, "componentType"},
|
{ComponentTypeRole, "componentType"},
|
||||||
{ChatBarCacheRole, "chatBarCache"},
|
{ChatBarCacheRole, "chatBarCache"},
|
||||||
|
{ThreadRootRole, "threadRoot"},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public:
|
|||||||
enum Roles {
|
enum Roles {
|
||||||
ComponentTypeRole = MessageContentModel::ComponentTypeRole, /**< The type of component to visualise the message. */
|
ComponentTypeRole = MessageContentModel::ComponentTypeRole, /**< The type of component to visualise the message. */
|
||||||
ChatBarCacheRole = MessageContentModel::ChatBarCacheRole, /**< The ChatBarCache to use. */
|
ChatBarCacheRole = MessageContentModel::ChatBarCacheRole, /**< The ChatBarCache to use. */
|
||||||
|
ThreadRootRole = MessageContentModel::ThreadRootRole, /**< The thread root event ID for the thread. */
|
||||||
};
|
};
|
||||||
Q_ENUM(Roles)
|
Q_ENUM(Roles)
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ QQC2.Control {
|
|||||||
leftPadding: 0
|
leftPadding: 0
|
||||||
rightPadding: 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: {
|
onVisibleChanged: {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
// HACK: delay disapearing by 200ms, otherwise this can create some glitches
|
// HACK: delay disapearing by 200ms, otherwise this can create some glitches
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ ecm_add_qml_module(timeline GENERATE_PLUGIN_SOURCE
|
|||||||
PollComponent.qml
|
PollComponent.qml
|
||||||
QuoteComponent.qml
|
QuoteComponent.qml
|
||||||
ReplyAuthorComponent.qml
|
ReplyAuthorComponent.qml
|
||||||
|
ReplyButtonComponent.qml
|
||||||
ReplyComponent.qml
|
ReplyComponent.qml
|
||||||
StateComponent.qml
|
StateComponent.qml
|
||||||
TextComponent.qml
|
TextComponent.qml
|
||||||
|
|||||||
@@ -210,6 +210,14 @@ DelegateChooser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DelegateChoice {
|
||||||
|
roleValue: MessageComponentType.ReplyButton
|
||||||
|
delegate: ReplyButtonComponent {
|
||||||
|
room: root.room
|
||||||
|
maxContentWidth: root.maxContentWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DelegateChoice {
|
DelegateChoice {
|
||||||
roleValue: MessageComponentType.Verification
|
roleValue: MessageComponentType.Verification
|
||||||
delegate: MimeComponent {
|
delegate: MimeComponent {
|
||||||
|
|||||||
50
src/timeline/ReplyButtonComponent.qml
Normal file
50
src/timeline/ReplyButtonComponent.qml
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user