Skip to content

Commit

Permalink
Fix emote & badge tooltips not showing up when thumbnails were hidden (
Browse files Browse the repository at this point in the history
…#4509)

Co-authored-by: Rasmus Karlsson <[email protected]>
  • Loading branch information
kornes and pajlada authored Apr 8, 2023
1 parent 073192b commit 5c55f62
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 68 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Bugfix: Fixed blocked user list sticking around when switching from a logged in user to being logged out. (#4437)
- Bugfix: Fixed search popup ignoring setting for message scrollback limit. (#4496)
- Bugfix: Fixed a memory leak that occurred when loading message history. This was mostly noticeable with unstable internet connections where reconnections were frequent or long-running instances of Chatterino. (#4499)
- Bugfix: Fixed emote & badge tooltips not showing up when thumbnails were hidden. (#4509)
- Dev: Disabling precompiled headers on Windows is now tested in CI. (#4472)
- Dev: Themes are now stored as JSON files in `resources/themes`. (#4471)
- Dev: Ignore unhandled BTTV user-events. (#4438)
Expand Down
14 changes: 12 additions & 2 deletions src/singletons/Settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ enum HelixTimegateOverride : int {
AlwaysUseHelix = 3,
};

enum ThumbnailPreviewMode : int {
DontShow = 0,

AlwaysShow = 1,

ShowOnShift = 2,
};

/// Settings which are availlable for reading and writing on the gui thread.
// These settings are still accessed concurrently in the code but it is bad practice.
class Settings : public ABSettings, public ConcurrentSettings
Expand Down Expand Up @@ -217,7 +225,6 @@ class Settings : public ABSettings, public ConcurrentSettings
FloatSetting emoteScale = {"/emotes/scale", 1.f};
BoolSetting showUnlistedSevenTVEmotes = {
"/emotes/showUnlistedSevenTVEmotes", false};

QStringSetting emojiSet = {"/emotes/emojiSet", "Twitter"};

BoolSetting stackBits = {"/emotes/stackBits", false};
Expand Down Expand Up @@ -478,9 +485,12 @@ class Settings : public ABSettings, public ConcurrentSettings
HelixTimegateOverride::Timegate,
};

IntSetting emotesTooltipPreview = {"/misc/emotesTooltipPreview", 1};
BoolSetting openLinksIncognito = {"/misc/openLinksIncognito", 0};

EnumSetting<ThumbnailPreviewMode> emotesTooltipPreview = {
"/misc/emotesTooltipPreview",
ThumbnailPreviewMode::AlwaysShow,
};
QStringSetting cachePath = {"/cache/path", ""};
BoolSetting restartOnCrash = {"/misc/restartOnCrash", false};
BoolSetting attachExtensionToAnyProcess = {
Expand Down
129 changes: 68 additions & 61 deletions src/widgets/helper/ChannelView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1672,81 +1672,88 @@ void ChannelView::mouseMoveEvent(QMouseEvent *event)
{
auto badgeElement = dynamic_cast<const BadgeElement *>(element);

if ((badgeElement || emoteElement || layeredEmoteElement) &&
getSettings()->emotesTooltipPreview.getValue())
if (badgeElement || emoteElement || layeredEmoteElement)
{
if (event->modifiers() == Qt::ShiftModifier ||
getSettings()->emotesTooltipPreview.getValue() == 1)
auto showThumbnailSetting =
getSettings()->emotesTooltipPreview.getValue();

bool showThumbnail =
showThumbnailSetting == ThumbnailPreviewMode::AlwaysShow ||
(showThumbnailSetting == ThumbnailPreviewMode::ShowOnShift &&
event->modifiers() == Qt::ShiftModifier);

if (emoteElement)
{
if (emoteElement)
{
tooltipWidget->setOne({
emoteElement->getEmote()->images.getImage(3.0),
element->getTooltip(),
});
}
else if (layeredEmoteElement)
tooltipWidget->setOne({
showThumbnail
? emoteElement->getEmote()->images.getImage(3.0)
: nullptr,
element->getTooltip(),
});
}
else if (layeredEmoteElement)
{
auto &layeredEmotes = layeredEmoteElement->getEmotes();
// Should never be empty but ensure it
if (!layeredEmotes.empty())
{
auto &layeredEmotes = layeredEmoteElement->getEmotes();
// Should never be empty but ensure it
if (!layeredEmotes.empty())
std::vector<TooltipEntry> entries;
entries.reserve(layeredEmotes.size());

auto &emoteTooltips =
layeredEmoteElement->getEmoteTooltips();

// Someone performing some tomfoolery could put an emote with tens,
// if not hundreds of zero-width emotes on a single emote. If the
// tooltip may take up more than three rows, truncate everything else.
bool truncating = false;
size_t upperLimit = layeredEmotes.size();
if (layeredEmotes.size() > TOOLTIP_EMOTE_ENTRIES_LIMIT)
{
std::vector<TooltipEntry> entries;
entries.reserve(layeredEmotes.size());

auto &emoteTooltips =
layeredEmoteElement->getEmoteTooltips();

// Someone performing some tomfoolery could put an emote with tens,
// if not hundreds of zero-width emotes on a single emote. If the
// tooltip may take up more than three rows, truncate everything else.
bool truncating = false;
size_t upperLimit = layeredEmotes.size();
if (layeredEmotes.size() > TOOLTIP_EMOTE_ENTRIES_LIMIT)
{
upperLimit = TOOLTIP_EMOTE_ENTRIES_LIMIT - 1;
truncating = true;
}
upperLimit = TOOLTIP_EMOTE_ENTRIES_LIMIT - 1;
truncating = true;
}

for (size_t i = 0; i < upperLimit; ++i)
for (size_t i = 0; i < upperLimit; ++i)
{
const auto &emote = layeredEmotes[i].ptr;
if (i == 0)
{
const auto &emote = layeredEmotes[i].ptr;
if (i == 0)
{
// First entry gets a large image and full description
entries.push_back({emote->images.getImage(3.0),
emoteTooltips[i]});
}
else
{
// Every other entry gets a small image and just the emote name
entries.push_back({emote->images.getImage(1.0),
emote->name.string});
}
// First entry gets a large image and full description
entries.push_back({showThumbnail
? emote->images.getImage(3.0)
: nullptr,
emoteTooltips[i]});
}

if (truncating)
else
{
entries.push_back({nullptr, "..."});
// Every other entry gets a small image and just the emote name
entries.push_back({showThumbnail
? emote->images.getImage(1.0)
: nullptr,
emote->name.string});
}
}

auto style = layeredEmotes.size() > 2
? TooltipStyle::Grid
: TooltipStyle::Vertical;
tooltipWidget->set(entries, style);
if (truncating)
{
entries.push_back({nullptr, "..."});
}
}
else if (badgeElement)
{
tooltipWidget->setOne({
badgeElement->getEmote()->images.getImage(3.0),
element->getTooltip(),
});

auto style = layeredEmotes.size() > 2
? TooltipStyle::Grid
: TooltipStyle::Vertical;
tooltipWidget->set(entries, style);
}
}
else
else if (badgeElement)
{
tooltipWidget->clearEntries();
tooltipWidget->setOne({
showThumbnail
? badgeElement->getEmote()->images.getImage(3.0)
: nullptr,
element->getTooltip(),
});
}
}
else
Expand Down
24 changes: 19 additions & 5 deletions src/widgets/settingspages/GeneralPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,16 +416,30 @@ void GeneralPage::initLayout(GeneralPageView &layout)
});
},
false);
layout.addDropdown<int>(
"Show info on hover", {"Don't show", "Always show", "Hold shift"},
layout.addDropdown<std::underlying_type<ThumbnailPreviewMode>::type>(
"Show emote & badge thumbnail on hover",
{
"Don't show",
"Always show",
"Hold shift",
},
s.emotesTooltipPreview,
[](int index) {
return index;
[](auto val) {
switch (val)
{
case ThumbnailPreviewMode::DontShow:
return "Don't show";
case ThumbnailPreviewMode::AlwaysShow:
return "Always show";
case ThumbnailPreviewMode::ShowOnShift:
return "Hold shift";
}
return "";
},
[](auto args) {
return args.index;
},
false, "Show emote name, provider, and author on hover.");
false);
layout.addDropdown("Emoji style",
{
"Twitter",
Expand Down

0 comments on commit 5c55f62

Please sign in to comment.