2017-01-18 04:33:30 +01:00
|
|
|
#include "emojis.h"
|
2017-04-12 17:46:44 +02:00
|
|
|
#include "emotemanager.h"
|
2017-01-18 04:33:30 +01:00
|
|
|
|
2017-01-07 20:43:55 +01:00
|
|
|
#include <QFile>
|
2017-01-11 18:52:09 +01:00
|
|
|
#include <QStringBuilder>
|
2017-01-07 20:43:55 +01:00
|
|
|
#include <QTextStream>
|
|
|
|
|
2017-04-14 17:52:22 +02:00
|
|
|
namespace chatterino {
|
2017-01-18 21:30:23 +01:00
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
QRegularExpression Emojis::findShortCodesRegex(":([-+\\w]+):");
|
2017-01-07 20:43:55 +01:00
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
QMap<QString, Emojis::EmojiData> Emojis::shortCodeToEmoji;
|
|
|
|
QMap<QString, QString> Emojis::emojiToShortCode;
|
|
|
|
QMap<QChar, QMap<QString, QString>> Emojis::firstEmojiChars;
|
2017-01-07 20:43:55 +01:00
|
|
|
|
2017-01-18 21:30:23 +01:00
|
|
|
ConcurrentMap<QString, messages::LazyLoadedImage *> Emojis::imageCache;
|
2017-01-07 20:43:55 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
QString Emojis::replaceShortCodes(const QString &text)
|
2017-01-07 20:43:55 +01:00
|
|
|
{
|
2017-01-15 17:21:28 +01:00
|
|
|
// TODO: Implement this xD
|
2017-01-07 20:43:55 +01:00
|
|
|
return text;
|
|
|
|
}
|
2017-01-06 23:28:48 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
void Emojis::parseEmojis(std::vector<std::tuple<messages::LazyLoadedImage *, QString>> &vector,
|
|
|
|
const QString &text)
|
2017-01-06 23:28:48 +01:00
|
|
|
{
|
2017-01-07 20:43:55 +01:00
|
|
|
long lastSlice = 0;
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
for (auto i = 0; i < text.length() - 1; i++) {
|
|
|
|
if (!text.at(i).isLowSurrogate()) {
|
2017-01-18 04:33:30 +01:00
|
|
|
auto iter = firstEmojiChars.find(text.at(i));
|
2017-01-07 20:43:55 +01:00
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
if (iter != firstEmojiChars.end()) {
|
2017-01-11 18:52:09 +01:00
|
|
|
for (auto j = std::min(8, text.length() - i); j > 0; j--) {
|
2017-01-07 20:43:55 +01:00
|
|
|
QString emojiString = text.mid(i, 2);
|
|
|
|
auto emojiIter = iter.value().find(emojiString);
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
if (emojiIter != iter.value().end()) {
|
|
|
|
QString url = "https://cdnjs.cloudflare.com/ajax/libs/"
|
|
|
|
"emojione/2.2.6/assets/png/" +
|
|
|
|
emojiIter.value() + ".png";
|
2017-01-07 20:43:55 +01:00
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
if (i - lastSlice != 0) {
|
2017-04-12 17:46:44 +02:00
|
|
|
vector.push_back(std::tuple<messages::LazyLoadedImage *, QString>(
|
|
|
|
NULL, text.mid(lastSlice, i - lastSlice)));
|
2017-01-07 20:43:55 +01:00
|
|
|
}
|
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
vector.push_back(std::tuple<messages::LazyLoadedImage *, QString>(
|
|
|
|
imageCache.getOrAdd(
|
|
|
|
url, [&url] { return new messages::LazyLoadedImage(url, 0.35); }),
|
|
|
|
QString()));
|
2017-01-07 20:43:55 +01:00
|
|
|
|
|
|
|
i += j - 1;
|
2017-01-06 23:28:48 +01:00
|
|
|
|
2017-01-07 20:43:55 +01:00
|
|
|
lastSlice = i + 1;
|
2017-01-06 23:28:48 +01:00
|
|
|
|
2017-01-07 20:43:55 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
if (lastSlice < text.length()) {
|
2017-04-12 17:46:44 +02:00
|
|
|
vector.push_back(
|
|
|
|
std::tuple<messages::LazyLoadedImage *, QString>(NULL, text.mid(lastSlice)));
|
2017-01-07 20:43:55 +01:00
|
|
|
}
|
2017-01-06 23:28:48 +01:00
|
|
|
}
|
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
void Emojis::loadEmojis()
|
2017-01-06 23:28:48 +01:00
|
|
|
{
|
2017-01-07 20:43:55 +01:00
|
|
|
QFile file(":/emojidata.txt");
|
|
|
|
file.open(QFile::ReadOnly);
|
|
|
|
QTextStream in(&file);
|
|
|
|
|
|
|
|
uint emotes[4];
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
while (!in.atEnd()) {
|
2017-01-07 20:43:55 +01:00
|
|
|
QString line = in.readLine();
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
if (line.length() < 3 || line.at(0) == '#')
|
|
|
|
continue;
|
2017-01-07 20:43:55 +01:00
|
|
|
|
|
|
|
QStringList a = line.split(' ');
|
2017-01-11 18:52:09 +01:00
|
|
|
if (a.length() < 2)
|
|
|
|
continue;
|
2017-01-07 20:43:55 +01:00
|
|
|
|
|
|
|
QStringList b = a.at(1).split('-');
|
2017-01-11 18:52:09 +01:00
|
|
|
if (b.length() < 1)
|
|
|
|
continue;
|
2017-01-07 20:43:55 +01:00
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
2017-01-11 18:52:09 +01:00
|
|
|
for (const QString &item : b) {
|
2017-01-07 20:43:55 +01:00
|
|
|
emotes[i++] = QString(item).toUInt(nullptr, 16);
|
|
|
|
}
|
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
shortCodeToEmoji.insert(a.at(0), Emojis::EmojiData{QString::fromUcs4(emotes, i), a.at(1)});
|
2017-01-07 20:43:55 +01:00
|
|
|
}
|
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
for (auto const &emoji : shortCodeToEmoji.toStdMap()) {
|
|
|
|
emojiToShortCode.insert(emoji.second.value, emoji.first);
|
2017-01-07 20:43:55 +01:00
|
|
|
}
|
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
for (auto const &emoji : shortCodeToEmoji.toStdMap()) {
|
|
|
|
auto iter = firstEmojiChars.find(emoji.first.at(0));
|
2017-01-06 23:28:48 +01:00
|
|
|
|
2017-01-18 04:33:30 +01:00
|
|
|
if (iter != firstEmojiChars.end()) {
|
2017-01-07 20:43:55 +01:00
|
|
|
iter.value().insert(emoji.second.value, emoji.second.value);
|
|
|
|
continue;
|
|
|
|
}
|
2017-01-06 23:28:48 +01:00
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
firstEmojiChars.insert(emoji.first.at(0),
|
|
|
|
QMap<QString, QString>{{emoji.second.value, emoji.second.code}});
|
2017-01-07 20:43:55 +01:00
|
|
|
}
|
2017-01-06 23:28:48 +01:00
|
|
|
}
|
2017-01-18 21:30:23 +01:00
|
|
|
}
|