fix replacement with emotes issues

This commit is contained in:
hemirt 2018-09-23 19:52:03 +02:00
parent 646268ab18
commit 1acb1278aa
2 changed files with 119 additions and 51 deletions

View file

@ -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

View file

@ -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) {