mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Display all parsed elements when parsing emojis in replies (#4875)
This commit is contained in:
parent
4db93bf1da
commit
fe4d6121a2
4 changed files with 74 additions and 42 deletions
|
@ -19,6 +19,7 @@
|
|||
- Bugfix: Fixed too much text being copied when copying chat messages. (#4812, #4830, #4839)
|
||||
- Bugfix: Fixed empty page being added when showing out of bounds dialog. (#4849)
|
||||
- Bugfix: Fixed issue on Windows preventing the title bar from being dragged in the top left corner. (#4873)
|
||||
- Bugfix: Fixed an issue where reply context didn't render correctly if an emoji was touching text. (#4875)
|
||||
- Bugfix: Fixed the input completion popup from disappearing when clicking on it on Windows and macOS. (#4876)
|
||||
- Dev: Fixed UTF16 encoding of `modes` file for the installer. (#4791)
|
||||
- Dev: Temporarily disable High DPI scaling on Qt6 builds on Windows. (#4767)
|
||||
|
|
|
@ -458,6 +458,7 @@ set(SOURCE_FILES
|
|||
util/Twitch.cpp
|
||||
util/Twitch.hpp
|
||||
util/TypeName.hpp
|
||||
util/Variant.hpp
|
||||
util/WidgetHelpers.cpp
|
||||
util/WidgetHelpers.hpp
|
||||
util/WindowsHelper.cpp
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "singletons/Settings.hpp"
|
||||
#include "singletons/Theme.hpp"
|
||||
#include "util/DebugCount.hpp"
|
||||
#include "util/Variant.hpp"
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
|
@ -665,55 +666,56 @@ void SingleLineTextElement::addToContainer(MessageLayoutContainer &container,
|
|||
container.first = FirstWord::Neutral;
|
||||
for (Word &word : this->words_)
|
||||
{
|
||||
auto parsedWords = app->emotes->emojis.parse(word.text);
|
||||
if (parsedWords.size() == 0)
|
||||
for (const auto &parsedWord : app->emotes->emojis.parse(word.text))
|
||||
{
|
||||
continue; // sanity check
|
||||
}
|
||||
|
||||
auto &parsedWord = parsedWords[0];
|
||||
if (parsedWord.type() == typeid(QString))
|
||||
{
|
||||
if (!currentText.isEmpty())
|
||||
if (parsedWord.type() == typeid(QString))
|
||||
{
|
||||
currentText += ' ';
|
||||
}
|
||||
currentText += word.text;
|
||||
QString prev = currentText; // only increments the ref-count
|
||||
currentText = metrics.elidedText(currentText, Qt::ElideRight,
|
||||
container.remainingWidth());
|
||||
if (currentText != prev)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (parsedWord.type() == typeid(EmotePtr))
|
||||
{
|
||||
auto emote = boost::get<EmotePtr>(parsedWord);
|
||||
auto image =
|
||||
emote->images.getImageOrLoaded(container.getScale());
|
||||
if (!image->isEmpty())
|
||||
{
|
||||
auto emoteScale = getSettings()->emoteScale.getValue();
|
||||
|
||||
int currentWidth = metrics.horizontalAdvance(currentText);
|
||||
auto emoteSize = QSize(image->width(), image->height()) *
|
||||
(emoteScale * container.getScale());
|
||||
|
||||
if (!container.fitsInLine(currentWidth + emoteSize.width()))
|
||||
if (!currentText.isEmpty())
|
||||
{
|
||||
currentText += ' ';
|
||||
}
|
||||
currentText += boost::get<QString>(parsedWord);
|
||||
QString prev =
|
||||
currentText; // only increments the ref-count
|
||||
currentText =
|
||||
metrics.elidedText(currentText, Qt::ElideRight,
|
||||
container.remainingWidth());
|
||||
if (currentText != prev)
|
||||
{
|
||||
currentText += ellipsis;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (parsedWord.type() == typeid(EmotePtr))
|
||||
{
|
||||
auto emote = boost::get<EmotePtr>(parsedWord);
|
||||
auto image =
|
||||
emote->images.getImageOrLoaded(container.getScale());
|
||||
if (!image->isEmpty())
|
||||
{
|
||||
auto emoteScale = getSettings()->emoteScale.getValue();
|
||||
|
||||
// Add currently pending text to container, then add the emote after.
|
||||
container.addElementNoLineBreak(
|
||||
getTextLayoutElement(currentText, currentWidth, false));
|
||||
currentText.clear();
|
||||
int currentWidth =
|
||||
metrics.horizontalAdvance(currentText);
|
||||
auto emoteSize =
|
||||
QSize(image->width(), image->height()) *
|
||||
(emoteScale * container.getScale());
|
||||
|
||||
container.addElementNoLineBreak(
|
||||
(new ImageLayoutElement(*this, image, emoteSize))
|
||||
->setLink(this->getLink()));
|
||||
if (!container.fitsInLine(currentWidth +
|
||||
emoteSize.width()))
|
||||
{
|
||||
currentText += ellipsis;
|
||||
break;
|
||||
}
|
||||
|
||||
// Add currently pending text to container, then add the emote after.
|
||||
container.addElementNoLineBreak(getTextLayoutElement(
|
||||
currentText, currentWidth, false));
|
||||
currentText.clear();
|
||||
|
||||
container.addElementNoLineBreak(
|
||||
(new ImageLayoutElement(*this, image, emoteSize))
|
||||
->setLink(this->getLink()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
28
src/util/Variant.hpp
Normal file
28
src/util/Variant.hpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
namespace chatterino::variant {
|
||||
|
||||
/// Compile-time safe visitor for std and boost variants.
|
||||
///
|
||||
/// From https://en.cppreference.com/w/cpp/utility/variant/visit
|
||||
///
|
||||
/// Usage:
|
||||
///
|
||||
/// ```
|
||||
/// std::variant<int, double> v;
|
||||
/// std::visit(variant::Overloaded{
|
||||
/// [](double) { qDebug() << "double"; },
|
||||
/// [](int) { qDebug() << "int"; }
|
||||
/// }, v);
|
||||
/// ```
|
||||
template <class... Ts>
|
||||
struct Overloaded : Ts... {
|
||||
using Ts::operator()...;
|
||||
};
|
||||
|
||||
// Technically, we shouldn't need this, as we're on C++ 20,
|
||||
// but not all of our compilers support CTAD for aggregates yet.
|
||||
template <class... Ts>
|
||||
Overloaded(Ts...) -> Overloaded<Ts...>;
|
||||
|
||||
} // namespace chatterino::variant
|
Loading…
Reference in a new issue