#pragma once #define GIF_FRAME_LENGTH 33 #include "concurrentmap.hpp" #include "emojis.hpp" #include "messages/lazyloadedimage.hpp" #include "signalvector.hpp" #include "twitch/emotevalue.hpp" #include #include #include #include #include #include namespace chatterino { struct EmoteData { EmoteData() { } EmoteData(messages::LazyLoadedImage *_image) : image(_image) { } messages::LazyLoadedImage *image = nullptr; }; typedef ConcurrentMap EmoteMap; class EmoteManager { EmoteManager(); public: static EmoteManager &getInstance() { static EmoteManager instance; return instance; } void loadGlobalEmotes(); void reloadBTTVChannelEmotes(const QString &channelName, std::weak_ptr channelEmoteMap); void reloadFFZChannelEmotes(const QString &channelName, std::weak_ptr channelEmoteMap); ConcurrentMap &getTwitchEmotes(); EmoteMap &getFFZEmotes(); EmoteMap &getChatterinoEmotes(); EmoteMap &getBTTVChannelEmoteFromCaches(); ConcurrentMap &getFFZChannelEmoteFromCaches(); ConcurrentMap &getTwitchEmoteFromCache(); EmoteData getCheerImage(long long int amount, bool animated); EmoteData getTwitchEmoteById(long int id, const QString &emoteName); int getGeneration() { return _generation; } void incGeneration() { _generation++; } boost::signals2::signal &getGifUpdateSignal(); // Bit badge/emotes? ConcurrentMap miscImageCache; private: /// Emojis QRegularExpression findShortCodesRegex; // shortCodeToEmoji maps strings like "sunglasses" to its emoji QMap emojiShortCodeToEmoji; // Maps the first character of the emoji unicode string to a vector of possible emojis QMap> emojiFirstByte; // url Emoji-one image EmoteMap emojis; void loadEmojis(); public: void parseEmojis(std::vector> &parsedWords, const QString &text); QString replaceShortCodes(const QString &text); std::vector emojiShortCodes; /// Twitch emotes void refreshTwitchEmotes(const std::string &roomID); struct TwitchAccountEmoteData { struct TwitchEmote { std::string id; std::string code; }; // emote set std::map> emoteSets; std::vector emoteCodes; bool filled = false; }; std::map twitchAccountEmotes; private: // emote code ConcurrentMap _twitchEmotes; // emote id ConcurrentMap _twitchEmoteFromCache; /// BTTV emotes EmoteMap bttvChannelEmotes; public: ConcurrentMap bttvChannels; EmoteMap bttvGlobalEmotes; SignalVector bttvGlobalEmoteCodes; // roomID std::map> bttvChannelEmoteCodes; EmoteMap _bttvChannelEmoteFromCaches; private: void loadBTTVEmotes(); /// FFZ emotes EmoteMap ffzChannelEmotes; public: ConcurrentMap ffzChannels; EmoteMap ffzGlobalEmotes; SignalVector ffzGlobalEmoteCodes; std::map> ffzChannelEmoteCodes; private: ConcurrentMap _ffzChannelEmoteFromCaches; void loadFFZEmotes(); /// Chatterino emotes EmoteMap _chatterinoEmotes; boost::signals2::signal gifUpdateTimerSignal; QTimer gifUpdateTimer; bool gifUpdateTimerInitiated = false; int _generation = 0; // methods static QString getTwitchEmoteLink(long id, qreal &scale); }; } // namespace chatterino