diff --git a/CHANGELOG.md b/CHANGELOG.md index 57fffc7d..b8681c52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Minor: Added an API to get the current Twitch account in plugins. (#6554) - Minor: Added options to close multiple visible tabs. (#6515, #6619) - Minor: Added a setting to show the stream title in live messages. (#6572) +- Minor: Add categories to the emoji viewer. (#6598) - Minor: Added broadcaster-only `/poll`, `/cancelpoll`, and `/endpoll` commands. (#6583, #6605) - Minor: Added broadcaster-only `/prediction` command to start a prediction. (#6583) - Bugfix: Expose the "Extra extension IDs" setting on non-Windows systems too. (#6509) diff --git a/src/providers/emoji/Emojis.cpp b/src/providers/emoji/Emojis.cpp index 36cf2113..3d49d892 100644 --- a/src/providers/emoji/Emojis.cpp +++ b/src/providers/emoji/Emojis.cpp @@ -62,6 +62,8 @@ void parseEmoji(const std::shared_ptr &emojiData, rj::getSafe(unparsedEmoji, "has_img_twitter", capabilities.twitter); rj::getSafe(unparsedEmoji, "has_img_facebook", capabilities.facebook); + rj::getSafe(unparsedEmoji, "category", emojiData->category); + if (capabilities.apple) { emojiData->capabilities.set(EmojiData::Capability::Apple); @@ -219,6 +221,10 @@ void Emojis::loadEmojis() parseEmoji(variationEmojiData, variation, emojiData->shortCodes[0] + "_" + toneName); + // NOTE: Emoji variations do not have a category. + // We have to manually inherit it from the original emojiData. + variationEmojiData->category = emojiData->category; + this->emojiShortCodeToEmoji_.insert( variationEmojiData->shortCodes[0], variationEmojiData); this->shortCodes.push_back(variationEmojiData->shortCodes[0]); diff --git a/src/providers/emoji/Emojis.hpp b/src/providers/emoji/Emojis.hpp index 44d102ce..e650804e 100644 --- a/src/providers/emoji/Emojis.hpp +++ b/src/providers/emoji/Emojis.hpp @@ -31,6 +31,8 @@ struct EmojiData { // i.e. thinking std::vector shortCodes; + QString category; + using Capability = EmojiStyle; using Capabilities = FlagsEnum; diff --git a/src/widgets/dialogs/EmotePopup.cpp b/src/widgets/dialogs/EmotePopup.cpp index a8812ad5..548fb08c 100644 --- a/src/widgets/dialogs/EmotePopup.cpp +++ b/src/widgets/dialogs/EmotePopup.cpp @@ -1,6 +1,7 @@ #include "widgets/dialogs/EmotePopup.hpp" #include "Application.hpp" +#include "common/enums/MessageContext.hpp" #include "common/QLogging.hpp" #include "controllers/accounts/AccountController.hpp" #include "controllers/emotes/EmoteController.hpp" @@ -164,11 +165,48 @@ void addTwitchEmoteSets(const std::shared_ptr &local, void loadEmojis(ChannelView &view, const std::vector &emojiMap) { + static auto emoteCategoryMap = [&] { + std::map> emoteCatMap; + + for (const auto &emoji : emojiMap) + { + auto cat = emoteCatMap.find(emoji->category); + if (cat != emoteCatMap.end()) + { + auto &vec = cat->second; + vec.push_back(emoji); + } + else + { + emoteCatMap.emplace(emoji->category, + std::vector{emoji}); + } + } + return emoteCatMap; + }(); + ChannelPtr emojiChannel(new Channel("", Channel::Type::None)); // set the channel first to make sure the scrollbar is at the top view.setChannel(emojiChannel); - emojiChannel->addMessage(makeEmojiMessage(emojiMap), + for (auto &it : emoteCategoryMap) + { + // Skip the Component category for now. + if (it.first == "Component") + { + continue; + } + + emojiChannel->addMessage(makeTitleMessage(it.first), + MessageContext::Original); + emojiChannel->addMessage(makeEmojiMessage(it.second), + MessageContext::Original); + } + + // Add the Component category at the bottom of the picker. + emojiChannel->addMessage(makeTitleMessage("Component"), + MessageContext::Original); + emojiChannel->addMessage(makeEmojiMessage(emoteCategoryMap["Component"]), MessageContext::Original); }