File indexing completed on 2024-12-08 04:34:37
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 mainLayout->setSpacing(0); 0047 0048 auto hboxLayout = new QHBoxLayout; 0049 hboxLayout->setObjectName(QStringLiteral("hboxLayout")); 0050 hboxLayout->setContentsMargins(QMargins()); 0051 0052 mainLayout->addLayout(hboxLayout); 0053 0054 mFollowButton->setObjectName(QStringLiteral("mFollowButton")); 0055 mFollowButton->setCheckable(true); 0056 mFollowButton->setAutoRaise(true); 0057 hboxLayout->addWidget(mFollowButton); 0058 connect(mFollowButton, &QToolButton::clicked, this, &ThreadMessageWidget::slotFollowThreadChanged); 0059 0060 mThreadPreview->setObjectName(QStringLiteral("mThreadPreview")); 0061 mThreadPreview->setContextMenuPolicy(Qt::NoContextMenu); 0062 mThreadPreview->setWordWrap(true); 0063 mThreadPreview->setTextInteractionFlags(Qt::TextBrowserInteraction); 0064 hboxLayout->addWidget(mThreadPreview); 0065 0066 #if HAVE_TEXT_TO_SPEECH 0067 mTextToSpeechWidget->setObjectName(QStringLiteral("mTextToSpeechWidget")); 0068 mainLayout->addWidget(mTextToSpeechWidget); 0069 connect(mRoomWidgetBase, &RoomWidgetBase::textToSpeech, mTextToSpeechWidget, &TextEditTextToSpeech::TextToSpeechContainerWidget::say); 0070 #endif 0071 0072 mRoomWidgetBase->setObjectName(QStringLiteral("mRoomWidgetBase")); 0073 mainLayout->addWidget(mRoomWidgetBase); 0074 connect(mRoomWidgetBase, &RoomWidgetBase::createNewDiscussion, this, &ThreadMessageWidget::slotCreateNewDiscussion); 0075 setAcceptDrops(true); 0076 if (mRocketChatAccount) { 0077 initialize(); 0078 } 0079 } 0080 0081 ThreadMessageWidget::~ThreadMessageWidget() = default; 0082 0083 void ThreadMessageWidget::slotCreateNewDiscussion(const QString &messageId, const QString &originalMessage) 0084 { 0085 mRoomWidgetBase->slotCreateNewDiscussion(messageId, originalMessage, QString()); 0086 } 0087 0088 void ThreadMessageWidget::slotFollowThreadChanged(bool clicked) 0089 { 0090 if (clicked) { 0091 auto job = new RocketChatRestApi::UnFollowMessageJob(this); 0092 job->setMessageId(mThreadMessageId); 0093 mRocketChatAccount->restApi()->initializeRestApiJob(job); 0094 connect(job, &RocketChatRestApi::UnFollowMessageJob::unFollowMessageDone, this, [this]() { 0095 updateFollowThreadIcon(false); // TODO verify it 0096 }); 0097 if (!job->start()) { 0098 qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start UnFollowMessageJob job"; 0099 } 0100 } else { 0101 auto job = new RocketChatRestApi::FollowMessageJob(this); 0102 job->setMessageId(mThreadMessageId); 0103 mRocketChatAccount->restApi()->initializeRestApiJob(job); 0104 connect(job, &RocketChatRestApi::FollowMessageJob::followMessageDone, this, [this]() { 0105 updateFollowThreadIcon(true); // TODO verify it 0106 }); 0107 if (!job->start()) { 0108 qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start FollowMessageJob job"; 0109 } 0110 } 0111 } 0112 0113 void ThreadMessageWidget::updateFollowThreadIcon(bool followThread) 0114 { 0115 mFollowButton->setIcon(followThread ? QIcon::fromTheme(QStringLiteral("notifications")) : QIcon::fromTheme(QStringLiteral("notifications-disabled"))); 0116 mFollowButton->setToolTip(followThread ? i18n("Follow Message") : i18n("Unfollow Message")); 0117 } 0118 0119 void ThreadMessageWidget::setThreadMessageInfo(const ThreadMessageWidget::ThreadMessageInfo &info) 0120 { 0121 updateFollowThreadIcon(info.threadIsFollowing); 0122 mFollowButton->setChecked(!info.threadIsFollowing); 0123 0124 mRoom = info.room; 0125 if (mRoom) { 0126 mRoomWidgetBase->messageLineWidget()->setRoomId(mRoom->roomId()); 0127 mRoomWidgetBase->messageListView()->setRoom(mRoom); 0128 mRoomWidgetBase->updateRoomReadOnly(mRoom); 0129 } 0130 mThreadPreview->setText(info.threadMessagePreview); 0131 if (mThreadMessageId != info.threadMessageId) { 0132 mThreadMessageId = info.threadMessageId; 0133 mRocketChatAccount->getThreadMessages(mThreadMessageId, info.messageThread); 0134 mRoomWidgetBase->messageListView()->setModel(mRocketChatAccount->threadMessageModel()); 0135 mRoomWidgetBase->messageLineWidget()->setThreadMessageId(mThreadMessageId, {}, true); 0136 } 0137 } 0138 0139 void ThreadMessageWidget::initialize() 0140 { 0141 mRoomWidgetBase->setCurrentRocketChatAccount(mRocketChatAccount); 0142 mRoomWidgetBase->messageLineWidget()->setCurrentRocketChatAccount(mRocketChatAccount, true); 0143 mRoomWidgetBase->messageListView()->setCurrentRocketChatAccount(mRocketChatAccount); 0144 // When we switch we need to update it. 0145 mRoomWidgetBase->messageLineWidget()->slotPublicSettingChanged(); 0146 mRoomWidgetBase->messageLineWidget()->slotOwnUserPreferencesChanged(); 0147 } 0148 0149 void ThreadMessageWidget::dragEnterEvent(QDragEnterEvent *event) 0150 { 0151 const QMimeData *mimeData = event->mimeData(); 0152 if (mimeData->hasUrls()) { 0153 event->accept(); 0154 } 0155 } 0156 0157 void ThreadMessageWidget::dropEvent(QDropEvent *event) 0158 { 0159 // Don't allow to drop element when it's blocked 0160 if (mRoom && mRoom->roomIsBlocked()) { 0161 return; 0162 } 0163 const QMimeData *mimeData = event->mimeData(); 0164 if (mimeData->hasUrls()) { 0165 mRoomWidgetBase->messageLineWidget()->handleMimeData(mimeData); 0166 } 0167 } 0168 0169 #include "moc_threadmessagewidget.cpp"