File indexing completed on 2024-12-08 07:33:43

0001 // SPDX-FileCopyrightText: 2021-2023 Tobias Fella <tobias.fella@kde.org>
0002 // SPDX-License-Identifier: LGPL-2.0-or-later
0003 
0004 #include "accountemoticonmodel.h"
0005 
0006 #include <Quotient/csapi/content-repo.h>
0007 #include <qcoro/qcorosignal.h>
0008 
0009 using namespace Quotient;
0010 
0011 AccountEmoticonModel::AccountEmoticonModel(QObject *parent)
0012     : QAbstractListModel(parent)
0013 {
0014 }
0015 
0016 int AccountEmoticonModel::rowCount(const QModelIndex &index) const
0017 {
0018     Q_UNUSED(index);
0019     if (!m_images) {
0020         return 0;
0021     }
0022     return m_images->images.size();
0023 }
0024 
0025 QVariant AccountEmoticonModel::data(const QModelIndex &index, int role) const
0026 {
0027     if (m_connection == nullptr) {
0028         return {};
0029     }
0030 
0031     const auto &row = index.row();
0032     const auto &image = m_images->images[row];
0033     if (role == UrlRole) {
0034         return m_connection->makeMediaUrl(image.url);
0035     }
0036     if (role == BodyRole) {
0037         if (image.body) {
0038             return *image.body;
0039         }
0040     }
0041     if (role == ShortCodeRole) {
0042         return image.shortcode;
0043     }
0044     if (role == IsStickerRole) {
0045         if (image.usage) {
0046             return image.usage->isEmpty() || image.usage->contains("sticker"_ls);
0047         }
0048         if (m_images->pack && m_images->pack->usage) {
0049             return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("sticker"_ls);
0050         }
0051         return true;
0052     }
0053     if (role == IsEmojiRole) {
0054         if (image.usage) {
0055             return image.usage->isEmpty() || image.usage->contains("emoticon"_ls);
0056         }
0057         if (m_images->pack && m_images->pack->usage) {
0058             return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("emoticon"_ls);
0059         }
0060         return true;
0061     }
0062     return {};
0063 }
0064 
0065 QHash<int, QByteArray> AccountEmoticonModel::roleNames() const
0066 {
0067     return {
0068         {AccountEmoticonModel::UrlRole, "url"},
0069         {AccountEmoticonModel::BodyRole, "body"},
0070         {AccountEmoticonModel::ShortCodeRole, "shortcode"},
0071         {AccountEmoticonModel::IsStickerRole, "isSticker"},
0072         {AccountEmoticonModel::IsEmojiRole, "isEmoji"},
0073     };
0074 }
0075 
0076 Connection *AccountEmoticonModel::connection() const
0077 {
0078     return m_connection;
0079 }
0080 
0081 void AccountEmoticonModel::setConnection(Connection *connection)
0082 {
0083     if (m_connection) {
0084         disconnect(m_connection, nullptr, this, nullptr);
0085     }
0086 
0087     m_connection = connection;
0088     Q_EMIT connectionChanged();
0089     connect(m_connection, &Connection::accountDataChanged, this, [this](QString type) {
0090         if (type == QStringLiteral("im.ponies.user_emotes")) {
0091             reloadEmoticons();
0092         }
0093     });
0094     reloadEmoticons();
0095 }
0096 
0097 void AccountEmoticonModel::reloadEmoticons()
0098 {
0099     if (m_connection == nullptr) {
0100         return;
0101     }
0102 
0103     QJsonObject json;
0104     if (m_connection->hasAccountData("im.ponies.user_emotes"_ls)) {
0105         json = m_connection->accountData("im.ponies.user_emotes"_ls)->contentJson();
0106     }
0107     const auto &content = ImagePackEventContent(json);
0108     beginResetModel();
0109     m_images = content;
0110     endResetModel();
0111 }
0112 
0113 void AccountEmoticonModel::deleteEmoticon(int index)
0114 {
0115     if (m_connection == nullptr) {
0116         return;
0117     }
0118 
0119     QJsonObject data;
0120     m_images->images.removeAt(index);
0121     m_images->fillJson(&data);
0122     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0123 }
0124 
0125 void AccountEmoticonModel::setEmoticonBody(int index, const QString &text)
0126 {
0127     if (m_connection == nullptr) {
0128         return;
0129     }
0130 
0131     m_images->images[index].body = text;
0132     QJsonObject data;
0133     m_images->fillJson(&data);
0134     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0135 }
0136 
0137 void AccountEmoticonModel::setEmoticonShortcode(int index, const QString &shortcode)
0138 {
0139     if (m_connection == nullptr) {
0140         return;
0141     }
0142 
0143     m_images->images[index].shortcode = shortcode;
0144     QJsonObject data;
0145     m_images->fillJson(&data);
0146     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0147 }
0148 
0149 void AccountEmoticonModel::setEmoticonImage(int index, const QUrl &source)
0150 {
0151     if (m_connection == nullptr) {
0152         return;
0153     }
0154     doSetEmoticonImage(index, source);
0155 }
0156 
0157 QCoro::Task<void> AccountEmoticonModel::doSetEmoticonImage(int index, QUrl source)
0158 {
0159     auto job = m_connection->uploadFile(source.isLocalFile() ? source.toLocalFile() : source.toString());
0160     co_await qCoro(job, &BaseJob::finished);
0161     if (job->error() != BaseJob::NoError) {
0162         co_return;
0163     }
0164     m_images->images[index].url = job->contentUri();
0165     m_images->images[index].info = none;
0166     QJsonObject data;
0167     m_images->fillJson(&data);
0168     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0169 }
0170 
0171 QCoro::Task<void> AccountEmoticonModel::doAddEmoticon(QUrl source, QString shortcode, QString description, QString type)
0172 {
0173     auto job = m_connection->uploadFile(source.isLocalFile() ? source.toLocalFile() : source.toString());
0174     co_await qCoro(job, &BaseJob::finished);
0175     if (job->error() != BaseJob::NoError) {
0176         co_return;
0177     }
0178     m_images->images.append(ImagePackEventContent::ImagePackImage{
0179         shortcode,
0180         job->contentUri(),
0181         description,
0182         none,
0183         QStringList{type},
0184     });
0185     QJsonObject data;
0186     m_images->fillJson(&data);
0187     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0188 }
0189 
0190 void AccountEmoticonModel::addEmoticon(const QUrl &source, const QString &shortcode, const QString &description, const QString &type)
0191 {
0192     if (m_connection == nullptr) {
0193         return;
0194     }
0195     doAddEmoticon(source, shortcode, description, type);
0196 }
0197 
0198 #include "moc_accountemoticonmodel.cpp"