File indexing completed on 2024-12-08 07:33:44
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"_ls] = QJsonObject{ 0086 {"display_name"_ls, 0087 m_showStickers ? i18nc("As in 'The user's own Stickers'", "Own Stickers") : i18nc("As in 'The user's own emojis", "Own Emojis")}, 0088 }; 0089 const auto &content = ImagePackEventContent(json); 0090 if (!content.images.isEmpty()) { 0091 m_events += ImagePackEventContent(json); 0092 } 0093 } 0094 0095 // Load emoticons from the saved rooms 0096 const auto &accountData = m_room->connection()->accountData("im.ponies.emote_rooms"_ls); 0097 if (accountData) { 0098 const auto &rooms = accountData->contentJson()["rooms"_ls].toObject(); 0099 for (const auto &roomId : rooms.keys()) { 0100 if (roomId == m_room->id()) { 0101 continue; 0102 } 0103 auto packs = rooms[roomId].toObject(); 0104 const auto &stickerRoom = m_room->connection()->room(roomId); 0105 if (!stickerRoom) { 0106 continue; 0107 } 0108 for (const auto &packKey : packs.keys()) { 0109 if (const auto &pack = stickerRoom->currentState().get<ImagePackEvent>(packKey)) { 0110 const auto packContent = pack->content(); 0111 if ((!packContent.pack || !packContent.pack->usage || (packContent.pack->usage->contains("emoticon"_ls) && showEmoticons()) 0112 || (packContent.pack->usage->contains("sticker"_ls) && showStickers())) 0113 && !packContent.images.isEmpty()) { 0114 m_events += packContent; 0115 } 0116 } 0117 } 0118 } 0119 } 0120 0121 // Load emoticons from the current room 0122 auto events = m_room->currentState().eventsOfType("im.ponies.room_emotes"_ls); 0123 for (const auto &event : events) { 0124 auto packContent = eventCast<const ImagePackEvent>(event)->content(); 0125 if (packContent.pack.has_value()) { 0126 if (!packContent.pack->usage || (packContent.pack->usage->contains("emoticon"_ls) && showEmoticons()) 0127 || (packContent.pack->usage->contains("sticker"_ls) && showStickers())) { 0128 m_events += packContent; 0129 } 0130 } 0131 } 0132 Q_EMIT imagesLoaded(); 0133 endResetModel(); 0134 } 0135 0136 bool ImagePacksModel::showStickers() const 0137 { 0138 return m_showStickers; 0139 } 0140 0141 void ImagePacksModel::setShowStickers(bool showStickers) 0142 { 0143 m_showStickers = showStickers; 0144 Q_EMIT showStickersChanged(); 0145 } 0146 0147 bool ImagePacksModel::showEmoticons() const 0148 { 0149 return m_showEmoticons; 0150 } 0151 0152 void ImagePacksModel::setShowEmoticons(bool showEmoticons) 0153 { 0154 m_showEmoticons = showEmoticons; 0155 Q_EMIT showEmoticonsChanged(); 0156 } 0157 QList<Quotient::ImagePackEventContent::ImagePackImage> ImagePacksModel::images(int index) 0158 { 0159 if (index < 0 || index >= m_events.size()) { 0160 return {}; 0161 } 0162 return m_events[index].images; 0163 } 0164 0165 #include "moc_imagepacksmodel.cpp"