File indexing completed on 2025-01-12 10:33:24
0001 /* 0002 SPDX-FileCopyrightText: 2020-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "threadmessagewidget.h" 0008 #include "chat/followmessagejob.h" 0009 #include "chat/unfollowmessagejob.h" 0010 #include "connection.h" 0011 #include "rocketchataccount.h" 0012 #include "room.h" 0013 #include "room/messagelinewidget.h" 0014 #include "room/messagelistview.h" 0015 #include "room/roomwidgetbase.h" 0016 #include "ruqolawidgets_debug.h" 0017 0018 #include <KLocalizedString> 0019 0020 #include <QDragEnterEvent> 0021 #include <QDropEvent> 0022 #include <QLabel> 0023 #include <QMimeData> 0024 #include <QToolButton> 0025 #include <QVBoxLayout> 0026 0027 #include "config-ruqola.h" 0028 0029 #if HAVE_TEXT_TO_SPEECH 0030 #include <TextEditTextToSpeech/TextToSpeechContainerWidget> 0031 #endif 0032 0033 ThreadMessageWidget::ThreadMessageWidget(RocketChatAccount *account, QWidget *parent) 0034 : QWidget(parent) 0035 , mThreadPreview(new QLabel(this)) 0036 , mRoomWidgetBase(new RoomWidgetBase(MessageListView::Mode::ThreadEditing, this)) 0037 , mRocketChatAccount(account) 0038 , mFollowButton(new QToolButton(this)) 0039 #if HAVE_TEXT_TO_SPEECH 0040 , mTextToSpeechWidget(new TextEditTextToSpeech::TextToSpeechContainerWidget(this)) 0041 #endif 0042 { 0043 auto mainLayout = new QVBoxLayout(this); 0044 mainLayout->setObjectName(QStringLiteral("mainLayout")); 0045 mainLayout->setContentsMargins({}); 0046 #if QT_VERSION > QT_VERSION_CHECK(6, 0, 0) 0047 mainLayout->setSpacing(0); 0048 #endif 0049 0050 auto hboxLayout = new QHBoxLayout; 0051 hboxLayout->setObjectName(QStringLiteral("hboxLayout")); 0052 hboxLayout->setContentsMargins(QMargins()); 0053 0054 mainLayout->addLayout(hboxLayout); 0055 0056 mFollowButton->setObjectName(QStringLiteral("mFollowButton")); 0057 mFollowButton->setCheckable(true); 0058 mFollowButton->setAutoRaise(true); 0059 hboxLayout->addWidget(mFollowButton); 0060 connect(mFollowButton, &QToolButton::clicked, this, &ThreadMessageWidget::slotFollowThreadChanged); 0061 0062 mThreadPreview->setObjectName(QStringLiteral("mThreadPreview")); 0063 mThreadPreview->setContextMenuPolicy(Qt::NoContextMenu); 0064 mThreadPreview->setWordWrap(true); 0065 mThreadPreview->setTextInteractionFlags(Qt::TextBrowserInteraction); 0066 hboxLayout->addWidget(mThreadPreview); 0067 0068 #if HAVE_TEXT_TO_SPEECH 0069 mTextToSpeechWidget->setObjectName(QStringLiteral("mTextToSpeechWidget")); 0070 mainLayout->addWidget(mTextToSpeechWidget); 0071 connect(mRoomWidgetBase, &RoomWidgetBase::textToSpeech, mTextToSpeechWidget, &TextEditTextToSpeech::TextToSpeechContainerWidget::say); 0072 #endif 0073 0074 mRoomWidgetBase->setObjectName(QStringLiteral("mRoomWidgetBase")); 0075 mainLayout->addWidget(mRoomWidgetBase); 0076 connect(mRoomWidgetBase, &RoomWidgetBase::createNewDiscussion, this, &ThreadMessageWidget::slotCreateNewDiscussion); 0077 setAcceptDrops(true); 0078 if (mRocketChatAccount) { 0079 initialize(); 0080 } 0081 } 0082 0083 ThreadMessageWidget::~ThreadMessageWidget() = default; 0084 0085 void ThreadMessageWidget::slotCreateNewDiscussion(const QString &messageId, const QString &originalMessage) 0086 { 0087 mRoomWidgetBase->slotCreateNewDiscussion(messageId, originalMessage, QString()); 0088 } 0089 0090 void ThreadMessageWidget::slotFollowThreadChanged(bool clicked) 0091 { 0092 if (clicked) { 0093 auto job = new RocketChatRestApi::UnFollowMessageJob(this); 0094 job->setMessageId(mThreadMessageId); 0095 mRocketChatAccount->restApi()->initializeRestApiJob(job); 0096 connect(job, &RocketChatRestApi::UnFollowMessageJob::unFollowMessageDone, this, [this]() { 0097 updateFollowThreadIcon(false); // TODO verify it 0098 }); 0099 if (!job->start()) { 0100 qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start UnFollowMessageJob job"; 0101 } 0102 } else { 0103 auto job = new RocketChatRestApi::FollowMessageJob(this); 0104 job->setMessageId(mThreadMessageId); 0105 mRocketChatAccount->restApi()->initializeRestApiJob(job); 0106 connect(job, &RocketChatRestApi::FollowMessageJob::followMessageDone, this, [this]() { 0107 updateFollowThreadIcon(true); // TODO verify it 0108 }); 0109 if (!job->start()) { 0110 qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start FollowMessageJob job"; 0111 } 0112 } 0113 } 0114 0115 void ThreadMessageWidget::updateFollowThreadIcon(bool followThread) 0116 { 0117 mFollowButton->setIcon(followThread ? QIcon::fromTheme(QStringLiteral("notifications")) : QIcon::fromTheme(QStringLiteral("notifications-disabled"))); 0118 mFollowButton->setToolTip(followThread ? i18n("Follow Message") : i18n("Unfollow Message")); 0119 } 0120 0121 void ThreadMessageWidget::setThreadMessageInfo(const ThreadMessageWidget::ThreadMessageInfo &info) 0122 { 0123 updateFollowThreadIcon(info.threadIsFollowing); 0124 mFollowButton->setChecked(!info.threadIsFollowing); 0125 0126 mRoom = info.room; 0127 if (mRoom) { 0128 mRoomWidgetBase->messageLineWidget()->setRoomId(mRoom->roomId()); 0129 mRoomWidgetBase->messageListView()->setRoom(mRoom); 0130 mRoomWidgetBase->updateRoomReadOnly(mRoom); 0131 } 0132 mThreadPreview->setText(info.threadMessagePreview); 0133 if (mThreadMessageId != info.threadMessageId) { 0134 mThreadMessageId = info.threadMessageId; 0135 mRocketChatAccount->getThreadMessages(mThreadMessageId, info.messageThread); 0136 mRoomWidgetBase->messageListView()->setModel(mRocketChatAccount->threadMessageModel()); 0137 mRoomWidgetBase->messageLineWidget()->setThreadMessageId(mThreadMessageId, {}, true); 0138 } 0139 } 0140 0141 void ThreadMessageWidget::initialize() 0142 { 0143 mRoomWidgetBase->setCurrentRocketChatAccount(mRocketChatAccount); 0144 mRoomWidgetBase->messageLineWidget()->setCurrentRocketChatAccount(mRocketChatAccount, true); 0145 mRoomWidgetBase->messageListView()->setCurrentRocketChatAccount(mRocketChatAccount); 0146 // When we switch we need to update it. 0147 mRoomWidgetBase->messageLineWidget()->slotPublicSettingChanged(); 0148 mRoomWidgetBase->messageLineWidget()->slotOwnUserPreferencesChanged(); 0149 } 0150 0151 void ThreadMessageWidget::dragEnterEvent(QDragEnterEvent *event) 0152 { 0153 const QMimeData *mimeData = event->mimeData(); 0154 if (mimeData->hasUrls()) { 0155 event->accept(); 0156 } 0157 } 0158 0159 void ThreadMessageWidget::dropEvent(QDropEvent *event) 0160 { 0161 // Don't allow to drop element when it's blocked 0162 if (mRoom && mRoom->roomIsBlocked()) { 0163 return; 0164 } 0165 const QMimeData *mimeData = event->mimeData(); 0166 if (mimeData->hasUrls()) { 0167 mRoomWidgetBase->messageLineWidget()->handleMimeData(mimeData); 0168 } 0169 } 0170 0171 #include "moc_threadmessagewidget.cpp"