diff --git a/src/models/emoticonfiltermodel.cpp b/src/models/emoticonfiltermodel.cpp index af0f53173..1bbab356f 100644 --- a/src/models/emoticonfiltermodel.cpp +++ b/src/models/emoticonfiltermodel.cpp @@ -4,17 +4,27 @@ #include "emoticonfiltermodel.h" #include "accountemoticonmodel.h" +#include "stickermodel.h" EmoticonFilterModel::EmoticonFilterModel(QObject *parent) : QSortFilterProxyModel(parent) { + connect(this, &EmoticonFilterModel::sourceModelChanged, this, [this]() { + if (dynamic_cast(sourceModel())) { + m_stickerRole = StickerModel::IsStickerRole; + m_emojiRole = StickerModel::IsEmojiRole; + } else { + m_stickerRole = AccountEmoticonModel::IsStickerRole; + m_emojiRole = AccountEmoticonModel::IsEmojiRole; + } + }); } bool EmoticonFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { Q_UNUSED(sourceParent); - auto stickerUsage = sourceModel()->data(sourceModel()->index(sourceRow, 0), AccountEmoticonModel::IsStickerRole).toBool(); - auto emojiUsage = sourceModel()->data(sourceModel()->index(sourceRow, 0), AccountEmoticonModel::IsEmojiRole).toBool(); + auto stickerUsage = sourceModel()->data(sourceModel()->index(sourceRow, 0), m_stickerRole).toBool(); + auto emojiUsage = sourceModel()->data(sourceModel()->index(sourceRow, 0), m_emojiRole).toBool(); return (stickerUsage && m_showStickers) || (emojiUsage && m_showEmojis); } diff --git a/src/models/emoticonfiltermodel.h b/src/models/emoticonfiltermodel.h index 70c6bc4d2..89839c562 100644 --- a/src/models/emoticonfiltermodel.h +++ b/src/models/emoticonfiltermodel.h @@ -46,4 +46,6 @@ Q_SIGNALS: private: bool m_showStickers = false; bool m_showEmojis = false; + int m_stickerRole = 0; + int m_emojiRole = 0; }; diff --git a/src/models/imagepacksmodel.cpp b/src/models/imagepacksmodel.cpp index 16f1c2d55..da8870106 100644 --- a/src/models/imagepacksmodel.cpp +++ b/src/models/imagepacksmodel.cpp @@ -15,6 +15,7 @@ ImagePacksModel::ImagePacksModel(QObject *parent) int ImagePacksModel::rowCount(const QModelIndex &index) const { + Q_UNUSED(index); return m_events.count(); } @@ -81,16 +82,20 @@ void ImagePacksModel::reloadImages() { beginResetModel(); m_events.clear(); + + // Load emoticons from the account data if (m_room->connection()->hasAccountData("im.ponies.user_emotes"_ls)) { auto json = m_room->connection()->accountData("im.ponies.user_emotes"_ls)->contentJson(); json["pack"] = QJsonObject{ - {"display_name", i18n("Own Stickers")}, + {"display_name", m_showStickers ? i18nc("As in 'The user's own Stickers'", "Own Stickers") : i18nc("As in 'The user's own emojis", "Own Emojis")}, }; const auto &content = ImagePackEventContent(json); if (!content.images.isEmpty()) { m_events += ImagePackEventContent(json); } } + + // Load emoticons from the saved rooms const auto &accountData = m_room->connection()->accountData("im.ponies.emote_rooms"_ls); if (accountData) { const auto &rooms = accountData->contentJson()["rooms"_ls].toObject(); @@ -104,11 +109,10 @@ void ImagePacksModel::reloadImages() #ifdef QUOTIENT_07 if (const auto &pack = stickerRoom->currentState().get(packKey)) { const auto packContent = pack->content(); - if (packContent.pack.has_value()) { - if (!packContent.pack->usage || (packContent.pack->usage->contains("emoticon") && showEmoticons()) - || (packContent.pack->usage->contains("sticker") && showStickers())) { - m_events += packContent; - } + if ((!packContent.pack || !packContent.pack->usage || (packContent.pack->usage->contains("emoticon") && showEmoticons()) + || (packContent.pack->usage->contains("sticker") && showStickers())) + && !packContent.images.isEmpty()) { + m_events += packContent; } } #endif @@ -116,6 +120,8 @@ void ImagePacksModel::reloadImages() } } #ifdef QUOTIENT_07 + + // Load emoticons from the current room auto events = m_room->currentState().eventsOfType("im.ponies.room_emotes"); for (const auto &event : events) { auto packContent = eventCast(event)->content(); diff --git a/src/models/stickermodel.cpp b/src/models/stickermodel.cpp index e82c586bb..a9f233e06 100644 --- a/src/models/stickermodel.cpp +++ b/src/models/stickermodel.cpp @@ -14,30 +14,45 @@ StickerModel::StickerModel(QObject *parent) int StickerModel::rowCount(const QModelIndex &index) const { + Q_UNUSED(index); return m_images.size(); } QVariant StickerModel::data(const QModelIndex &index, int role) const { const auto &row = index.row(); const auto &image = m_images[row]; - if (role == Url) { + if (role == UrlRole) { #ifdef QUOTIENT_07 return m_room->connection()->makeMediaUrl(image.url); #endif } - if (role == Body) { + if (role == BodyRole) { if (image.body) { return *image.body; } } + if (role == IsStickerRole) { + if (image.usage) { + return image.usage->isEmpty() || image.usage->contains("sticker"_ls); + } + return true; + } + if (role == IsEmojiRole) { + if (image.usage) { + return image.usage->isEmpty() || image.usage->contains("emoticon"_ls); + } + return true; + } return {}; } QHash StickerModel::roleNames() const { return { - {StickerModel::Url, "url"}, - {StickerModel::Body, "body"}, + {UrlRole, "url"}, + {BodyRole, "body"}, + {IsStickerRole, "isSticker"}, + {IsEmojiRole, "isEmoji"}, }; } ImagePacksModel *StickerModel::model() const diff --git a/src/models/stickermodel.h b/src/models/stickermodel.h index f83ab3c27..8c4a68998 100644 --- a/src/models/stickermodel.h +++ b/src/models/stickermodel.h @@ -47,8 +47,10 @@ public: * @brief Defines the model roles. */ enum Roles { - Url = Qt::UserRole + 1, /**< The source mxc URL for the image. */ - Body, /**< The image caption, if any. */ + UrlRole = Qt::UserRole + 1, /**< The source mxc URL for the image. */ + BodyRole, /**< The image caption, if any. */ + IsStickerRole, /**< Whether this emoticon is a sticker. */ + IsEmojiRole, /**< Whether this emoticon is an emoji. */ }; explicit StickerModel(QObject *parent = nullptr); diff --git a/src/qml/Component/Emoji/EmojiPicker.qml b/src/qml/Component/Emoji/EmojiPicker.qml index 91933b229..419da680e 100644 --- a/src/qml/Component/Emoji/EmojiPicker.qml +++ b/src/qml/Component/Emoji/EmojiPicker.qml @@ -107,7 +107,7 @@ ColumnLayout { EmojiGrid { id: emojiGrid targetIconSize: root.currentCategory === EmojiModel.Custom ? Kirigami.Units.gridUnit * 3 : root.categoryIconSize // Custom emojis are bigger - model: root.selectedType === 1 ? stickerModel : searchField.text.length === 0 ? EmojiModel.emojis(root.currentCategory) : (root.includeCustom ? EmojiModel.filterModel(searchField.text, false) : EmojiModel.filterModelNoCustom(searchField.text, false)) + model: root.selectedType === 1 ? emoticonFilterModel : searchField.text.length === 0 ? EmojiModel.emojis(root.currentCategory) : (root.includeCustom ? EmojiModel.filterModel(searchField.text, false) : EmojiModel.filterModelNoCustom(searchField.text, false)) Layout.fillWidth: true Layout.fillHeight: true withCustom: root.includeCustom @@ -115,7 +115,7 @@ ColumnLayout { header: categories Keys.forwardTo: searchField stickers: root.selectedType === 1 - onStickerChosen: stickerModel.postSticker(index) + onStickerChosen: stickerModel.postSticker(emoticonFilterModel.mapToSource(emoticonFilterModel.index(index, 0)).row) } Kirigami.Separator { @@ -163,6 +163,12 @@ ColumnLayout { room: currentRoom } + EmoticonFilterModel { + id: emoticonFilterModel + sourceModel: stickerModel + showStickers: true + } + Component { id: emojiDelegate Kirigami.NavigationTabButton {