#pragma once #include "common/Aliases.hpp" #include "common/UniqueAccess.hpp" #include "providers/twitch/TwitchUser.hpp" #include <boost/unordered/unordered_flat_map_fwd.hpp> #include <QColor> #include <QRegularExpression> #include <QString> #include <memory> #include <unordered_map> namespace chatterino { // NB: "default" can be replaced with "static" to always get a non-animated // variant /// %1 <-> {id} /// %2 <-> {scale} (1.0, 2.0, 3.0) inline constexpr QStringView TWITCH_EMOTE_TEMPLATE = u"https://static-cdn.jtvnw.net/emoticons/v2/%1/default/dark/%2"; struct Emote; using EmotePtr = std::shared_ptr<const Emote>; struct CheerEmote { QColor color; int minBits; QRegularExpression regex; EmotePtr animatedEmote; EmotePtr staticEmote; }; struct CheerEmoteSet { QRegularExpression regex; std::vector<CheerEmote> cheerEmotes; }; struct TwitchEmoteSet { /// @brief The owner of this set /// /// This owner might not be resolved yet std::shared_ptr<TwitchUser> owner; std::vector<EmotePtr> emotes; /// If this is a bitstier emote set bool isBits = false; /// @brief If this emote set is a subscriber or similar emote set /// /// This includes sub and bit emotes bool isSubLike = false; /// @brief The title of this set /// /// We generate this based on the emote set's flags & owner QString title() const; }; using TwitchEmoteSetMap = boost::unordered_flat_map<EmoteSetId, TwitchEmoteSet>; struct HelixChannelEmote; inline constexpr QStringView TWITCH_SUB_EMOTE_SET_PREFIX = u"x-c2-s-"; inline constexpr QStringView TWITCH_BIT_EMOTE_SET_PREFIX = u"x-c2-b-"; struct TwitchEmoteSetMeta { QString setID; /// See TwitchEmoteSet::isBits bool isBits = false; /// See TwitchEmoteSet::isSubLike bool isSubLike = false; }; TwitchEmoteSetMeta getTwitchEmoteSetMeta(const HelixChannelEmote &emote); class ITwitchEmotes { public: virtual ~ITwitchEmotes() = default; virtual EmotePtr getOrCreateEmote(const EmoteId &id, const EmoteName &name) = 0; }; class TwitchEmotes : public ITwitchEmotes { public: static QString cleanUpEmoteCode(const QString &dirtyEmoteCode); TwitchEmotes() = default; EmotePtr getOrCreateEmote(const EmoteId &id, const EmoteName &name) override; private: UniqueAccess<std::unordered_map<EmoteId, std::weak_ptr<Emote>>> twitchEmotesCache_; }; } // namespace chatterino