File indexing completed on 2024-05-12 16:25:02

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     const auto &row = index.row();
0028     const auto &image = m_images->images[row];
0029     if (role == UrlRole) {
0030         return m_connection->makeMediaUrl(image.url);
0031     }
0032     if (role == BodyRole) {
0033         if (image.body) {
0034             return *image.body;
0035         }
0036     }
0037     if (role == ShortCodeRole) {
0038         return image.shortcode;
0039     }
0040     if (role == IsStickerRole) {
0041         if (image.usage) {
0042             return image.usage->isEmpty() || image.usage->contains("sticker"_ls);
0043         }
0044         if (m_images->pack && m_images->pack->usage) {
0045             return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("sticker"_ls);
0046         }
0047         return true;
0048     }
0049     if (role == IsEmojiRole) {
0050         if (image.usage) {
0051             return image.usage->isEmpty() || image.usage->contains("emoticon"_ls);
0052         }
0053         if (m_images->pack && m_images->pack->usage) {
0054             return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("emoticon"_ls);
0055         }
0056         return true;
0057     }
0058     return {};
0059 }
0060 
0061 QHash<int, QByteArray> AccountEmoticonModel::roleNames() const
0062 {
0063     return {
0064         {AccountEmoticonModel::UrlRole, "url"},
0065         {AccountEmoticonModel::BodyRole, "body"},
0066         {AccountEmoticonModel::ShortCodeRole, "shortcode"},
0067         {AccountEmoticonModel::IsStickerRole, "isSticker"},
0068         {AccountEmoticonModel::IsEmojiRole, "isEmoji"},
0069     };
0070 }
0071 
0072 Connection *AccountEmoticonModel::connection() const
0073 {
0074     return m_connection;
0075 }
0076 
0077 void AccountEmoticonModel::setConnection(Connection *connection)
0078 {
0079     if (m_connection) {
0080         disconnect(m_connection, nullptr, this, nullptr);
0081     }
0082 
0083     m_connection = connection;
0084     Q_EMIT connectionChanged();
0085     connect(m_connection, &Connection::accountDataChanged, this, [this](QString type) {
0086         if (type == QStringLiteral("im.ponies.user_emotes")) {
0087             reloadEmoticons();
0088         }
0089     });
0090     reloadEmoticons();
0091 }
0092 
0093 void AccountEmoticonModel::reloadEmoticons()
0094 {
0095     QJsonObject json;
0096     if (m_connection->hasAccountData("im.ponies.user_emotes"_ls)) {
0097         json = m_connection->accountData("im.ponies.user_emotes"_ls)->contentJson();
0098     }
0099     const auto &content = ImagePackEventContent(json);
0100     beginResetModel();
0101     m_images = content;
0102     endResetModel();
0103 }
0104 
0105 void AccountEmoticonModel::deleteEmoticon(int index)
0106 {
0107     QJsonObject data;
0108     m_images->images.removeAt(index);
0109     m_images->fillJson(&data);
0110     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0111 }
0112 
0113 void AccountEmoticonModel::setEmoticonBody(int index, const QString &text)
0114 {
0115     m_images->images[index].body = text;
0116     QJsonObject data;
0117     m_images->fillJson(&data);
0118     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0119 }
0120 
0121 void AccountEmoticonModel::setEmoticonShortcode(int index, const QString &shortcode)
0122 {
0123     m_images->images[index].shortcode = shortcode;
0124     QJsonObject data;
0125     m_images->fillJson(&data);
0126     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0127 }
0128 
0129 void AccountEmoticonModel::setEmoticonImage(int index, const QUrl &source)
0130 {
0131     doSetEmoticonImage(index, source);
0132 }
0133 
0134 QCoro::Task<void> AccountEmoticonModel::doSetEmoticonImage(int index, QUrl source)
0135 {
0136     auto job = m_connection->uploadFile(source.isLocalFile() ? source.toLocalFile() : source.toString());
0137     co_await qCoro(job, &BaseJob::finished);
0138     if (job->error() != BaseJob::NoError) {
0139         co_return;
0140     }
0141     m_images->images[index].url = job->contentUri().toString();
0142     m_images->images[index].info = none;
0143     QJsonObject data;
0144     m_images->fillJson(&data);
0145     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0146 }
0147 
0148 QCoro::Task<void> AccountEmoticonModel::doAddEmoticon(QUrl source, QString shortcode, QString description, QString type)
0149 {
0150     auto job = m_connection->uploadFile(source.isLocalFile() ? source.toLocalFile() : source.toString());
0151     co_await qCoro(job, &BaseJob::finished);
0152     if (job->error() != BaseJob::NoError) {
0153         co_return;
0154     }
0155     m_images->images.append(ImagePackEventContent::ImagePackImage{
0156         shortcode,
0157         job->contentUri(),
0158         description,
0159         none,
0160         QStringList{type},
0161     });
0162     QJsonObject data;
0163     m_images->fillJson(&data);
0164     m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
0165 }
0166 
0167 void AccountEmoticonModel::addEmoticon(const QUrl &source, const QString &shortcode, const QString &description, const QString &type)
0168 {
0169     doAddEmoticon(source, shortcode, description, type);
0170 }
0171 
0172 #include "moc_accountemoticonmodel.cpp"