mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
fix replacement with emotes issues
This commit is contained in:
parent
646268ab18
commit
1acb1278aa
2 changed files with 119 additions and 51 deletions
|
@ -41,16 +41,6 @@ public:
|
||||||
regex_.setPatternOptions(QRegularExpression::CaseInsensitiveOption |
|
regex_.setPatternOptions(QRegularExpression::CaseInsensitiveOption |
|
||||||
QRegularExpression::UseUnicodePropertiesOption);
|
QRegularExpression::UseUnicodePropertiesOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &accvec = getApp()->accounts->twitch.accounts.getVector();
|
|
||||||
for (const auto &acc : accvec) {
|
|
||||||
const auto &accemotes = *acc->accessEmotes();
|
|
||||||
for (const auto &emote : accemotes.emotes) {
|
|
||||||
if (this->replace_.contains(emote.first.string, Qt::CaseSensitive)) {
|
|
||||||
this->emotes_.emplace(emote.first, emote.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString &getPattern() const
|
const QString &getPattern() const
|
||||||
|
@ -107,6 +97,18 @@ public:
|
||||||
|
|
||||||
bool containsEmote() const
|
bool containsEmote() const
|
||||||
{
|
{
|
||||||
|
if (!this->emotesChecked_) {
|
||||||
|
const auto &accvec = getApp()->accounts->twitch.accounts.getVector();
|
||||||
|
for (const auto &acc : accvec) {
|
||||||
|
const auto &accemotes = *acc->accessEmotes();
|
||||||
|
for (const auto &emote : accemotes.emotes) {
|
||||||
|
if (this->replace_.contains(emote.first.string, Qt::CaseSensitive)) {
|
||||||
|
this->emotes_.emplace(emote.first, emote.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->emotesChecked_ = true;
|
||||||
|
}
|
||||||
return !this->emotes_.empty();
|
return !this->emotes_.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +119,8 @@ private:
|
||||||
bool isBlock_;
|
bool isBlock_;
|
||||||
QString replace_;
|
QString replace_;
|
||||||
bool isCaseSensitive_;
|
bool isCaseSensitive_;
|
||||||
std::unordered_map<EmoteName, EmotePtr> emotes_;
|
mutable std::unordered_map<EmoteName, EmotePtr> emotes_;
|
||||||
|
mutable bool emotesChecked_{false};
|
||||||
};
|
};
|
||||||
} // namespace chatterino
|
} // namespace chatterino
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QMediaPlayer>
|
#include <QMediaPlayer>
|
||||||
|
#include <QStringRef>
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
@ -156,36 +157,39 @@ MessagePtr TwitchMessageBuilder::build()
|
||||||
}
|
}
|
||||||
auto app = getApp();
|
auto app = getApp();
|
||||||
const auto &phrases = app->ignores->phrases.getVector();
|
const auto &phrases = app->ignores->phrases.getVector();
|
||||||
auto removeEmotesInRange = [&twitchEmotes](int pos, int len) mutable {
|
auto removeEmotesInRange =
|
||||||
auto it = std::remove_if(
|
[](int pos, int len,
|
||||||
twitchEmotes.begin(), twitchEmotes.end(), [&pos, &len](const auto &item) {
|
std::vector<std::tuple<int, EmotePtr, EmoteName>> &twitchEmotes) mutable {
|
||||||
return ((std::get<0>(item) >= pos) && std::get<0>(item) < (pos + len));
|
auto it = std::partition(
|
||||||
});
|
twitchEmotes.begin(), twitchEmotes.end(), [pos, len](const auto &item) {
|
||||||
for (; it != twitchEmotes.end(); ++it) {
|
return !((std::get<0>(item) >= pos) && std::get<0>(item) < (pos + len));
|
||||||
if (std::get<1>(*it) == nullptr) {
|
});
|
||||||
log("remem nullptr {}", std::get<2>(*it).string);
|
for (auto copy = it; copy != twitchEmotes.end(); ++copy) {
|
||||||
|
if (std::get<1>(*copy) == nullptr) {
|
||||||
|
log("remem nullptr {}", std::get<2>(*copy).string);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
std::vector<std::tuple<int, EmotePtr, EmoteName>> v(it, twitchEmotes.end());
|
||||||
std::vector<std::tuple<int, EmotePtr, EmoteName>> v(it, twitchEmotes.end());
|
twitchEmotes.erase(it, twitchEmotes.end());
|
||||||
twitchEmotes.erase(it, twitchEmotes.end());
|
return v;
|
||||||
return v;
|
};
|
||||||
};
|
|
||||||
|
|
||||||
auto shiftIndicesAfter = [&twitchEmotes](int pos, int by) mutable {
|
auto shiftIndicesAfter = [&twitchEmotes](int pos, int by) mutable {
|
||||||
auto it = std::find_if(twitchEmotes.begin(), twitchEmotes.end(),
|
for (auto &item : twitchEmotes) {
|
||||||
[&pos](const auto &item) { return std::get<0>(item) >= pos; });
|
auto &index = std::get<0>(item);
|
||||||
while (it != twitchEmotes.end()) {
|
if (index >= pos) {
|
||||||
std::get<0>(*it) += by;
|
index += by;
|
||||||
++it;
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto addReplEmotes = [&twitchEmotes](const IgnorePhrase &phrase, const QString &midrepl,
|
auto addReplEmotes = [&twitchEmotes](const IgnorePhrase &phrase, const QStringRef &midrepl,
|
||||||
int startIndex) mutable {
|
int startIndex) mutable {
|
||||||
if (!phrase.containsEmote()) {
|
if (!phrase.containsEmote()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QStringList words = midrepl.split(' ');
|
|
||||||
|
QVector<QStringRef> words = midrepl.split(' ');
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
for (const auto &word : words) {
|
for (const auto &word : words) {
|
||||||
for (const auto &emote : phrase.getEmotes()) {
|
for (const auto &emote : phrase.getEmotes()) {
|
||||||
|
@ -214,17 +218,14 @@ MessagePtr TwitchMessageBuilder::build()
|
||||||
int from = 0;
|
int from = 0;
|
||||||
while ((from = this->originalMessage_.indexOf(regex, from, &match)) != -1) {
|
while ((from = this->originalMessage_.indexOf(regex, from, &match)) != -1) {
|
||||||
int len = match.capturedLength();
|
int len = match.capturedLength();
|
||||||
auto vret = removeEmotesInRange(from, len);
|
auto vret = removeEmotesInRange(from, len, twitchEmotes);
|
||||||
auto mid = this->originalMessage_.mid(from, len);
|
auto mid = this->originalMessage_.mid(from, len);
|
||||||
mid.replace(regex, phrase.getReplace());
|
mid.replace(regex, phrase.getReplace());
|
||||||
|
|
||||||
// hemirt
|
/*for (auto &tup : vret) {
|
||||||
// doesnt check for own emotes in the Replace part
|
|
||||||
// mb in IgnoredPhrase ??
|
|
||||||
|
|
||||||
for (auto &tup : vret) {
|
|
||||||
if (std::get<1>(tup) == nullptr) {
|
if (std::get<1>(tup) == nullptr) {
|
||||||
log("v nullptr {}", std::get<2>(tup).string);
|
log("v nullptr {}", std::get<2>(tup).string);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
int index = 0;
|
int index = 0;
|
||||||
const auto &emote = std::get<2>(tup);
|
const auto &emote = std::get<2>(tup);
|
||||||
|
@ -233,14 +234,45 @@ MessagePtr TwitchMessageBuilder::build()
|
||||||
index += emote.string.size();
|
index += emote.string.size();
|
||||||
twitchEmotes.push_back(tup);
|
twitchEmotes.push_back(tup);
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
int midsize = mid.size();
|
||||||
|
this->originalMessage_.replace(from, len, mid);
|
||||||
|
int pos1 = from;
|
||||||
|
while (pos1 > 0) {
|
||||||
|
if (this->originalMessage_[pos1 - 1] == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--pos1;
|
||||||
|
}
|
||||||
|
int pos2 = from + midsize;
|
||||||
|
while (pos2 < this->originalMessage_.length()) {
|
||||||
|
if (this->originalMessage_[pos2] == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++pos2;
|
||||||
}
|
}
|
||||||
|
|
||||||
addReplEmotes(phrase, mid, from);
|
shiftIndicesAfter(from + len, midsize - len);
|
||||||
|
|
||||||
|
auto midExtendedRef = this->originalMessage_.midRef(pos1, pos2 - pos1);
|
||||||
|
|
||||||
|
for (auto &tup : vret) {
|
||||||
|
if (std::get<1>(tup) == nullptr) {
|
||||||
|
log("v nullptr {}", std::get<2>(tup).string);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int index = 0;
|
||||||
|
QString emote = " " + std::get<2>(tup).string + " ";
|
||||||
|
while ((index = midExtendedRef.indexOf(emote, index)) != -1) {
|
||||||
|
std::get<0>(tup) = from + index + 1;
|
||||||
|
index += emote.size() - 1;
|
||||||
|
twitchEmotes.push_back(tup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addReplEmotes(phrase, midExtendedRef, pos1);
|
||||||
|
|
||||||
this->originalMessage_.replace(from, len, mid);
|
|
||||||
int midsize = mid.size();
|
|
||||||
from += midsize;
|
from += midsize;
|
||||||
shiftIndicesAfter(from, midsize - len);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const auto &pattern = phrase.getPattern();
|
const auto &pattern = phrase.getPattern();
|
||||||
|
@ -251,16 +283,13 @@ MessagePtr TwitchMessageBuilder::build()
|
||||||
while ((from = this->originalMessage_.indexOf(pattern, from,
|
while ((from = this->originalMessage_.indexOf(pattern, from,
|
||||||
phrase.caseSensitivity())) != -1) {
|
phrase.caseSensitivity())) != -1) {
|
||||||
int len = pattern.size();
|
int len = pattern.size();
|
||||||
auto vret = removeEmotesInRange(from, len);
|
auto vret = removeEmotesInRange(from, len, twitchEmotes);
|
||||||
auto replace = phrase.getReplace();
|
auto replace = phrase.getReplace();
|
||||||
|
|
||||||
// hemirt
|
/*for (auto &tup : vret) {
|
||||||
// doesnt check for own emotes in the Replace part
|
|
||||||
// mb in IgnoredPhrase ??
|
|
||||||
|
|
||||||
for (auto &tup : vret) {
|
|
||||||
if (std::get<1>(tup) == nullptr) {
|
if (std::get<1>(tup) == nullptr) {
|
||||||
log("v nullptr {}", std::get<2>(tup).string);
|
log("v nullptr {}", std::get<2>(tup).string);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
int index = 0;
|
int index = 0;
|
||||||
const auto &emote = std::get<2>(tup);
|
const auto &emote = std::get<2>(tup);
|
||||||
|
@ -269,14 +298,47 @@ MessagePtr TwitchMessageBuilder::build()
|
||||||
index += emote.string.size();
|
index += emote.string.size();
|
||||||
twitchEmotes.push_back(tup);
|
twitchEmotes.push_back(tup);
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
int replacesize = replace.size();
|
||||||
|
this->originalMessage_.replace(from, len, replace);
|
||||||
|
|
||||||
|
int pos1 = from;
|
||||||
|
while (pos1 > 0) {
|
||||||
|
if (this->originalMessage_[pos1 - 1] == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--pos1;
|
||||||
|
}
|
||||||
|
int pos2 = from + replacesize;
|
||||||
|
while (pos2 < this->originalMessage_.length()) {
|
||||||
|
if (this->originalMessage_[pos2] == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++pos2;
|
||||||
}
|
}
|
||||||
|
|
||||||
addReplEmotes(phrase, replace, from);
|
shiftIndicesAfter(from + len, replacesize - len);
|
||||||
|
|
||||||
|
auto midExtendedRef = this->originalMessage_.midRef(pos1, pos2 - pos1);
|
||||||
|
|
||||||
|
for (auto &tup : vret) {
|
||||||
|
if (std::get<1>(tup) == nullptr) {
|
||||||
|
log("v nullptr {}", std::get<2>(tup).string);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int index = 0;
|
||||||
|
QString emote = " " + std::get<2>(tup).string + " ";
|
||||||
|
while ((index = midExtendedRef.indexOf(emote, index)) != -1) {
|
||||||
|
std::get<0>(tup) = from + index + 1;
|
||||||
|
index += emote.size() - 1;
|
||||||
|
twitchEmotes.push_back(tup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addReplEmotes(phrase, midExtendedRef, pos1);
|
||||||
|
|
||||||
this->originalMessage_.replace(from, len, replace);
|
|
||||||
int replacesize = replace.size();
|
|
||||||
from += replacesize;
|
from += replacesize;
|
||||||
shiftIndicesAfter(from, replacesize - len);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,6 +370,9 @@ void TwitchMessageBuilder::addWords(
|
||||||
|
|
||||||
for (const auto &word : words) {
|
for (const auto &word : words) {
|
||||||
// check if it's a twitch emote twitch emote
|
// check if it's a twitch emote twitch emote
|
||||||
|
while (currentTwitchEmote != twitchEmotes.end() && std::get<0>(*currentTwitchEmote) < i) {
|
||||||
|
++currentTwitchEmote;
|
||||||
|
}
|
||||||
if (currentTwitchEmote != twitchEmotes.end() && std::get<0>(*currentTwitchEmote) == i) {
|
if (currentTwitchEmote != twitchEmotes.end() && std::get<0>(*currentTwitchEmote) == i) {
|
||||||
auto emoteImage = std::get<1>(*currentTwitchEmote);
|
auto emoteImage = std::get<1>(*currentTwitchEmote);
|
||||||
if (emoteImage == nullptr) {
|
if (emoteImage == nullptr) {
|
||||||
|
|
Loading…
Reference in a new issue