added emojis

This commit is contained in:
fourtf 2017-01-06 23:28:48 +01:00
parent 4d96dcc5e3
commit 82bc101bb8
25 changed files with 2094 additions and 90 deletions

View file

@ -1,6 +1,13 @@
#include "appsettings.h"
Word::Type AppSettings::m_wordTypeMask = Word::Default;
AppSettings::AppSettings()
{
}
bool AppSettings::isIgnoredEmote(const QString &emote)
{
return false;
}

View file

@ -6,13 +6,15 @@
class AppSettings
{
public:
Word::Type wordTypeMask() {
static Word::Type wordTypeMask() {
return m_wordTypeMask;
}
static bool isIgnoredEmote(const QString& emote);
private:
AppSettings();
Word::Type m_wordTypeMask = Word::Default;
static Word::Type m_wordTypeMask;
};
#endif // APPSETTINGS_H

View file

@ -27,7 +27,7 @@ public:
QString getStreamStatus();
QString getStreamGame();
const QString& name() {
const QString& name() const {
return m_name;
}

View file

@ -55,7 +55,8 @@ SOURCES += main.cpp\
word.cpp \
link.cpp \
fonts.cpp \
appsettings.cpp
appsettings.cpp \
emojis.cpp
HEADERS += mainwindow.h \
chatwidget.h \
@ -87,7 +88,8 @@ HEADERS += mainwindow.h \
link.h \
fonts.h \
common.h \
appsettings.h
appsettings.h \
emojis.h
PRECOMPILED_HEADER = common.h

View file

@ -26,5 +26,5 @@ void ChatWidget::paintEvent(QPaintEvent *)
{
QPainter painter (this);
painter.fillRect(rect(), ColorScheme::getInstance().ChatBackground);
painter.fillRect(rect(), ColorScheme::instance().ChatBackground);
}

View file

@ -17,8 +17,8 @@ void ChatWidgetHeader::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(rect(), ColorScheme::getInstance().ChatHeaderBackground);
painter.setPen(ColorScheme::getInstance().ChatHeaderBorder);
painter.fillRect(rect(), ColorScheme::instance().ChatHeaderBackground);
painter.setPen(ColorScheme::instance().ChatHeaderBorder);
painter.drawRect(0, 0, width() - 1, height() - 1);
}

View file

@ -11,7 +11,7 @@ void ChatWidgetInput::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(rect(), ColorScheme::getInstance().ChatInputBackground);
painter.setPen(ColorScheme::getInstance().ChatInputBorder);
painter.fillRect(rect(), ColorScheme::instance().ChatInputBackground);
painter.setPen(ColorScheme::instance().ChatInputBorder);
painter.drawRect(0, 0, width() - 1, height() - 1);
}

View file

@ -56,7 +56,7 @@ public:
const int HighlightColorCount = 3;
QColor HighlightColors[3];
static ColorScheme& getInstance()
static ColorScheme& instance()
{
static ColorScheme instance;

View file

@ -1,9 +1,9 @@
#ifndef CONCURRENTMAP_H
#define CONCURRENTMAP_H
#include "QMutex"
#include "QMap"
#include "functional"
#include <QMutex>
#include <QMap>
#include <functional>
template<typename TKey, typename TValue>
class ConcurrentMap

1847
emojis.cpp Normal file

File diff suppressed because it is too large Load diff

27
emojis.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef EMOJIS_H
#define EMOJIS_H
#include <QRegularExpression>
#include <QObject>
#include <QString>
#include "lazyloadedimage.h"
#include "concurrentmap.h"
class Emojis
{
public:
std::vector<std::tuple<LazyLoadedImage*, QString>> parseEmotes(const QString& value);
static void initEmojis();
private:
static QRegularExpression* findShortCodesRegex;
static QMap<QString, QString>* shortCodeToEmoji;
static QMap<QString, QString>* emojiToShortCode;
static QMap<QChar, QMap<QString, LazyLoadedImage*>>* firstEmojiChars;
Emojis() {}
};
#endif // EMOJIS_H

View file

@ -21,6 +21,13 @@ Emotes::Emotes()
}
LazyLoadedImage* Emotes::getTwitchEmoteById(const QString &name, long id)
{
#warning "xD"
return new LazyLoadedImage(NULL);
// return m_twitchEmoteFromCache->getOrAdd()
}
LazyLoadedImage* Emotes::getCheerImage(long long amount, bool animated)
{
#warning "xD"

View file

@ -24,6 +24,8 @@ public:
static LazyLoadedImage* getCheerImage(long long int amount, bool animated);
static LazyLoadedImage* getCheerBadge(long long int amount);
static LazyLoadedImage* getTwitchEmoteById(const QString& name, long int id);
private:
Emotes();

View file

@ -1,11 +1,25 @@
#include "lazyloadedimage.h"
LazyLoadedImage::LazyLoadedImage(QString url)
LazyLoadedImage::LazyLoadedImage(const QString& url, qreal scale, const QString& name, const QString& tooltip, const QMargins& margin, bool isHat)
: m_url(url)
, m_name(name)
, m_tooltip(tooltip)
, m_animated(false)
, m_margin(margin)
, m_ishat(isHat)
, m_scale(scale)
{
}
LazyLoadedImage::LazyLoadedImage(QImage *image)
LazyLoadedImage::LazyLoadedImage(QImage *image, qreal scale, const QString& name, const QString& tooltip, const QMargins& margin, bool isHat)
: m_name(name)
, m_tooltip(tooltip)
, m_animated(false)
, m_margin(margin)
, m_ishat(isHat)
, m_scale(scale)
, m_image(image)
{
}

View file

@ -7,15 +7,34 @@
class LazyLoadedImage
{
public:
LazyLoadedImage(QString url);
LazyLoadedImage(QImage* image);
LazyLoadedImage(const QString& url, qreal scale = 1, const QString& name = "", const QString& tooltip = "", const QMargins& margin = QMargins(), bool isHat = false);
LazyLoadedImage(QImage* image, qreal scale = 1, const QString& name = "", const QString& tooltip = "", const QMargins& margin = QMargins(), bool isHat = false);
QImage* image() {
const QImage* image() const {
return m_image;
}
qreal scale() const {
return m_scale;
}
const QString& url() const { return m_url; }
const QString& name() const { return m_name; }
const QString& tooltip() const { return m_tooltip; }
const QMargins& margin() const { return m_margin; }
bool animated() const { return m_animated; }
bool isHat() const { return m_ishat; }
private:
QImage* m_image = NULL;
qreal m_scale;
QString m_url;
QString m_name;
QString m_tooltip;
bool m_animated;
QMargins m_margin;
bool m_ishat;
};
#endif // LAZYLOADEDIMAGE_H

View file

@ -2,12 +2,15 @@
#include "mainwindow.h"
#include "colorscheme.h"
#include "ircmanager.h"
#include "emojis.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ColorScheme::getInstance().setColors(0, -0.8);
Emojis::initEmojis();
ColorScheme::instance().setColors(0, -0.8);
MainWindow w;
w.show();

View file

@ -15,7 +15,7 @@ MainWindow::MainWindow(QWidget *parent) :
this->notebook.addPage();
QPalette palette;
palette.setColor(QPalette::Background, ColorScheme::getInstance().TabPanelBackground);
palette.setColor(QPalette::Background, ColorScheme::instance().TabPanelBackground);
setPalette(palette);
resize(1280, 800);

View file

@ -4,6 +4,7 @@
#include "emotes.h"
#include <ctime>
#include <QStringList>
LazyLoadedImage* Message::badgeStaff = new LazyLoadedImage(new QImage(":/images/staff_bg.png"));
LazyLoadedImage* Message::badgeAdmin = new LazyLoadedImage(new QImage(":/images/admin_bg.png"));
@ -49,65 +50,8 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
strftime(timeStampBuffer, 69, "%H:%M:%S", localtime(&time));
QString timestampWithSeconds = QString(timeStampBuffer);
words->append(Word(timestamp, Word::TimestampNoSeconds, ColorScheme::getInstance().SystemMessageColor, QString(), QString()));
words->append(Word(timestampWithSeconds, Word::TimestampWithSeconds, ColorScheme::getInstance().SystemMessageColor, QString(), QString()));
// color
QColor usernameColor = ColorScheme::getInstance().SystemMessageColor;
iterator = ircMessage.tags().find("color");
if (iterator != ircMessage.tags().end())
{
usernameColor = QColor(iterator.value().toString());
}
// channel name
if (includeChannel)
{
QString channelName("#" + channel.name());
words->append(Word(channelName, Word::Misc, QString(channelName), QString(), Link(Link::ShowMessage, channel.name() + "\n" + m_id)));
}
// username
m_userName = ircMessage.account();
if (m_userName.isEmpty())
{
auto iterator = ircMessage.tags().find("login");
if (iterator != ircMessage.tags().end())
{
m_userName = iterator.value().toString();
}
}
// display name
QString displayName;
iterator = ircMessage.tags().find("display-name");
if (iterator == ircMessage.tags().end()) {
displayName = ircMessage.account();
}
else {
displayName = iterator.value().toString();
}
bool hasLocalizedName = QString::compare(displayName, ircMessage.account()) == 0;
QString userDisplayString = displayName + (hasLocalizedName ? (" (" + ircMessage.account() + ")") : QString());
words->append(Word(userDisplayString, Word::Username, usernameColor, userDisplayString, QString()));
// highlights
#pragma message WARN("xD")
// bits
QString bits = "";
iterator = ircMessage.tags().find("bits");
if (iterator != ircMessage.tags().end())
{
bits = iterator.value().toString();
}
words->append(Word(timestamp, Word::TimestampNoSeconds, ColorScheme::instance().SystemMessageColor, QString(), QString()));
words->append(Word(timestampWithSeconds, Word::TimestampWithSeconds, ColorScheme::instance().SystemMessageColor, QString(), QString()));
// badges
iterator = ircMessage.tags().find("badges");
@ -155,5 +99,133 @@ Message::Message(const IrcPrivateMessage& ircMessage, const Channel& channel, bo
}
}
// color
QColor usernameColor = ColorScheme::instance().SystemMessageColor;
iterator = ircMessage.tags().find("color");
if (iterator != ircMessage.tags().end())
{
usernameColor = QColor(iterator.value().toString());
}
// channel name
if (includeChannel)
{
QString channelName("#" + channel.name());
words->append(Word(channelName, Word::Misc, ColorScheme::instance().SystemMessageColor, QString(channelName), QString(), Link(Link::ShowMessage, channel.name() + "\n" + m_id)));
}
// username
m_userName = ircMessage.account();
if (m_userName.isEmpty())
{
auto iterator = ircMessage.tags().find("login");
if (iterator != ircMessage.tags().end())
{
m_userName = iterator.value().toString();
}
}
QString displayName;
iterator = ircMessage.tags().find("display-name");
if (iterator == ircMessage.tags().end()) {
displayName = ircMessage.account();
}
else {
displayName = iterator.value().toString();
}
bool hasLocalizedName = QString::compare(displayName, ircMessage.account()) == 0;
QString userDisplayString = displayName + (hasLocalizedName ? (" (" + ircMessage.account() + ")") : QString());
words->append(Word(userDisplayString, Word::Username, usernameColor, userDisplayString, QString()));
// highlights
#pragma message WARN("xD")
// bits
QString bits = "";
iterator = ircMessage.tags().find("bits");
if (iterator != ircMessage.tags().end())
{
bits = iterator.value().toString();
}
// twitch emotes
QVector<std::pair<long int, LazyLoadedImage*>> twitchEmotes;
iterator = ircMessage.tags().find("emotes");
if (iterator != ircMessage.tags().end())
{
auto emotes = iterator.value().toString().split('/');
for (QString emote : emotes)
{
if (!emote.contains(':')) continue;
QStringList parameters = emote.split(':');
if (parameters.length() < 2) continue;
long int id = std::stol(parameters.at(0).toStdString(), NULL, 10);
QStringList occurences = parameters.at(1).split(',');
for (QString occurence : occurences)
{
QStringList coords = occurence.split('-');
if (coords.length() < 2) continue;
long int start = std::stol(coords.at(0).toStdString(), NULL, 10);
long int end = std::stol(coords.at(1).toStdString(), NULL, 10);
if (start >= end || start < 0 || end > ircMessage.content().length()) continue;
QString name = ircMessage.content().mid(start, end - start);
twitchEmotes.append(std::pair<long int, LazyLoadedImage*>(start, Emotes::getTwitchEmoteById(name, id)));
}
}
std::sort(twitchEmotes.begin(), twitchEmotes.end(), sortTwitchEmotes);
}
auto currentTwitchEmote = twitchEmotes.begin();
// words
QColor textColor = ircMessage.isAction() ? usernameColor : ColorScheme::instance().Text;
QStringList splits = ircMessage.content().split(' ');
long int i = 0;
for (QString split : splits)
{
// twitch emote
if (currentTwitchEmote == twitchEmotes.end()) break;
if (currentTwitchEmote->first == i)
{
words->append(Word(currentTwitchEmote->second, Word::TwitchEmoteImage, currentTwitchEmote->second->name(), currentTwitchEmote->second->name() + QString("\nTwitch Emote")));
words->append(Word(currentTwitchEmote->second->name(), Word::TwitchEmoteText, textColor, currentTwitchEmote->second->name(), currentTwitchEmote->second->name() + QString("\nTwitch Emote")));
i += split.length() + 1;
currentTwitchEmote = std::next(currentTwitchEmote);
continue;
}
// split words
}
}
bool Message::sortTwitchEmotes(const std::pair<long int, LazyLoadedImage*>& a, const std::pair<long int, LazyLoadedImage*>& b)
{
return a.first < b.first;
}

View file

@ -76,6 +76,8 @@ private:
QString m_id = "";
QList<Word> m_words;
static bool sortTwitchEmotes(const std::pair<long int, LazyLoadedImage*>& a, const std::pair<long int, LazyLoadedImage*>& b);
};
#endif // MESSAGE_H

View file

@ -17,7 +17,7 @@ void NotebookButton::paintEvent(QPaintEvent *)
QColor background;
QColor foreground;
auto colorScheme = ColorScheme::getInstance();
auto colorScheme = ColorScheme::instance();
if (mouseDown)
{

View file

@ -201,17 +201,17 @@ void NotebookPage::paintEvent(QPaintEvent *)
if (hbox.count() == 0)
{
painter.fillRect(rect(), ColorScheme::getInstance().ChatBackground);
painter.fillRect(rect(), ColorScheme::instance().ChatBackground);
painter.fillRect(0, 0, width(), 2, ColorScheme::getInstance().TabSelectedBackground);
painter.fillRect(0, 0, width(), 2, ColorScheme::instance().TabSelectedBackground);
painter.setPen(ColorScheme::getInstance().Text);
painter.setPen(ColorScheme::instance().Text);
painter.drawText(rect(), "Add Chat", QTextOption(Qt::AlignCenter));
}
else
{
painter.fillRect(rect(), ColorScheme::getInstance().TabSelectedBackground);
painter.fillRect(rect(), ColorScheme::instance().TabSelectedBackground);
painter.fillRect(0, 0, width(), 2, ColorScheme::getInstance().TabSelectedBackground);
painter.fillRect(0, 0, width(), 2, ColorScheme::instance().TabSelectedBackground);
}
}

View file

@ -12,5 +12,5 @@ void NotebookPageDropPreview::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(8, 8, width()-17, height()-17, ColorScheme::getInstance().DropPreviewBackground);
painter.fillRect(8, 8, width()-17, height()-17, ColorScheme::instance().DropPreviewBackground);
}

View file

@ -47,7 +47,7 @@ void NotebookTab::paintEvent(QPaintEvent *)
QColor fg = QColor(0, 0, 0);
auto colorScheme = ColorScheme::getInstance();
auto colorScheme = ColorScheme::instance();
if (selected)
{

View file

@ -73,7 +73,7 @@ void ScrollBar::addHighlight(ScrollBarHighlight* highlight)
void ScrollBar::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.fillRect(rect(), ColorScheme::getInstance().ScrollbarBG);
painter.fillRect(rect(), ColorScheme::instance().ScrollbarBG);
mutex.lock();

View file

@ -3,7 +3,7 @@
ScrollBarHighlight::ScrollBarHighlight(float position, int colorIndex, Style style, QString tag)
: m_position(position),
m_colorIndex(std::max(0, std::min(ColorScheme::getInstance().HighlightColorCount, colorIndex))),
m_colorIndex(std::max(0, std::min(ColorScheme::instance().HighlightColorCount, colorIndex))),
m_style(style),
m_tag(tag),
next(NULL)