File indexing completed on 2024-05-12 16:27:40

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"