Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into chatterino7
Browse files Browse the repository at this point in the history
Now we're on commit 0021290; Changes from upstream we pulled:

- Bugfix: Fix reconnecting when IRC write connection is lost (Chatterino#1831, Chatterino#2356, Chatterino#2850, Chatterino#2892)
- Bugfix: Fixed subscription emotes showing up incorrectly in the emote menu. (Chatterino#2905)

Changes added in Chatterino7 only:

- Major: Added 7tv badges. (2154981)
- Minor: Fixed potential issues preventing 7tv emotes from loading (c0b1117)
  • Loading branch information
zneix committed Jun 25, 2021
2 parents 5cc388b + 0021290 commit 20a7127
Show file tree
Hide file tree
Showing 25 changed files with 264 additions and 75 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unversioned

## 2.3.3

- Major: Added username autocompletion popup menu when typing usernames with an @ prefix. (#1979, #2866)
- Major: Added ability to toggle visibility of Channel Tabs - This can be done by right-clicking the tab area or pressing the keyboard shortcut (default: Ctrl+U). (#2600)
- Minor: The /live split now shows channels going offline. (#2880)
Expand All @@ -20,8 +22,9 @@
- Bugfix: Moderation buttons now show the correct time unit when using units other than seconds. (#1719, #2864)
- Bugfix: Fixed FFZ emote links for global emotes (#2807, #2808)
- Bugfix: Fixed pasting text with URLs included (#1688, #2855)
- Bugfix: Fix reconnecting when IRC write connection is lost (#1831, #2356, #2850)
- Bugfix: Fix reconnecting when IRC write connection is lost (#1831, #2356, #2850, #2892)
- Bugfix: Fixed bit and new subscriber emotes not (re)loading in some rare cases. (#2856, #2857)
- Bugfix: Fixed subscription emotes showing up incorrectly in the emote menu. (#2905)

## 2.3.2

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ list(APPEND CMAKE_MODULE_PATH
"${CMAKE_SOURCE_DIR}/cmake/sanitizers-cmake/cmake"
)

project(chatterino VERSION 2.3.2)
project(chatterino VERSION 2.3.3)

option(BUILD_APP "Build Chatterino" ON)
option(BUILD_TESTS "Build the tests for Chatterino" OFF)
Expand Down
2 changes: 1 addition & 1 deletion resources/com.chatterino.chatterino.appdata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
<binary>chatterino</binary>
</provides>
<releases>
<release version="2.3.2" date="2021-04-18"/>
<release version="2.3.3" date="2021-06-21"/>
</releases>
</component>
2 changes: 1 addition & 1 deletion src/common/Version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <QString>
#include <QtGlobal>

#define CHATTERINO_VERSION "7.3.2"
#define CHATTERINO_VERSION "7.3.3"

#if defined(Q_OS_WIN)
# define CHATTERINO_OS "win"
Expand Down
10 changes: 10 additions & 0 deletions src/messages/Image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,16 @@ void Image::actuallyLoad()
QBuffer buffer(const_cast<QByteArray *>(&data));
buffer.open(QIODevice::ReadOnly);
QImageReader reader(&buffer);

if (reader.size().width() * reader.size().height() *
reader.imageCount() * 4 >
Image::maxBytesRam)
{
qCDebug(chatterinoImage) << "image too large in RAM";

return Failure;
}

auto parsed = detail::readFrames(reader, shared->url());

postToThread(makeConvertCallback(parsed, [weak](auto frames) {
Expand Down
3 changes: 3 additions & 0 deletions src/messages/Image.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ using ImagePtr = std::shared_ptr<Image>;
class Image : public std::enable_shared_from_this<Image>, boost::noncopyable
{
public:
// Maximum amount of RAM used by the image in bytes.
static constexpr int maxBytesRam = 20 * 1024 * 1024;

~Image();

static ImagePtr fromUrl(const Url &url, qreal scale = 1);
Expand Down
1 change: 1 addition & 0 deletions src/messages/MessageBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class MessageBuilder
MessageBuilder(const BanAction &action, uint32_t count = 1);
MessageBuilder(const UnbanAction &action);
MessageBuilder(const AutomodUserAction &action);
virtual ~MessageBuilder() = default;

Message *operator->();
Message &message();
Expand Down
8 changes: 6 additions & 2 deletions src/messages/SharedMessageBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ void SharedMessageBuilder::parse()
{
this->parseUsernameColor();

if (this->action_)
{
this->textColor_ = this->usernameColor_;
}

this->parseUsername();

this->message().flags.set(MessageFlag::Collapsed);
Expand Down Expand Up @@ -408,8 +413,7 @@ void SharedMessageBuilder::addTextOrEmoji(const QString &string_)
// Actually just text
auto linkString = this->matchLink(string);
auto link = Link();
auto textColor = this->action_ ? MessageColor(this->usernameColor_)
: MessageColor(MessageColor::Text);
auto &&textColor = this->textColor_;

if (linkString.isEmpty())
{
Expand Down
4 changes: 3 additions & 1 deletion src/messages/SharedMessageBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "common/Aliases.hpp"
#include "common/Outcome.hpp"
#include "messages/MessageColor.hpp"

#include <IrcMessage>
#include <QColor>
Expand Down Expand Up @@ -59,7 +60,8 @@ class SharedMessageBuilder : public MessageBuilder

const bool action_{};

QColor usernameColor_;
QColor usernameColor_ = {153, 153, 153};
MessageColor textColor_ = MessageColor::Text;

bool highlightAlert_ = false;
bool highlightSound_ = false;
Expand Down
19 changes: 4 additions & 15 deletions src/providers/irc/IrcConnection2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@

namespace chatterino {

// The minimum interval between attempting to establish a new connection
const int RECONNECT_MIN_INTERVAL = 15000;

namespace {

const auto payload = QString("chatterino/" CHATTERINO_VERSION);
Expand Down Expand Up @@ -48,18 +45,11 @@ IrcConnection::IrcConnection(QObject *parent)
return;
}

auto delta =
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - this->lastConnected_)
.count();
delta = delta < RECONNECT_MIN_INTERVAL
? (RECONNECT_MIN_INTERVAL - delta)
: 10;
qCDebug(chatterinoIrc) << "Reconnecting in" << delta << "ms";
this->reconnectTimer_.start(delta);
auto delay = this->reconnectBackoff_.next();
qCDebug(chatterinoIrc) << "Reconnecting in" << delay.count() << "ms";
this->reconnectTimer_.start(delay);
});

this->reconnectTimer_.setInterval(RECONNECT_MIN_INTERVAL);
this->reconnectTimer_.setSingleShot(true);
QObject::connect(&this->reconnectTimer_, &QTimer::timeout, [this] {
if (this->isConnected())
Expand Down Expand Up @@ -120,13 +110,12 @@ IrcConnection::IrcConnection(QObject *parent)
[this](Communi::IrcMessage *message) {
// This connection is probably still alive
this->recentlyReceivedMessage_ = true;
this->reconnectBackoff_.reset();
});
}

void IrcConnection::open()
{
// Accurately track the time a connection was opened
this->lastConnected_ = std::chrono::steady_clock::now();
this->expectConnectionLoss_ = false;
this->waitingForPong_ = false;
this->recentlyReceivedMessage_ = false;
Expand Down
7 changes: 5 additions & 2 deletions src/providers/irc/IrcConnection2.hpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#pragma once

#include "util/ExponentialBackoff.hpp"

#include <pajlada/signals/signal.hpp>

#include <IrcConnection>
#include <QTimer>
#include <chrono>

namespace chatterino {

Expand All @@ -28,7 +29,9 @@ class IrcConnection : public Communi::IrcConnection
QTimer pingTimer_;
QTimer reconnectTimer_;
std::atomic<bool> recentlyReceivedMessage_{true};
std::chrono::steady_clock::time_point lastConnected_;

// Reconnect with a base delay of 1 second and max out at 1 second * (2^4) (i.e. 16 seconds)
ExponentialBackoff<4> reconnectBackoff_{std::chrono::milliseconds{1000}};

std::atomic<bool> expectConnectionLoss_{false};

Expand Down
2 changes: 0 additions & 2 deletions src/providers/irc/IrcMessageBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ IrcMessageBuilder::IrcMessageBuilder(
const MessageParseArgs &_args)
: SharedMessageBuilder(_channel, _ircMessage, _args)
{
this->usernameColor_ = getApp()->themes->messages.textColors.system;
}

IrcMessageBuilder::IrcMessageBuilder(Channel *_channel,
Expand All @@ -31,7 +30,6 @@ IrcMessageBuilder::IrcMessageBuilder(Channel *_channel,
: SharedMessageBuilder(_channel, _ircMessage, _args, content, isAction)
{
assert(false);
this->usernameColor_ = getApp()->themes->messages.textColors.system;
}

MessagePtr IrcMessageBuilder::build()
Expand Down
69 changes: 39 additions & 30 deletions src/providers/twitch/TwitchAccount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,6 @@ void TwitchAccount::loadUserstateEmotes()
name[0] = name[0].toUpper();

newUserEmoteSet->text = name;
newUserEmoteSet->type = QString();
newUserEmoteSet->channelName = ivrEmoteSet.login;

for (const auto &emote : ivrEmoteSet.emotes)
Expand Down Expand Up @@ -508,38 +507,48 @@ void TwitchAccount::loadEmoteSetData(std::shared_ptr<EmoteSet> emoteSet)
return;
}

NetworkRequest(Env::get().twitchEmoteSetResolverUrl.arg(emoteSet->key))
.cache()
.onSuccess([emoteSet](NetworkResult result) -> Outcome {
auto root = result.parseJson();
if (root.isEmpty())
getHelix()->getEmoteSetData(
emoteSet->key,
[emoteSet](HelixEmoteSetData emoteSetData) {
if (emoteSetData.ownerId.isEmpty() ||
emoteSetData.setId != emoteSet->key)
{
return Failure;
qCWarning(chatterinoTwitch)
<< QString("Failed to fetch emoteSetData for %1, assuming "
"Twitch is the owner")
.arg(emoteSet->key);

// most (if not all) emotes that fail to load are time limited event emotes owned by Twitch
emoteSet->channelName = "twitch";
emoteSet->text = "Twitch";

return;
}

TwitchEmoteSetResolverResponse response(root);

auto name = response.channelName;
name.detach();
name[0] = name[0].toUpper();

emoteSet->text = name;
emoteSet->type = response.type;
emoteSet->channelName = response.channelName;

qCDebug(chatterinoTwitch)
<< QString("Loaded twitch emote set data for %1")
.arg(emoteSet->key);

return Success;
})
.onError([emoteSet](NetworkResult result) {
qCWarning(chatterinoTwitch)
<< QString("Error code %1 while loading emote set data for %2")
.arg(result.status())
.arg(emoteSet->key);
})
.execute();
// emote set 0 = global emotes
if (emoteSetData.ownerId == "0")
{
// emoteSet->channelName = QString();
emoteSet->text = "Twitch Global";
return;
}

getHelix()->getUserById(
emoteSetData.ownerId,
[emoteSet](HelixUser user) {
emoteSet->channelName = user.login;
emoteSet->text = user.displayName;
},
[emoteSetData] {
qCWarning(chatterinoTwitch)
<< "Failed to query user by id:" << emoteSetData.ownerId
<< emoteSetData.setId;
});
},
[emoteSet] {
// fetching emoteset data failed
return;
});
}

} // namespace chatterino
1 change: 0 additions & 1 deletion src/providers/twitch/TwitchAccount.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ class TwitchAccount : public Account
QString key;
QString channelName;
QString text;
QString type;
std::vector<TwitchEmote> emotes;
};

Expand Down
16 changes: 5 additions & 11 deletions src/providers/twitch/TwitchMessageBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ TwitchMessageBuilder::TwitchMessageBuilder(
: SharedMessageBuilder(_channel, _ircMessage, _args)
, twitchChannel(dynamic_cast<TwitchChannel *>(_channel))
{
this->usernameColor_ = getApp()->themes->messages.textColors.system;
}

TwitchMessageBuilder::TwitchMessageBuilder(
Expand All @@ -127,7 +126,6 @@ TwitchMessageBuilder::TwitchMessageBuilder(
: SharedMessageBuilder(_channel, _ircMessage, _args, content, isAction)
, twitchChannel(dynamic_cast<TwitchChannel *>(_channel))
{
this->usernameColor_ = getApp()->themes->messages.textColors.system;
}

bool TwitchMessageBuilder::isIgnored() const
Expand Down Expand Up @@ -470,8 +468,7 @@ void TwitchMessageBuilder::addTextOrEmoji(const QString &string_)

// Actually just text
auto linkString = this->matchLink(string);
auto textColor = this->action_ ? MessageColor(this->usernameColor_)
: MessageColor(MessageColor::Text);
auto textColor = this->textColor_;

if (!linkString.isEmpty())
{
Expand Down Expand Up @@ -727,18 +724,15 @@ void TwitchMessageBuilder::appendUsername()

// Separator
this->emplace<TextElement>("->", MessageElementFlag::Username,
app->themes->messages.textColors.system,
FontStyle::ChatMedium);
MessageColor::System, FontStyle::ChatMedium);

QColor selfColor = currentUser->color();
if (!selfColor.isValid())
{
selfColor = app->themes->messages.textColors.system;
}
MessageColor selfMsgColor =
selfColor.isValid() ? selfColor : MessageColor::System;

// Your own username
this->emplace<TextElement>(currentUser->getUserName() + ":",
MessageElementFlag::Username, selfColor,
MessageElementFlag::Username, selfMsgColor,
FontStyle::ChatMediumBold);
}
else
Expand Down
32 changes: 32 additions & 0 deletions src/providers/twitch/api/Helix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,38 @@ void Helix::getCheermotes(
.execute();
}

void Helix::getEmoteSetData(QString emoteSetId,
ResultCallback<HelixEmoteSetData> successCallback,
HelixFailureCallback failureCallback)
{
QUrlQuery urlQuery;

urlQuery.addQueryItem("emote_set_id", emoteSetId);

this->makeRequest("chat/emotes/set", urlQuery)
.onSuccess([successCallback, failureCallback,
emoteSetId](auto result) -> Outcome {
QJsonObject root = result.parseJson();
auto data = root.value("data");

if (!data.isArray())
{
failureCallback();
return Failure;
}

HelixEmoteSetData emoteSetData(data.toArray()[0].toObject());

successCallback(emoteSetData);
return Success;
})
.onError([failureCallback](NetworkResult result) {
// TODO: make better xd
failureCallback();
})
.execute();
}

NetworkRequest Helix::makeRequest(QString url, QUrlQuery urlQuery)
{
assert(!url.startsWith("/"));
Expand Down
Loading

0 comments on commit 20a7127

Please sign in to comment.