File indexing completed on 2026-08-09 14:19: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 "administratorcustomemojiwidget.h"
0008 #include "administratorcustomemojicreateorupdatedialog.h"
0009 #include "connection.h"
0010 #include "emoji/emojicustomalljob.h"
0011 #include "emoji/emojicustomcreatejob.h"
0012 #include "emoji/emojicustomdeletejob.h"
0013 #include "emoji/emojicustomupdatejob.h"
0014 #include "emoticons/emojimanager.h"
0015 #include "misc/searchwithdelaylineedit.h"
0016 #include "model/admincustomemojimodel.h"
0017 #include "model/searchtreebasefilterproxymodel.h"
0018 #include "rocketchataccount.h"
0019 #include "ruqolawidgets_debug.h"
0020 #include <KLocalizedString>
0021 #include <KMessageBox>
0022 #include <QLabel>
0023 #include <QMenu>
0024 #include <QPointer>
0025 #include <QTreeView>
0026 
0027 AdministratorCustomEmojiWidget::AdministratorCustomEmojiWidget(RocketChatAccount *account, QWidget *parent)
0028     : SearchTreeBaseWidget(account, parent)
0029 {
0030     mModel = new AdminCustomEmojiModel(account, this);
0031     mModel->setObjectName(QStringLiteral("mModel"));
0032     mSearchLineEdit->setPlaceholderText(i18n("Search custom emojis"));
0033 
0034     mProxyModelModel = new SearchTreeBaseFilterProxyModel(mModel, this);
0035     mProxyModelModel->setObjectName(QStringLiteral("mProxyModelModel"));
0036     mTreeView->setModel(mProxyModelModel);
0037     hideColumns();
0038     connectModel();
0039     connect(mTreeView, &QTreeView::doubleClicked, this, &AdministratorCustomEmojiWidget::slotModifyCustomEmoji);
0040 }
0041 
0042 AdministratorCustomEmojiWidget::~AdministratorCustomEmojiWidget() = default;
0043 
0044 void AdministratorCustomEmojiWidget::updateLabel()
0045 {
0046     mLabelResultSearch->setText(mModel->total() == 0 ? i18n("No custom emoji found") : displayShowMessage());
0047 }
0048 
0049 QString AdministratorCustomEmojiWidget::displayShowMessage() const
0050 {
0051     QString displayMessageStr = i18np("%1 custom emoji (Total: %2)", "%1 custom emojis (Total: %2)", mModel->rowCount(), mModel->total());
0052     if (!mModel->hasFullList()) {
0053         displayMessageStr += clickableStr();
0054     }
0055     return displayMessageStr;
0056 }
0057 
0058 void AdministratorCustomEmojiWidget::slotLoadElements(int offset, int count, const QString &searchName)
0059 {
0060     // https://<server>/api/v1/emoji-custom.all?query={%22name%22:{%22$regex%22:%22t%22,%22$options%22:%22i%22}}&sort={%22name%22:1}&count=25
0061     // https://<server>/api/v1/emoji-custom.all?query=%7B%22name%22:%22te%22%7D&sort=%7B%22name%22:1%7D
0062     auto job = new RocketChatRestApi::EmojiCustomAllJob(this);
0063 
0064     RocketChatRestApi::QueryParameters parameters;
0065     QMap<QString, RocketChatRestApi::QueryParameters::SortOrder> map;
0066     map.insert(QStringLiteral("name"), RocketChatRestApi::QueryParameters::SortOrder::Ascendant);
0067     parameters.setSorting(map);
0068     if (offset != -1) {
0069         parameters.setOffset(offset);
0070     }
0071     if (count != -1) {
0072         parameters.setCount(count);
0073     }
0074     parameters.setSearchString(searchName);
0075 
0076     job->setQueryParameters(parameters);
0077 
0078     mRocketChatAccount->restApi()->initializeRestApiJob(job);
0079     if (offset != -1) {
0080         connect(job, &RocketChatRestApi::EmojiCustomAllJob::emojiCustomAllDone, this, &AdministratorCustomEmojiWidget::slotLoadMoreElementDone);
0081     } else {
0082         connect(job, &RocketChatRestApi::EmojiCustomAllJob::emojiCustomAllDone, this, &AdministratorCustomEmojiWidget::slotSearchDone);
0083     }
0084     if (!job->start()) {
0085         qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start EmojiCustomAllJob job";
0086     }
0087 }
0088 
0089 void AdministratorCustomEmojiWidget::slotAddCustomEmoji()
0090 {
0091     QPointer<AdministratorCustomEmojiCreateOrUpdateDialog> dlg = new AdministratorCustomEmojiCreateOrUpdateDialog(this);
0092     if (dlg->exec()) {
0093         const AdministratorCustomEmojiCreateOrUpdateWidget::CustomEmojiCreateInfo info = dlg->info();
0094 
0095         RocketChatRestApi::EmojiCustomCreateJob::EmojiInfo emojiInfo;
0096         emojiInfo.alias = info.alias;
0097         emojiInfo.name = info.name;
0098         emojiInfo.fileNameUrl = info.fileNameUrl;
0099         auto job = new RocketChatRestApi::EmojiCustomCreateJob(this);
0100         job->setEmojiInfo(emojiInfo);
0101         mRocketChatAccount->restApi()->initializeRestApiJob(job);
0102         connect(job, &RocketChatRestApi::EmojiCustomCreateJob::emojiCustomCreateDone, this, [this](const QJsonObject &replyObject) {
0103             Q_UNUSED(replyObject)
0104             // qDebug() << " replyObject " << replyObject;
0105             initialize(); // No info about updating list without reload it
0106         });
0107         if (!job->start()) {
0108             qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start EmojiCustomCreateJob job";
0109         }
0110     }
0111     delete dlg;
0112 }
0113 
0114 void AdministratorCustomEmojiWidget::slotModifyCustomEmoji(const QModelIndex &index)
0115 {
0116     QPointer<AdministratorCustomEmojiCreateOrUpdateDialog> dlg = new AdministratorCustomEmojiCreateOrUpdateDialog(this);
0117     dlg->setType(AdministratorCustomEmojiCreateOrUpdateWidget::AdministratorCustomEmojiCreateOrUpdateType::Update);
0118     AdministratorCustomEmojiCreateOrUpdateWidget::CustomEmojiCreateInfo info;
0119 
0120     info.alias = mModel->index(index.row(), AdminCustomEmojiModel::Aliases).data().toString();
0121     info.name = mModel->index(index.row(), AdminCustomEmojiModel::Name).data().toString();
0122     const auto icon = mModel->index(index.row(), AdminCustomEmojiModel::Icon).data().value<QIcon>();
0123     info.icon = icon;
0124     // TODO info.fileNameUrl =
0125     dlg->setCustomEmojiInfo(info);
0126     if (dlg->exec()) {
0127         const AdministratorCustomEmojiCreateOrUpdateWidget::CustomEmojiCreateInfo newCustomEmojInfo = dlg->info();
0128 
0129         RocketChatRestApi::EmojiCustomUpdateJob::EmojiInfo emojiInfo;
0130         emojiInfo.alias = newCustomEmojInfo.alias;
0131         emojiInfo.name = newCustomEmojInfo.name;
0132         emojiInfo.emojiId = mModel->index(index.row(), AdminCustomEmojiModel::Identifier).data().toString();
0133         emojiInfo.fileNameUrl = newCustomEmojInfo.fileNameUrl;
0134         auto job = new RocketChatRestApi::EmojiCustomUpdateJob(this);
0135         job->setEmojiInfo(emojiInfo);
0136         mRocketChatAccount->restApi()->initializeRestApiJob(job);
0137         connect(job, &RocketChatRestApi::EmojiCustomUpdateJob::emojiCustomUpdateDone, this, [](const QJsonObject &replyObject) {
0138             qDebug() << " replyObject " << replyObject;
0139             // TODO update list
0140         });
0141         if (!job->start()) {
0142             qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start EmojiCustomUpdateJob job";
0143         }
0144     }
0145     delete dlg;
0146 }
0147 
0148 void AdministratorCustomEmojiWidget::slotRemoveCustomEmoji(const QModelIndex &index)
0149 {
0150     if (KMessageBox::questionTwoActions(this,
0151                                         i18n("Do you want to remove this emoji?"),
0152                                         i18nc("@title", "Remove Emoji"),
0153                                         KStandardGuiItem::remove(),
0154                                         KStandardGuiItem::cancel())
0155         == KMessageBox::ButtonCode::PrimaryAction) {
0156         auto job = new RocketChatRestApi::EmojiCustomDeleteJob(this);
0157         const QString emojiId = index.data().toString();
0158         job->setEmojiId(emojiId);
0159         mRocketChatAccount->restApi()->initializeRestApiJob(job);
0160         connect(job, &RocketChatRestApi::EmojiCustomDeleteJob::emojiCustomDeleteDone, this, [this, emojiId]() {
0161             slotEmojiRemoved(emojiId);
0162         });
0163         if (!job->start()) {
0164             qCWarning(RUQOLAWIDGETS_LOG) << "Impossible to start EmojiCustomDeleteJob job";
0165         }
0166     }
0167 }
0168 
0169 void AdministratorCustomEmojiWidget::slotEmojiRemoved(const QString &emojiId)
0170 {
0171     mModel->removeElement(emojiId);
0172 }
0173 
0174 void AdministratorCustomEmojiWidget::slotCustomContextMenuRequested(const QPoint &pos)
0175 {
0176     QMenu menu(this);
0177     const QModelIndex index = mTreeView->indexAt(pos);
0178     menu.addAction(QIcon::fromTheme(QStringLiteral("list-add")), i18n("Add..."), this, &AdministratorCustomEmojiWidget::slotAddCustomEmoji);
0179     if (index.isValid()) {
0180         const QModelIndex newModelIndex = mProxyModelModel->mapToSource(index);
0181         menu.addAction(QIcon::fromTheme(QStringLiteral("document-edit")), i18n("Modify..."), this, [this, newModelIndex]() {
0182             const QModelIndex modelIndex = mModel->index(newModelIndex.row(), AdminCustomEmojiModel::Identifier);
0183             slotModifyCustomEmoji(modelIndex);
0184         });
0185         menu.addSeparator();
0186         menu.addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("Remove"), this, [this, newModelIndex]() {
0187             const QModelIndex modelIndex = mModel->index(newModelIndex.row(), AdminCustomEmojiModel::Identifier);
0188             slotRemoveCustomEmoji(modelIndex);
0189         });
0190     }
0191     menu.exec(mTreeView->viewport()->mapToGlobal(pos));
0192 }
0193 
0194 #include "moc_administratorcustomemojiwidget.cpp"