#pragma once #include "common/Aliases.hpp" #include "common/Atomic.hpp" #include "common/FlagsEnum.hpp" #include #include #include #include #include #include #include #include #include #include namespace chatterino { class ImageSet; class Channel; namespace seventv::eventapi { struct EmoteAddDispatch; struct EmoteUpdateDispatch; struct EmoteRemoveDispatch; } // namespace seventv::eventapi // https://github.com/SevenTV/API/blob/a84e884b5590dbb5d91a5c6b3548afabb228f385/data/model/emote-set.model.go#L29-L36 enum class SeventvActiveEmoteFlag : std::int64_t { None = 0LL, // Emote is zero-width ZeroWidth = (1LL << 0), // Overrides Twitch Global emotes with the same name OverrideTwitchGlobal = (1 << 16), // Overrides Twitch Subscriber emotes with the same name OverrideTwitchSubscriber = (1 << 17), // Overrides BetterTTV emotes with the same name OverrideBetterTTV = (1 << 18), }; // https://github.com/SevenTV/API/blob/a84e884b5590dbb5d91a5c6b3548afabb228f385/data/model/emote.model.go#L57-L70 enum class SeventvEmoteFlag : int64_t { None = 0LL, // The emote is private and can only be accessed by its owner, editors and moderators Private = 1 << 0, // The emote was verified to be an original creation by the uploader Authentic = (1LL << 1), // The emote is recommended to be enabled as Zero-Width ZeroWidth = (1LL << 8), // Content Flags // Sexually Suggesive ContentSexual = (1LL << 16), // Rapid flashing ContentEpilepsy = (1LL << 17), // Edgy or distasteful, may be offensive to some users ContentEdgy = (1 << 18), // Not allowed specifically on the Twitch platform ContentTwitchDisallowed = (1LL << 24), }; using SeventvActiveEmoteFlags = FlagsEnum; using SeventvEmoteFlags = FlagsEnum; struct Emote; using EmotePtr = std::shared_ptr; class EmoteMap; enum class SeventvEmoteSetKind : uint8_t { Global, Personal, Channel, }; enum class SeventvEmoteSetFlag : uint32_t { Immutable = (1 << 0), Privileged = (1 << 1), Personal = (1 << 2), Commercial = (1 << 3), }; using SeventvEmoteSetFlags = FlagsEnum; namespace seventv::detail { EmoteMap parseEmotes(const QJsonArray &emoteSetEmotes, bool isGlobal); } // namespace seventv::detail class SeventvEmotes final { public: struct ChannelInfo { QString userID; QString emoteSetID; size_t twitchConnectionIndex; }; SeventvEmotes(); std::shared_ptr globalEmotes() const; std::optional globalEmote(const EmoteName &name) const; void loadGlobalEmotes(); void setGlobalEmotes(std::shared_ptr emotes); static void loadChannelEmotes( const std::weak_ptr &channel, const QString &channelId, std::function callback, bool manualRefresh, bool cacheHit); /** * Adds an emote to the `map` if it's valid. * This will _copy_ the emote map and * update the `Atomic`. * * @return The added emote if an emote was added. */ static std::optional addEmote( Atomic> &map, const seventv::eventapi::EmoteAddDispatch &dispatch); /** * Updates an emote in this `map`. * This will _copy_ the emote map and * update the `Atomic`. * * @return The updated emote if any emote was updated. */ static std::optional updateEmote( Atomic> &map, const seventv::eventapi::EmoteUpdateDispatch &dispatch); /** * Removes an emote from this `map`. * This will _copy_ the emote map and * update the `Atomic`. * * @return The removed emote if any emote was removed. */ static std::optional removeEmote( Atomic> &map, const seventv::eventapi::EmoteRemoveDispatch &dispatch); /** Fetches an emote-set by its id */ static void getEmoteSet( const QString &emoteSetId, std::function successCallback, std::function errorCallback); /** * Creates an image set from a 7TV emote or badge. * * @param emoteData { host: { files: [], url } } * @param useStatic use static version if possible */ static ImageSet createImageSet(const QJsonObject &emoteData, bool useStatic); private: Atomic> global_; std::vector> managedConnections; }; } // namespace chatterino