File indexing completed on 2024-05-12 16:25:04
0001 // SPDX-FileCopyrightText: 2021 Tobias Fella <tobias.fella@kde.org> 0002 // SPDX-License-Identifier: LGPL-2.0-or-later 0003 0004 #include "imagepacksmodel.h" 0005 #include "neochatroom.h" 0006 0007 #include <KLocalizedString> 0008 0009 using namespace Quotient; 0010 0011 ImagePacksModel::ImagePacksModel(QObject *parent) 0012 : QAbstractListModel(parent) 0013 { 0014 } 0015 0016 int ImagePacksModel::rowCount(const QModelIndex &index) const 0017 { 0018 Q_UNUSED(index); 0019 return m_events.count(); 0020 } 0021 0022 QVariant ImagePacksModel::data(const QModelIndex &index, int role) const 0023 { 0024 const auto row = index.row(); 0025 if (row < 0 || row >= m_events.size()) { 0026 return {}; 0027 } 0028 const auto &event = m_events[row]; 0029 if (role == DisplayNameRole) { 0030 if (event.pack->displayName) { 0031 return *event.pack->displayName; 0032 } 0033 } 0034 if (role == AvatarUrlRole) { 0035 if (event.pack->avatarUrl) { 0036 return m_room->connection()->makeMediaUrl(*event.pack->avatarUrl); 0037 } else if (!event.images.empty()) { 0038 return m_room->connection()->makeMediaUrl(event.images[0].url); 0039 } 0040 } 0041 return {}; 0042 } 0043 0044 QHash<int, QByteArray> ImagePacksModel::roleNames() const 0045 { 0046 return { 0047 {DisplayNameRole, "displayName"}, 0048 {AvatarUrlRole, "avatarUrl"}, 0049 {AttributionRole, "attribution"}, 0050 {IdRole, "id"}, 0051 }; 0052 } 0053 0054 NeoChatRoom *ImagePacksModel::room() const 0055 { 0056 return m_room; 0057 } 0058 0059 void ImagePacksModel::setRoom(NeoChatRoom *room) 0060 { 0061 if (m_room) { 0062 disconnect(m_room, nullptr, this, nullptr); 0063 disconnect(m_room->connection(), nullptr, this, nullptr); 0064 } 0065 m_room = room; 0066 0067 connect(m_room->connection(), &Connection::accountDataChanged, this, [this](const QString &type) { 0068 if (type == "im.ponies.user_emotes"_ls) { 0069 reloadImages(); 0070 } 0071 }); 0072 // TODO listen to packs changing 0073 reloadImages(); 0074 Q_EMIT roomChanged(); 0075 } 0076 0077 void ImagePacksModel::reloadImages() 0078 { 0079 beginResetModel(); 0080 m_events.clear(); 0081 0082 // Load emoticons from the account data 0083 if (m_room->connection()->hasAccountData("im.ponies.user_emotes"_ls)) { 0084 auto json = m_room->connection()->accountData("im.ponies.user_emotes"_ls)->contentJson(); 0085 json["pack"] = QJsonObject{ 0086 {"display_name", m_showStickers ? i18nc("As in 'The user's own Stickers'", "Own Stickers") : i18nc("As in 'The user's own emojis", "Own Emojis")}, 0087 }; 0088 const auto &content = ImagePackEventContent(json); 0089 if (!content.images.isEmpty()) { 0090 m_events += ImagePackEventContent(json); 0091 } 0092 } 0093 0094 // Load emoticons from the saved rooms 0095 const auto &accountData = m_room->connection()->accountData("im.ponies.emote_rooms"_ls); 0096 if (accountData) { 0097 const auto &rooms = accountData->contentJson()["rooms"_ls].toObject(); 0098 for (const auto &roomId : rooms.keys()) { 0099 if (roomId == m_room->id()) { 0100 continue; 0101 } 0102 auto packs = rooms[roomId].toObject(); 0103 const auto &stickerRoom = m_room->connection()->room(roomId); 0104 for (const auto &packKey : packs.keys()) { 0105 if (const auto &pack = stickerRoom->currentState().get<ImagePackEvent>(packKey)) { 0106 const auto packContent = pack->content(); 0107 if ((!packContent.pack || !packContent.pack->usage || (packContent.pack->usage->contains("emoticon") && showEmoticons()) 0108 || (packContent.pack->usage->contains("sticker") && showStickers())) 0109 && !packContent.images.isEmpty()) { 0110 m_events += packContent; 0111 } 0112 } 0113 } 0114 } 0115 } 0116 0117 // Load emoticons from the current room 0118 auto events = m_room->currentState().eventsOfType("im.ponies.room_emotes"); 0119 for (const auto &event : events) { 0120 auto packContent = eventCast<const ImagePackEvent>(event)->content(); 0121 if (packContent.pack.has_value()) { 0122 if (!packContent.pack->usage || (packContent.pack->usage->contains("emoticon") && showEmoticons()) 0123 || (packContent.pack->usage->contains("sticker") && showStickers())) { 0124 m_events += packContent; 0125 } 0126 } 0127 } 0128 Q_EMIT imagesLoaded(); 0129 endResetModel(); 0130 } 0131 0132 bool ImagePacksModel::showStickers() const 0133 { 0134 return m_showStickers; 0135 } 0136 0137 void ImagePacksModel::setShowStickers(bool showStickers) 0138 { 0139 m_showStickers = showStickers; 0140 Q_EMIT showStickersChanged(); 0141 } 0142 0143 bool ImagePacksModel::showEmoticons() const 0144 { 0145 return m_showEmoticons; 0146 } 0147 0148 void ImagePacksModel::setShowEmoticons(bool showEmoticons) 0149 { 0150 m_showEmoticons = showEmoticons; 0151 Q_EMIT showEmoticonsChanged(); 0152 } 0153 QVector<Quotient::ImagePackEventContent::ImagePackImage> ImagePacksModel::images(int index) 0154 { 0155 if (index < 0 || index >= m_events.size()) { 0156 return {}; 0157 } 0158 return m_events[index].images; 0159 } 0160 0161 #include "moc_imagepacksmodel.cpp"