File indexing completed on 2024-12-08 04:34:20

0001 /*
0002    SPDX-FileCopyrightText: 2021-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "directorywidget.h"
0008 #include "connection.h"
0009 #include "misc/directoryjob.h"
0010 #include "misc/searchwithdelaylineedit.h"
0011 #include "model/directoryroomsmodel.h"
0012 #include "model/directoryroomsproxymodel.h"
0013 #include "model/directoryteamsmodel.h"
0014 #include "model/directoryteamsproxymodel.h"
0015 #include "model/directoryusersmodel.h"
0016 #include "model/directoryusersproxymodel.h"
0017 #include "model/searchtreebasefilterproxymodel.h"
0018 #include "rocketchataccount.h"
0019 #include "ruqolawidgets_debug.h"
0020 #include <KLocalizedString>
0021 #include <QLabel>
0022 #include <QMenu>
0023 #include <QShowEvent>
0024 #include <QTreeView>
0025 
0026 DirectoryWidget::DirectoryWidget(RocketChatAccount *account, DirectoryType type, QWidget *parent)
0027     : SearchTreeBaseWidget(account, parent)
0028     , mType(type)
0029 {
0030     switch (mType) {
0031     case Room:
0032         mSearchLineEdit->setPlaceholderText(i18n("Search channels..."));
0033         mModel = new DirectoryRoomsModel(this);
0034         mProxyModelModel = new DirectoryRoomsProxyModel(mModel, this);
0035         break;
0036     case User:
0037         mSearchLineEdit->setPlaceholderText(i18n("Search users..."));
0038         mModel = new DirectoryUsersModel(this);
0039         mProxyModelModel = new DirectoryUsersProxyModel(mModel, this);
0040         break;
0041     case Team:
0042         mSearchLineEdit->setPlaceholderText(i18n("Search teams..."));
0043         mModel = new DirectoryTeamsModel(this);
0044         mProxyModelModel = new DirectoryTeamsProxyModel(mModel, this);
0045         break;
0046     case Unknown:
0047         break;
0048     }
0049     mTreeView->setModel(mProxyModelModel);
0050     connect(mTreeView, &QTreeView::doubleClicked, this, [this](const QModelIndex &index) {
0051         if (index.isValid()) {
0052             const QModelIndex i = mProxyModelModel->mapToSource(index);
0053             slotOpen(i);
0054         }
0055     });
0056     hideColumns();
0057     connectModel();
0058 }
0059 
0060 DirectoryWidget::~DirectoryWidget() = default;
0061 
0062 void DirectoryWidget::slotCustomContextMenuRequested(const QPoint &pos)
0063 {
0064     QMenu menu(this);
0065     const QModelIndex index = mTreeView->indexAt(pos);
0066     if (index.isValid()) {
0067         const QModelIndex i = mProxyModelModel->mapToSource(index);
0068         menu.addAction(i18n("Open..."), this, [this, i]() {
0069             slotOpen(i);
0070         });
0071     }
0072     menu.exec(mTreeView->viewport()->mapToGlobal(pos));
0073 }
0074 
0075 void DirectoryWidget::slotOpen(const QModelIndex &index)
0076 {
0077     switch (mType) {
0078     case Room: {
0079         QModelIndex modelIndex = mModel->index(index.row(), DirectoryRoomsModel::Identifier);
0080         const QString channelId = modelIndex.data().toString();
0081         modelIndex = mModel->index(index.row(), DirectoryRoomsModel::ChannelType);
0082         const QString channelType = modelIndex.data().toString();
0083         if (channelType == QLatin1String("p")) {
0084             mRocketChatAccount->openPrivateGroup(channelId, RocketChatAccount::ChannelTypeInfo::RoomId);
0085         } else if (channelType == QLatin1String("c")) {
0086             mRocketChatAccount->openChannel(channelId, RocketChatAccount::ChannelTypeInfo::RoomId);
0087         }
0088         break;
0089     }
0090     case User: {
0091         const QModelIndex modelIndex = mModel->index(index.row(), DirectoryUsersModel::UserName);
0092         const QString userId = modelIndex.data().toString();
0093         // mRocketChatAccount->openDirectChannel(userId);
0094         //  Workaround RC 4.7.x where openDirectChannel doesn't accept userId as direct open channel REST API
0095         mRocketChatAccount->ddp()->openDirectChannel(userId);
0096         break;
0097     }
0098     case Team: {
0099         const QModelIndex modelIndex = mModel->index(index.row(), DirectoryTeamsModel::RoomIdentifier);
0100         const QString roomId = modelIndex.data().toString();
0101         mRocketChatAccount->openChannel(roomId, RocketChatAccount::ChannelTypeInfo::RoomId);
0102         break;
0103     }
0104     case Unknown:
0105         break;
0106     }
0107 }
0108 
0109 void DirectoryWidget::slotLoadElements(int offset, int count, const QString &searchName)
0110 {
0111     RocketChatRestApi::DirectoryJob::DirectoryInfo info;
0112     switch (mType) {
0113     case Room:
0114         info.searchType = RocketChatRestApi::DirectoryJob::Rooms;
0115         break;
0116     case User:
0117         info.searchType = RocketChatRestApi::DirectoryJob::Users;
0118         break;
0119     case Team:
0120         info.searchType = RocketChatRestApi::DirectoryJob::Teams;
0121         break;
0122     case Unknown:
0123         qCWarning(RUQOLAWIDGETS_LOG) << "Invalid type it's a bug";
0124         return;
0125     }
0126     auto job = new RocketChatRestApi::DirectoryJob(this);
0127     if (!searchName.isEmpty()) {
0128         info.pattern = searchName;
0129     }
0130     job->setDirectoryInfo(info);
0131     RocketChatRestApi::QueryParameters parameters;
0132 
0133     QMap<QString, RocketChatRestApi::QueryParameters::SortOrder> map;
0134     map.insert(QStringLiteral("name"), RocketChatRestApi::QueryParameters::SortOrder::Ascendant);
0135     parameters.setSorting(map);
0136     if (offset != -1) {
0137         parameters.setOffset(offset);
0138     }
0139     if (count != -1) {
0140         parameters.setCount(count);
0141     }
0142     job->setQueryParameters(parameters);
0143 
0144     mRocketChatAccount->restApi()->initializeRestApiJob(job);
0145     if (offset != -1) {
0146         connect(job, &RocketChatRestApi::DirectoryJob::directoryDone, this, &DirectoryWidget::slotLoadMoreElementDone);
0147     } else {
0148         connect(job, &RocketChatRestApi::DirectoryJob::directoryDone, this, &DirectoryWidget::slotSearchDone);
0149     }
0150     if (!job->start()) {
0151         qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start DirectoryJob job";
0152     }
0153 }
0154 
0155 void DirectoryWidget::updateLabel()
0156 {
0157     mLabelResultSearch->setText(mModel->total() == 0 ? noFoundInfo() : displayShowMessageInRoom());
0158 }
0159 
0160 QString DirectoryWidget::noFoundInfo() const
0161 {
0162     switch (mType) {
0163     case Room:
0164         return i18n("No Room found");
0165     case User:
0166         return i18n("No User found");
0167     case Team:
0168         return i18n("No Team found");
0169     case Unknown:
0170         return {};
0171     }
0172     return {};
0173 }
0174 
0175 QString DirectoryWidget::displayShowMessageInRoom() const
0176 {
0177     QString displayMessageStr;
0178     switch (mType) {
0179     case Room:
0180         displayMessageStr = i18np("%1 room (Total: %2)", "%1 rooms (Total: %2)", mModel->rowCount(), mModel->total());
0181         break;
0182     case User:
0183         displayMessageStr = i18np("%1 user (Total: %2)", "%1 users (Total: %2)", mModel->rowCount(), mModel->total());
0184         break;
0185     case Team:
0186         displayMessageStr = i18np("%1 team (Total: %2)", "%1 teams (Total: %2)", mModel->rowCount(), mModel->total());
0187         break;
0188     case Unknown:
0189         break;
0190     }
0191     if (!mModel->hasFullList()) {
0192         displayMessageStr += clickableStr();
0193     }
0194     return displayMessageStr;
0195 }
0196 
0197 void DirectoryWidget::fillDirectory()
0198 {
0199     switch (mType) {
0200     case Room:
0201         mSearchLineEdit->setPlaceholderText(i18n("Search rooms..."));
0202         break;
0203     case User:
0204         mSearchLineEdit->setPlaceholderText(i18n("Search users..."));
0205         break;
0206     case Team:
0207         mSearchLineEdit->setPlaceholderText(i18n("Search teams..."));
0208         break;
0209     case Unknown:
0210         qCWarning(RUQOLAWIDGETS_LOG) << "Invalid type it's a bug";
0211         return;
0212     }
0213 }
0214 
0215 void DirectoryWidget::showEvent(QShowEvent *event)
0216 {
0217     if (!event->spontaneous() && !mWasInitialized) {
0218         mWasInitialized = true;
0219         initialize();
0220     }
0221     SearchTreeBaseWidget::showEvent(event);
0222 }
0223 
0224 DirectoryWidget::DirectoryType DirectoryWidget::type() const
0225 {
0226     return mType;
0227 }
0228 
0229 #include "moc_directorywidget.cpp"