File indexing completed on 2025-01-12 04:34:10

0001 /*
0002    SPDX-FileCopyrightText: 2023-2024 Laurent Montel <montel.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "moderationconsoletreewidget.h"
0008 #include "administratordialog/moderationconsole/moderationmessagesdialog.h"
0009 #include "connection.h"
0010 #include "misc/searchwithdelaylineedit.h"
0011 #include "model/commonmessagefilterproxymodel.h"
0012 #include "model/moderationmessagesmodel.h"
0013 #include "model/moderationmodel.h"
0014 #include "model/searchtreebasefilterproxymodel.h"
0015 #include "moderation/moderationdismissreportsjob.h"
0016 #include "moderation/moderationreportsbyusersjob.h"
0017 #include "moderation/moderationuserdeletereportedmessagesjob.h"
0018 #include "moderation/moderationuserreportedmessagesjob.h"
0019 #include "rocketchataccount.h"
0020 #include "ruqolawidgets_debug.h"
0021 #include <KLocalizedString>
0022 #include <KMessageBox>
0023 #include <QLabel>
0024 #include <QMenu>
0025 #include <QPointer>
0026 #include <QTreeView>
0027 
0028 ModerationConsoleTreeWidget::ModerationConsoleTreeWidget(RocketChatAccount *account, QWidget *parent)
0029     : SearchTreeBaseWidget(account, parent)
0030     , mCommonMessagesModel(new ModerationMessagesModel(account, this))
0031 {
0032     mCommonMessageFilterProxyModel = new CommonMessageFilterProxyModel(mCommonMessagesModel, this);
0033     mModel = new ModerationModel(this);
0034     mModel->setObjectName(QStringLiteral("mModel"));
0035     mSearchLineEdit->setPlaceholderText(i18n("Search moderation message..."));
0036 
0037     mProxyModelModel = new SearchTreeBaseFilterProxyModel(mModel, this);
0038     mProxyModelModel->setObjectName(QStringLiteral("mProxyModelModel"));
0039     mTreeView->setModel(mProxyModelModel);
0040     connect(this, &ModerationConsoleTreeWidget::doubleClicked, this, &ModerationConsoleTreeWidget::slotShowMessages);
0041     connect(this, &ModerationConsoleTreeWidget::refreshList, this, [this]() {
0042         slotLoadElements();
0043     });
0044     hideColumns();
0045     connectModel();
0046 }
0047 
0048 ModerationConsoleTreeWidget::~ModerationConsoleTreeWidget() = default;
0049 
0050 void ModerationConsoleTreeWidget::setModerationRanges(const AdministratorModerationRangeWidget::DateTimeRange &range)
0051 {
0052     mModerationRanges = range;
0053     slotLoadElements();
0054     // qDebug() << " range " << range;
0055 }
0056 
0057 void ModerationConsoleTreeWidget::updateLabel()
0058 {
0059     mLabelResultSearch->setText(mModel->total() == 0 ? i18n("No moderation message found") : displayShowMessage());
0060 }
0061 
0062 QString ModerationConsoleTreeWidget::displayShowMessage() const
0063 {
0064     QString displayMessageStr = i18np("%1 moderation message (Total: %2)", "%1 moderation messages (Total: %2)", mModel->rowCount(), mModel->total());
0065     if (!mModel->hasFullList()) {
0066         displayMessageStr += clickableStr();
0067     }
0068     return displayMessageStr;
0069 }
0070 
0071 void ModerationConsoleTreeWidget::slotLoadElements(int offset, int count, const QString &searchName)
0072 {
0073     auto job = new RocketChatRestApi::ModerationReportsByUsersJob(this);
0074 
0075     RocketChatRestApi::ModerationReportsByUsersJob::ModerationReportsByUsersInfo info;
0076     info.mOldest = mModerationRanges.fromDate;
0077     info.mLatest = mModerationRanges.toDate;
0078     info.mSelector = searchName;
0079     RocketChatRestApi::QueryParameters parameters;
0080     //    QMap<QString, RocketChatRestApi::QueryParameters::SortOrder> map;
0081     //    map.insert(QStringLiteral("name"), RocketChatRestApi::QueryParameters::SortOrder::Ascendant);
0082     //    parameters.setSorting(map);
0083     if (offset != -1) {
0084         parameters.setOffset(offset);
0085     }
0086     if (count != -1) {
0087         parameters.setCount(count);
0088     }
0089 
0090     job->setQueryParameters(parameters);
0091     if (info.isValid()) {
0092         job->setModerationReportsByUsersInfo(info);
0093     }
0094 
0095     mRocketChatAccount->restApi()->initializeRestApiJob(job);
0096     if (offset != -1) {
0097         connect(job, &RocketChatRestApi::ModerationReportsByUsersJob::moderationReportByUserDone, this, &ModerationConsoleTreeWidget::slotLoadMoreElementDone);
0098     } else {
0099         connect(job, &RocketChatRestApi::ModerationReportsByUsersJob::moderationReportByUserDone, this, &ModerationConsoleTreeWidget::slotSearchDone);
0100     }
0101     if (!job->start()) {
0102         qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start ModerationReportsByUsersJob job";
0103     }
0104 }
0105 
0106 void ModerationConsoleTreeWidget::slotShowMessages(const QModelIndex &newModelIndex)
0107 {
0108     if (!newModelIndex.isValid()) {
0109         return;
0110     }
0111     auto job = new RocketChatRestApi::ModerationUserReportedMessagesJob(this);
0112     mRocketChatAccount->restApi()->initializeRestApiJob(job);
0113     const QModelIndex modelIndex = mModel->index(newModelIndex.row(), ModerationModel::UserId);
0114     job->setReportedMessageFromUserId(modelIndex.data().toString());
0115     connect(job,
0116             &RocketChatRestApi::ModerationUserReportedMessagesJob::moderationUserReportedMessagesDone,
0117             this,
0118             &ModerationConsoleTreeWidget::slotShowReportedMessages);
0119     if (!job->start()) {
0120         qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start ModerationReportsByUsersJob job";
0121     }
0122 }
0123 
0124 void ModerationConsoleTreeWidget::slotCustomContextMenuRequested(const QPoint &pos)
0125 {
0126     const QModelIndex index = mTreeView->indexAt(pos);
0127     if (index.isValid()) {
0128         QMenu menu(this);
0129         const QModelIndex newModelIndex = mProxyModelModel->mapToSource(index);
0130         menu.addAction(QIcon::fromTheme(QStringLiteral("visibility")), i18n("See messages"), this, [this, newModelIndex]() {
0131             slotShowMessages(newModelIndex);
0132         });
0133         menu.addSeparator();
0134 
0135         menu.addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("Dismiss reports"), this, [this, newModelIndex]() {
0136             const QModelIndex modelIndex = mModel->index(newModelIndex.row(), ModerationModel::UserId);
0137             slotDismissReport(modelIndex);
0138         });
0139         menu.addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("Delete all Messages"), this, [this, newModelIndex]() {
0140             const QModelIndex modelIndex = mModel->index(newModelIndex.row(), ModerationModel::UserId);
0141             slotDeleteAllMessages(modelIndex);
0142         });
0143         menu.exec(mTreeView->viewport()->mapToGlobal(pos));
0144     }
0145 }
0146 
0147 void ModerationConsoleTreeWidget::slotShowReportedMessages(const QJsonObject &obj)
0148 {
0149     mCommonMessagesModel->parse(obj);
0150     ModerationMessagesDialog dlg(mRocketChatAccount, this);
0151     dlg.setModel(mCommonMessageFilterProxyModel);
0152     dlg.exec();
0153 }
0154 
0155 void ModerationConsoleTreeWidget::slotDismissReport(const QModelIndex &index)
0156 {
0157     if (KMessageBox::questionTwoActions(this,
0158                                         i18n("Are you sure you want to dismiss and delete all reports for this user's messages? This action cannot be undone."),
0159                                         i18nc("@title:window", "Dismiss"),
0160                                         KStandardGuiItem::remove(),
0161                                         KStandardGuiItem::cancel())
0162         == KMessageBox::ButtonCode::PrimaryAction) {
0163         auto job = new RocketChatRestApi::ModerationDismissReportsJob(this);
0164         mRocketChatAccount->restApi()->initializeRestApiJob(job);
0165         const QModelIndex modelIndex = mModel->index(index.row(), ModerationModel::UserId);
0166         job->setUserIdForMessages(modelIndex.data().toString());
0167         connect(job, &RocketChatRestApi::ModerationDismissReportsJob::moderationDismissReportsDone, this, [this]() {
0168             Q_EMIT refreshList();
0169         });
0170         if (!job->start()) {
0171             qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start ModerationDismissReportsJob job";
0172         }
0173     }
0174 }
0175 
0176 void ModerationConsoleTreeWidget::slotDeleteAllMessages(const QModelIndex &index)
0177 {
0178     if (KMessageBox::questionTwoActions(this,
0179                                         i18n("Are you sure you want to delete all reported messages from this user?\n"
0180                                              "The messages will be deleted from the message history and no one will be able to see it.\n"
0181                                              "This action cannot be undone."),
0182                                         i18nc("@title:window", "Delete All Messages"),
0183                                         KStandardGuiItem::remove(),
0184                                         KStandardGuiItem::cancel())
0185         == KMessageBox::ButtonCode::PrimaryAction) {
0186         auto job = new RocketChatRestApi::ModerationUserDeleteReportedMessagesJob(this);
0187         mRocketChatAccount->restApi()->initializeRestApiJob(job);
0188         const QModelIndex modelIndex = mModel->index(index.row(), ModerationModel::UserId);
0189         job->setUserIdForMessages(modelIndex.data().toString());
0190         connect(job, &RocketChatRestApi::ModerationUserDeleteReportedMessagesJob::moderationUserDeleteReportedMessagesDone, this, [this]() {
0191             Q_EMIT refreshList();
0192         });
0193         if (!job->start()) {
0194             qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start ModerationUserDeleteReportedMessagesJob job";
0195         }
0196     }
0197 }
0198 
0199 #include "moc_moderationconsoletreewidget.cpp"