From 5af6626e76a8966796e27dfc10e1cbccc87a55b0 Mon Sep 17 00:00:00 2001 From: nerix Date: Fri, 5 Sep 2025 10:01:21 +0200 Subject: [PATCH] fix: mark global BTTV emotes as zero-width at creation (#6440) * fix: mark global BTTV emotes as zero-width at creation * changelog * nit: slightly different formatting --------- Co-authored-by: Rasmus Karlsson --- CHANGELOG.md | 2 ++ src/messages/MessageBuilder.cpp | 54 +++++++------------------------ src/providers/bttv/BttvEmotes.cpp | 27 ++++++++++------ 3 files changed, 31 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b32aa07..d4aa85e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unversioned +- Bugfix: Fixed zero-width global BTTV emotes not showing in the `:~` completions. (#6440) + ## 2.5.4-beta.1 - Minor: Added `Open in custom player` to `twitch.tv/` link context menus. (#6403) diff --git a/src/messages/MessageBuilder.cpp b/src/messages/MessageBuilder.cpp index 31ea1790..cf86d722 100644 --- a/src/messages/MessageBuilder.cpp +++ b/src/messages/MessageBuilder.cpp @@ -78,11 +78,6 @@ const QRegularExpression allUsernamesMentionRegex("^" + regexHelpString); const QRegularExpression SPACE_REGEX("\\s"); -const QSet zeroWidthEmotes{ - "SoSnowy", "IceCold", "SantaHat", "TopHat", - "ReinDeer", "CandyCane", "cvMask", "cvHazmat", -}; - struct HypeChatPaidLevel { std::chrono::seconds duration; uint8_t numeric; @@ -421,7 +416,7 @@ EmotePtr makeSharedChatBadge(const QString &sourceName, }); } -std::tuple, MessageElementFlags, bool> parseEmote( +std::tuple, MessageElementFlags> parseEmote( TwitchChannel *twitchChannel, const EmoteName &name) { // Emote order: @@ -445,31 +440,19 @@ std::tuple, MessageElementFlags, bool> parseEmote( emote = twitchChannel->ffzEmote(name); if (emote) { - return { - emote, - MessageElementFlag::FfzEmote, - false, - }; + return {emote, MessageElementFlag::FfzEmote}; } emote = twitchChannel->bttvEmote(name); if (emote) { - return { - emote, - MessageElementFlag::BttvEmote, - false, - }; + return {emote, MessageElementFlag::BttvEmote}; } emote = twitchChannel->seventvEmote(name); if (emote) { - return { - emote, - MessageElementFlag::SevenTVEmote, - emote.value()->zeroWidth, - }; + return {emote, MessageElementFlag::SevenTVEmote}; } } @@ -478,38 +461,22 @@ std::tuple, MessageElementFlags, bool> parseEmote( emote = globalFfzEmotes->emote(name); if (emote) { - return { - emote, - MessageElementFlag::FfzEmote, - false, - }; + return {emote, MessageElementFlag::FfzEmote}; } emote = globalBttvEmotes->emote(name); if (emote) { - return { - emote, - MessageElementFlag::BttvEmote, - zeroWidthEmotes.contains(name.string), - }; + return {emote, MessageElementFlag::BttvEmote}; } emote = globalSeventvEmotes->globalEmote(name); if (emote) { - return { - emote, - MessageElementFlag::SevenTVEmote, - emote.value()->zeroWidth, - }; + return {emote, MessageElementFlag::SevenTVEmote}; } - return { - {}, - {}, - false, - }; + return {{}, {}}; } } // namespace @@ -2240,14 +2207,15 @@ void MessageBuilder::appendUsername(const QVariantMap &tags, Outcome MessageBuilder::tryAppendEmote(TwitchChannel *twitchChannel, const EmoteName &name) { - auto [emote, flags, zeroWidth] = parseEmote(twitchChannel, name); + auto [emote, flags] = parseEmote(twitchChannel, name); if (!emote) { return Failure; } - if (zeroWidth && getSettings()->enableZeroWidthEmotes && !this->isEmpty()) + if ((*emote)->zeroWidth && getSettings()->enableZeroWidthEmotes && + !this->isEmpty()) { // Attempt to merge current zero-width emote into any previous emotes auto *asEmote = dynamic_cast(&this->back()); diff --git a/src/providers/bttv/BttvEmotes.cpp b/src/providers/bttv/BttvEmotes.cpp index 40c2b2e7..844606fb 100644 --- a/src/providers/bttv/BttvEmotes.cpp +++ b/src/providers/bttv/BttvEmotes.cpp @@ -30,6 +30,11 @@ const QString CHANNEL_HAS_NO_EMOTES( /// %1 being the emote ID (e.g. 566ca04265dbbdab32ec054a) constexpr QStringView EMOTE_LINK_FORMAT = u"https://betterttv.com/emotes/%1"; +const QSet ZERO_WIDTH_EMOTES{ + u"SoSnowy", u"IceCold", u"SantaHat", u"TopHat", + u"ReinDeer", u"CandyCane", u"cvMask", u"cvHazmat", +}; + /// The emote CDN link template. /// /// %1 being the emote ID (e.g. 566ca04265dbbdab32ec054a) @@ -71,15 +76,19 @@ std::pair parseGlobalEmotes(const QJsonArray &jsonEmotes, auto name = EmoteName{jsonEmote.toObject().value("code").toString()}; auto emote = Emote({ - name, - ImageSet{ - Image::fromUrl(getEmoteLinkV3(id, "1x"), 1, EMOTE_BASE_SIZE), - Image::fromUrl(getEmoteLinkV3(id, "2x"), 0.5, - EMOTE_BASE_SIZE * 2), - Image::fromUrl(getEmoteLinkV3(id, "3x"), 0.25, - EMOTE_BASE_SIZE * 4)}, - Tooltip{name.string + "
Global BetterTTV Emote"}, - Url{EMOTE_LINK_FORMAT.arg(id.string)}, + .name = name, + .images = + ImageSet{ + Image::fromUrl(getEmoteLinkV3(id, "1x"), 1, + EMOTE_BASE_SIZE), + Image::fromUrl(getEmoteLinkV3(id, "2x"), 0.5, + EMOTE_BASE_SIZE * 2), + Image::fromUrl(getEmoteLinkV3(id, "3x"), 0.25, + EMOTE_BASE_SIZE * 4), + }, + .tooltip = Tooltip{name.string + "
Global BetterTTV Emote"}, + .homePage = Url{EMOTE_LINK_FORMAT.arg(id.string)}, + .zeroWidth = ZERO_WIDTH_EMOTES.contains(name.string), }); emotes[name] = cachedOrMakeEmotePtr(std::move(emote), currentEmotes);