mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-13 19:49:51 +01:00
Compare commits
10 commits
a9b446ffc7
...
6d376b5416
Author | SHA1 | Date | |
---|---|---|---|
6d376b5416 | |||
c7512dc734 | |||
0163474a93 | |||
d2681a0b43 | |||
e326ce428c | |||
59bb2fe2e9 | |||
d80dd6d8a2 | |||
de40d42a60 | |||
2ec8fa8723 | |||
45d2c292d0 |
|
@ -110,7 +110,7 @@
|
||||||
- Dev: Emojis now use flags instead of a set of strings for capabilities. (#5616)
|
- Dev: Emojis now use flags instead of a set of strings for capabilities. (#5616)
|
||||||
- Dev: Move plugins to Sol2. (#5622)
|
- Dev: Move plugins to Sol2. (#5622)
|
||||||
- Dev: Refactored static `MessageBuilder` helpers to standalone functions. (#5652)
|
- Dev: Refactored static `MessageBuilder` helpers to standalone functions. (#5652)
|
||||||
- Dev: Decoupled reply parsing from `MessageBuilder`. (#5660)
|
- Dev: Decoupled reply parsing from `MessageBuilder`. (#5660, #5668)
|
||||||
- Dev: Refactored IRC message building. (#5663)
|
- Dev: Refactored IRC message building. (#5663)
|
||||||
|
|
||||||
## 2.5.1
|
## 2.5.1
|
||||||
|
|
|
@ -71,17 +71,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove(const key_t &key)
|
|
||||||
{
|
|
||||||
auto it = _cache_items_map.find(key);
|
|
||||||
if (it == _cache_items_map.end())
|
|
||||||
{
|
|
||||||
throw std::range_error("There is no such key in cache");
|
|
||||||
}
|
|
||||||
_cache_items_list.erase(it->second);
|
|
||||||
_cache_items_map.erase(it);
|
|
||||||
}
|
|
||||||
|
|
||||||
const value_t &get(const key_t &key)
|
const value_t &get(const key_t &key)
|
||||||
{
|
{
|
||||||
auto it = _cache_items_map.find(key);
|
auto it = _cache_items_map.find(key);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "common/Args.hpp"
|
#include "common/Args.hpp"
|
||||||
#include "mocks/DisabledStreamerMode.hpp"
|
#include "mocks/DisabledStreamerMode.hpp"
|
||||||
#include "mocks/EmptyApplication.hpp"
|
#include "mocks/EmptyApplication.hpp"
|
||||||
|
#include "mocks/TwitchUsers.hpp"
|
||||||
#include "providers/bttv/BttvLiveUpdates.hpp"
|
#include "providers/bttv/BttvLiveUpdates.hpp"
|
||||||
#include "singletons/Fonts.hpp"
|
#include "singletons/Fonts.hpp"
|
||||||
#include "singletons/Settings.hpp"
|
#include "singletons/Settings.hpp"
|
||||||
|
@ -55,6 +56,11 @@ public:
|
||||||
return &this->fonts;
|
return &this->fonts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ITwitchUsers *getTwitchUsers() override
|
||||||
|
{
|
||||||
|
return &this->twitchUsers;
|
||||||
|
}
|
||||||
|
|
||||||
BttvLiveUpdates *getBttvLiveUpdates() override
|
BttvLiveUpdates *getBttvLiveUpdates() override
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -71,6 +77,7 @@ public:
|
||||||
DisabledStreamerMode streamerMode;
|
DisabledStreamerMode streamerMode;
|
||||||
Theme theme;
|
Theme theme;
|
||||||
Fonts fonts;
|
Fonts fonts;
|
||||||
|
TwitchUsers twitchUsers;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace chatterino::mock
|
} // namespace chatterino::mock
|
||||||
|
|
|
@ -26,7 +26,6 @@ public:
|
||||||
, mentionsChannel(std::shared_ptr<Channel>(new MockChannel("forsen3")))
|
, mentionsChannel(std::shared_ptr<Channel>(new MockChannel("forsen3")))
|
||||||
, liveChannel(std::shared_ptr<Channel>(new MockChannel("forsen")))
|
, liveChannel(std::shared_ptr<Channel>(new MockChannel("forsen")))
|
||||||
, automodChannel(std::shared_ptr<Channel>(new MockChannel("forsen2")))
|
, automodChannel(std::shared_ptr<Channel>(new MockChannel("forsen2")))
|
||||||
, channelNamesById_(1)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,18 +49,6 @@ public:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<QString> getOrPopulateChannelCache(
|
|
||||||
const QString &channelId) override
|
|
||||||
{
|
|
||||||
if (channelId == "11148817")
|
|
||||||
return "pajlada";
|
|
||||||
if (channelId == "141981764")
|
|
||||||
return "twitchdev";
|
|
||||||
if (channelId == "1025594235")
|
|
||||||
return "shared_chat_test_01";
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void addFakeMessage(const QString &data) override
|
void addFakeMessage(const QString &data) override
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -161,7 +148,6 @@ public:
|
||||||
ChannelPtr mentionsChannel;
|
ChannelPtr mentionsChannel;
|
||||||
ChannelPtr liveChannel;
|
ChannelPtr liveChannel;
|
||||||
ChannelPtr automodChannel;
|
ChannelPtr automodChannel;
|
||||||
UniqueAccess<cache::lru_cache<QString, QString>> channelNamesById_;
|
|
||||||
QString lastUserThatWhisperedMe{"forsen"};
|
QString lastUserThatWhisperedMe{"forsen"};
|
||||||
|
|
||||||
std::unordered_map<QString, std::weak_ptr<Channel>> mockChannels;
|
std::unordered_map<QString, std::weak_ptr<Channel>> mockChannels;
|
||||||
|
|
24
mocks/include/mocks/TwitchUsers.hpp
Normal file
24
mocks/include/mocks/TwitchUsers.hpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "providers/twitch/TwitchUser.hpp"
|
||||||
|
#include "providers/twitch/TwitchUsers.hpp"
|
||||||
|
|
||||||
|
namespace chatterino::mock {
|
||||||
|
|
||||||
|
class TwitchUsers : public ITwitchUsers
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TwitchUsers() = default;
|
||||||
|
|
||||||
|
std::shared_ptr<TwitchUser> resolveID(const UserId &id)
|
||||||
|
{
|
||||||
|
TwitchUser u = {
|
||||||
|
.id = id.string,
|
||||||
|
.name = {},
|
||||||
|
.displayName = {},
|
||||||
|
};
|
||||||
|
return std::make_shared<TwitchUser>(u);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace chatterino::mock
|
|
@ -32,6 +32,7 @@
|
||||||
#include "providers/twitch/TwitchChannel.hpp"
|
#include "providers/twitch/TwitchChannel.hpp"
|
||||||
#include "providers/twitch/TwitchIrc.hpp"
|
#include "providers/twitch/TwitchIrc.hpp"
|
||||||
#include "providers/twitch/TwitchIrcServer.hpp"
|
#include "providers/twitch/TwitchIrcServer.hpp"
|
||||||
|
#include "providers/twitch/TwitchUsers.hpp"
|
||||||
#include "singletons/Emotes.hpp"
|
#include "singletons/Emotes.hpp"
|
||||||
#include "singletons/Resources.hpp"
|
#include "singletons/Resources.hpp"
|
||||||
#include "singletons/Settings.hpp"
|
#include "singletons/Settings.hpp"
|
||||||
|
@ -382,13 +383,14 @@ EmotePtr makeAutoModBadge()
|
||||||
|
|
||||||
EmotePtr makeSharedChatBadge(const QString &sourceName)
|
EmotePtr makeSharedChatBadge(const QString &sourceName)
|
||||||
{
|
{
|
||||||
return std::make_shared<Emote>(
|
return std::make_shared<Emote>(Emote{
|
||||||
Emote{"SharedChat_" + sourceName,
|
.name = EmoteName{},
|
||||||
ImageSet{Image::fromResourcePixmap(
|
.images = ImageSet{Image::fromResourcePixmap(
|
||||||
getResources().twitch.sharedChat, 0.25)},
|
getResources().twitch.sharedChat, 0.25)},
|
||||||
Tooltip{"Shared Message" +
|
.tooltip = Tooltip{"Shared Message" +
|
||||||
(sourceName.isEmpty() ? "" : " from " + sourceName)},
|
(sourceName.isEmpty() ? "" : " from " + sourceName)},
|
||||||
Url{"https://link.twitch.tv/SharedChatViewer"}});
|
.homePage = Url{"https://link.twitch.tv/SharedChatViewer"},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<std::optional<EmotePtr>, MessageElementFlags, bool> parseEmote(
|
std::tuple<std::optional<EmotePtr>, MessageElementFlags, bool> parseEmote(
|
||||||
|
@ -2393,6 +2395,11 @@ void MessageBuilder::parseThread(const QString &messageContent,
|
||||||
this->message().replyParent = parent;
|
this->message().replyParent = parent;
|
||||||
thread->addToThread(std::weak_ptr{this->message_});
|
thread->addToThread(std::weak_ptr{this->message_});
|
||||||
|
|
||||||
|
if (thread->subscribed())
|
||||||
|
{
|
||||||
|
this->message().flags.set(MessageFlag::SubscribedThread);
|
||||||
|
}
|
||||||
|
|
||||||
// enable reply flag
|
// enable reply flag
|
||||||
this->message().flags.set(MessageFlag::ReplyMessage);
|
this->message().flags.set(MessageFlag::ReplyMessage);
|
||||||
|
|
||||||
|
@ -2760,28 +2767,23 @@ void MessageBuilder::appendTwitchBadges(const QVariantMap &tags,
|
||||||
if (this->message().flags.has(MessageFlag::SharedMessage))
|
if (this->message().flags.has(MessageFlag::SharedMessage))
|
||||||
{
|
{
|
||||||
const QString sourceId = tags["source-room-id"].toString();
|
const QString sourceId = tags["source-room-id"].toString();
|
||||||
std::optional<QString> sourceName;
|
QString sourceName;
|
||||||
if (twitchChannel->roomId() == sourceId)
|
if (sourceId.isEmpty())
|
||||||
|
{
|
||||||
|
sourceName = "";
|
||||||
|
}
|
||||||
|
else if (twitchChannel->roomId() == sourceId)
|
||||||
{
|
{
|
||||||
sourceName = twitchChannel->getName();
|
sourceName = twitchChannel->getName();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sourceName =
|
sourceName =
|
||||||
getApp()->getTwitch()->getOrPopulateChannelCache(sourceId);
|
getApp()->getTwitchUsers()->resolveID({sourceId})->displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourceName.has_value())
|
this->emplace<BadgeElement>(makeSharedChatBadge(sourceName),
|
||||||
{
|
MessageElementFlag::BadgeSharedChannel);
|
||||||
const auto &name = sourceName.value();
|
|
||||||
auto *badge = this->emplace<BadgeElement>(
|
|
||||||
makeSharedChatBadge(name),
|
|
||||||
MessageElementFlag::BadgeSharedChannel);
|
|
||||||
if (!name.isEmpty())
|
|
||||||
{
|
|
||||||
badge->setLink({Link::UserInfo, name});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto badgeInfos = parseBadgeInfoTag(tags);
|
auto badgeInfos = parseBadgeInfoTag(tags);
|
||||||
|
|
|
@ -123,47 +123,34 @@ int stripLeadingReplyMention(const QVariantMap &tags, QString &content)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] bool shouldHighlightReplyThread(
|
void checkThreadSubscription(const QVariantMap &tags,
|
||||||
const QVariantMap &tags, const QString &senderLogin,
|
const QString &senderLogin,
|
||||||
std::shared_ptr<MessageThread> &thread, bool isNew)
|
std::shared_ptr<MessageThread> &thread)
|
||||||
{
|
{
|
||||||
const auto ¤tLogin =
|
if (thread->subscribed() || thread->unsubscribed())
|
||||||
getApp()->getAccounts()->twitch.getCurrent()->getUserName();
|
|
||||||
|
|
||||||
if (thread->subscribed())
|
|
||||||
{
|
{
|
||||||
return true;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (thread->unsubscribed())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getSettings()->autoSubToParticipatedThreads)
|
if (getSettings()->autoSubToParticipatedThreads)
|
||||||
{
|
{
|
||||||
if (isNew)
|
const auto ¤tLogin =
|
||||||
{
|
getApp()->getAccounts()->twitch.getCurrent()->getUserName();
|
||||||
if (const auto it = tags.find("reply-parent-user-login");
|
|
||||||
it != tags.end())
|
|
||||||
{
|
|
||||||
auto name = it.value().toString();
|
|
||||||
if (name == currentLogin)
|
|
||||||
{
|
|
||||||
thread->markSubscribed();
|
|
||||||
return true; // already marked as participated
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (senderLogin == currentLogin)
|
if (senderLogin == currentLogin)
|
||||||
{
|
{
|
||||||
thread->markSubscribed();
|
thread->markSubscribed();
|
||||||
// don't set the highlight here
|
}
|
||||||
|
else if (const auto it = tags.find("reply-parent-user-login");
|
||||||
|
it != tags.end())
|
||||||
|
{
|
||||||
|
auto name = it.value().toString();
|
||||||
|
if (name == currentLogin)
|
||||||
|
{
|
||||||
|
thread->markSubscribed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelPtr channelOrEmptyByTarget(const QString &target,
|
ChannelPtr channelOrEmptyByTarget(const QString &target,
|
||||||
|
@ -243,7 +230,6 @@ QMap<QString, QString> parseBadges(const QString &badgesString)
|
||||||
struct ReplyContext {
|
struct ReplyContext {
|
||||||
std::shared_ptr<MessageThread> thread;
|
std::shared_ptr<MessageThread> thread;
|
||||||
MessagePtr parent;
|
MessagePtr parent;
|
||||||
bool highlight = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] ReplyContext getReplyContext(
|
[[nodiscard]] ReplyContext getReplyContext(
|
||||||
|
@ -265,8 +251,7 @@ struct ReplyContext {
|
||||||
if (owned)
|
if (owned)
|
||||||
{
|
{
|
||||||
// Thread already exists (has a reply)
|
// Thread already exists (has a reply)
|
||||||
ctx.highlight = shouldHighlightReplyThread(
|
checkThreadSubscription(tags, message->nick(), owned);
|
||||||
tags, message->nick(), owned, false);
|
|
||||||
ctx.thread = owned;
|
ctx.thread = owned;
|
||||||
rootThread = owned;
|
rootThread = owned;
|
||||||
}
|
}
|
||||||
|
@ -301,8 +286,7 @@ struct ReplyContext {
|
||||||
{
|
{
|
||||||
std::shared_ptr<MessageThread> newThread =
|
std::shared_ptr<MessageThread> newThread =
|
||||||
std::make_shared<MessageThread>(foundMessage);
|
std::make_shared<MessageThread>(foundMessage);
|
||||||
ctx.highlight = shouldHighlightReplyThread(
|
checkThreadSubscription(tags, message->nick(), newThread);
|
||||||
tags, message->nick(), newThread, true);
|
|
||||||
|
|
||||||
ctx.thread = newThread;
|
ctx.thread = newThread;
|
||||||
rootThread = newThread;
|
rootThread = newThread;
|
||||||
|
@ -724,10 +708,6 @@ std::vector<MessagePtr> IrcMessageHandler::parseMessageWithReply(
|
||||||
|
|
||||||
if (built)
|
if (built)
|
||||||
{
|
{
|
||||||
if (replyCtx.highlight)
|
|
||||||
{
|
|
||||||
built->flags.set(MessageFlag::SubscribedThread);
|
|
||||||
}
|
|
||||||
builtMessages.emplace_back(built);
|
builtMessages.emplace_back(built);
|
||||||
MessageBuilder::triggerHighlights(channel, alert);
|
MessageBuilder::triggerHighlights(channel, alert);
|
||||||
}
|
}
|
||||||
|
@ -1552,8 +1532,7 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
|
||||||
{
|
{
|
||||||
// Thread already exists (has a reply)
|
// Thread already exists (has a reply)
|
||||||
auto thread = threadIt->second.lock();
|
auto thread = threadIt->second.lock();
|
||||||
replyCtx.highlight = shouldHighlightReplyThread(
|
checkThreadSubscription(tags, message->nick(), thread);
|
||||||
tags, message->nick(), thread, false);
|
|
||||||
replyCtx.thread = thread;
|
replyCtx.thread = thread;
|
||||||
rootThread = thread;
|
rootThread = thread;
|
||||||
}
|
}
|
||||||
|
@ -1565,8 +1544,7 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
|
||||||
{
|
{
|
||||||
// Found root reply message
|
// Found root reply message
|
||||||
auto newThread = std::make_shared<MessageThread>(root);
|
auto newThread = std::make_shared<MessageThread>(root);
|
||||||
replyCtx.highlight = shouldHighlightReplyThread(
|
checkThreadSubscription(tags, message->nick(), newThread);
|
||||||
tags, message->nick(), newThread, true);
|
|
||||||
|
|
||||||
replyCtx.thread = newThread;
|
replyCtx.thread = newThread;
|
||||||
rootThread = newThread;
|
rootThread = newThread;
|
||||||
|
@ -1621,10 +1599,6 @@ void IrcMessageHandler::addMessage(Communi::IrcMessage *message,
|
||||||
msg->flags.set(MessageFlag::Subscription);
|
msg->flags.set(MessageFlag::Subscription);
|
||||||
msg->flags.unset(MessageFlag::Highlighted);
|
msg->flags.unset(MessageFlag::Highlighted);
|
||||||
}
|
}
|
||||||
if (replyCtx.highlight)
|
|
||||||
{
|
|
||||||
msg->flags.set(MessageFlag::SubscribedThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
IrcMessageHandler::setSimilarityFlags(msg, chan);
|
IrcMessageHandler::setSimilarityFlags(msg, chan);
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,6 @@ TwitchIrcServer::TwitchIrcServer()
|
||||||
, liveChannel(new Channel("/live", Channel::Type::TwitchLive))
|
, liveChannel(new Channel("/live", Channel::Type::TwitchLive))
|
||||||
, automodChannel(new Channel("/automod", Channel::Type::TwitchAutomod))
|
, automodChannel(new Channel("/automod", Channel::Type::TwitchAutomod))
|
||||||
, watchingChannel(Channel::getEmpty(), Channel::Type::TwitchWatching)
|
, watchingChannel(Channel::getEmpty(), Channel::Type::TwitchWatching)
|
||||||
, channelNamesById_(512)
|
|
||||||
{
|
{
|
||||||
// Initialize the connections
|
// Initialize the connections
|
||||||
// XXX: don't create write connection if there is no separate write connection.
|
// XXX: don't create write connection if there is no separate write connection.
|
||||||
|
@ -1129,38 +1128,6 @@ std::shared_ptr<Channel> TwitchIrcServer::getChannelOrEmptyByID(
|
||||||
return Channel::getEmpty();
|
return Channel::getEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<QString> TwitchIrcServer::getOrPopulateChannelCache(
|
|
||||||
const QString &channelId)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
const auto cache = this->channelNamesById_.access();
|
|
||||||
if (cache->exists(channelId))
|
|
||||||
{
|
|
||||||
return cache->get(channelId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// prevent multiple helix requests for single user
|
|
||||||
cache->put(channelId, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
getHelix()->getUserById(
|
|
||||||
channelId,
|
|
||||||
[this](const HelixUser &user) {
|
|
||||||
const auto cache = this->channelNamesById_.access();
|
|
||||||
cache->put(user.id, user.login);
|
|
||||||
},
|
|
||||||
[this, &channelId] {
|
|
||||||
const auto cache = this->channelNamesById_.access();
|
|
||||||
if (cache->exists(channelId) && cache->get(channelId).isEmpty())
|
|
||||||
{
|
|
||||||
// invalidate cache so another helix request can be attempted
|
|
||||||
cache->remove(channelId);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QString TwitchIrcServer::cleanChannelName(const QString &dirtyChannelName)
|
QString TwitchIrcServer::cleanChannelName(const QString &dirtyChannelName)
|
||||||
{
|
{
|
||||||
if (dirtyChannelName.startsWith('#'))
|
if (dirtyChannelName.startsWith('#'))
|
||||||
|
|
|
@ -3,12 +3,10 @@
|
||||||
#include "common/Atomic.hpp"
|
#include "common/Atomic.hpp"
|
||||||
#include "common/Channel.hpp"
|
#include "common/Channel.hpp"
|
||||||
#include "common/Common.hpp"
|
#include "common/Common.hpp"
|
||||||
#include "common/UniqueAccess.hpp"
|
|
||||||
#include "providers/irc/IrcConnection2.hpp"
|
#include "providers/irc/IrcConnection2.hpp"
|
||||||
#include "util/RatelimitBucket.hpp"
|
#include "util/RatelimitBucket.hpp"
|
||||||
|
|
||||||
#include <IrcMessage>
|
#include <IrcMessage>
|
||||||
#include <lrucache/lrucache.hpp>
|
|
||||||
#include <pajlada/signals/signal.hpp>
|
#include <pajlada/signals/signal.hpp>
|
||||||
#include <pajlada/signals/signalholder.hpp>
|
#include <pajlada/signals/signalholder.hpp>
|
||||||
|
|
||||||
|
@ -45,9 +43,6 @@ public:
|
||||||
virtual ChannelPtr getOrAddChannel(const QString &dirtyChannelName) = 0;
|
virtual ChannelPtr getOrAddChannel(const QString &dirtyChannelName) = 0;
|
||||||
virtual ChannelPtr getChannelOrEmpty(const QString &dirtyChannelName) = 0;
|
virtual ChannelPtr getChannelOrEmpty(const QString &dirtyChannelName) = 0;
|
||||||
|
|
||||||
virtual std::optional<QString> getOrPopulateChannelCache(
|
|
||||||
const QString &channelId) = 0;
|
|
||||||
|
|
||||||
virtual void addFakeMessage(const QString &data) = 0;
|
virtual void addFakeMessage(const QString &data) = 0;
|
||||||
|
|
||||||
virtual void addGlobalSystemMessage(const QString &messageText) = 0;
|
virtual void addGlobalSystemMessage(const QString &messageText) = 0;
|
||||||
|
@ -100,14 +95,6 @@ public:
|
||||||
std::shared_ptr<Channel> getChannelOrEmptyByID(
|
std::shared_ptr<Channel> getChannelOrEmptyByID(
|
||||||
const QString &channelID) override;
|
const QString &channelID) override;
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtains the channel login name associated with the passed ID,
|
|
||||||
* so that Shared Chat messages can provide source channel context.
|
|
||||||
* Can yield an empty string if a helix request is already in-flight.
|
|
||||||
*/
|
|
||||||
std::optional<QString> getOrPopulateChannelCache(
|
|
||||||
const QString &channelId) override;
|
|
||||||
|
|
||||||
void reloadAllBTTVChannelEmotes();
|
void reloadAllBTTVChannelEmotes();
|
||||||
void reloadAllFFZChannelEmotes();
|
void reloadAllFFZChannelEmotes();
|
||||||
void reloadAllSevenTVChannelEmotes();
|
void reloadAllSevenTVChannelEmotes();
|
||||||
|
@ -203,9 +190,6 @@ private:
|
||||||
// https://dev.twitch.tv/docs/irc/guide#rate-limits
|
// https://dev.twitch.tv/docs/irc/guide#rate-limits
|
||||||
QObjectPtr<RatelimitBucket> joinBucket_;
|
QObjectPtr<RatelimitBucket> joinBucket_;
|
||||||
|
|
||||||
// cached channel id => name for resolving Shared Chat members
|
|
||||||
UniqueAccess<cache::lru_cache<QString, QString>> channelNamesById_;
|
|
||||||
|
|
||||||
QTimer reconnectTimer_;
|
QTimer reconnectTimer_;
|
||||||
int falloffCounter_ = 1;
|
int falloffCounter_ = 1;
|
||||||
|
|
||||||
|
|
|
@ -2408,6 +2408,11 @@ void ChannelView::handleMouseClick(QMouseEvent *event,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link.value.startsWith("id:"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Insert @username into split input
|
// Insert @username into split input
|
||||||
const bool commaMention =
|
const bool commaMention =
|
||||||
getSettings()->mentionUsersWithComma;
|
getSettings()->mentionUsersWithComma;
|
||||||
|
|
|
@ -70,15 +70,15 @@
|
||||||
"images": {
|
"images": {
|
||||||
"1x": ""
|
"1x": ""
|
||||||
},
|
},
|
||||||
"name": "SharedChat_shared_chat_test_01",
|
"name": "",
|
||||||
"tooltip": "Shared Message from shared_chat_test_01"
|
"tooltip": "Shared Message"
|
||||||
},
|
},
|
||||||
"flags": "BadgeSharedChannel",
|
"flags": "BadgeSharedChannel",
|
||||||
"link": {
|
"link": {
|
||||||
"type": "UserInfo",
|
"type": "None",
|
||||||
"value": "shared_chat_test_01"
|
"value": ""
|
||||||
},
|
},
|
||||||
"tooltip": "Shared Message from shared_chat_test_01",
|
"tooltip": "Shared Message",
|
||||||
"trailingSpace": true,
|
"trailingSpace": true,
|
||||||
"type": "BadgeElement"
|
"type": "BadgeElement"
|
||||||
},
|
},
|
||||||
|
|
|
@ -70,13 +70,13 @@
|
||||||
"images": {
|
"images": {
|
||||||
"1x": ""
|
"1x": ""
|
||||||
},
|
},
|
||||||
"name": "SharedChat_twitchdev",
|
"name": "",
|
||||||
"tooltip": "Shared Message from twitchdev"
|
"tooltip": "Shared Message from twitchdev"
|
||||||
},
|
},
|
||||||
"flags": "BadgeSharedChannel",
|
"flags": "BadgeSharedChannel",
|
||||||
"link": {
|
"link": {
|
||||||
"type": "UserInfo",
|
"type": "None",
|
||||||
"value": "twitchdev"
|
"value": ""
|
||||||
},
|
},
|
||||||
"tooltip": "Shared Message from twitchdev",
|
"tooltip": "Shared Message from twitchdev",
|
||||||
"trailingSpace": true,
|
"trailingSpace": true,
|
||||||
|
|
|
@ -70,13 +70,13 @@
|
||||||
"images": {
|
"images": {
|
||||||
"1x": ""
|
"1x": ""
|
||||||
},
|
},
|
||||||
"name": "SharedChat_twitchdev",
|
"name": "",
|
||||||
"tooltip": "Shared Message from twitchdev"
|
"tooltip": "Shared Message from twitchdev"
|
||||||
},
|
},
|
||||||
"flags": "BadgeSharedChannel",
|
"flags": "BadgeSharedChannel",
|
||||||
"link": {
|
"link": {
|
||||||
"type": "UserInfo",
|
"type": "None",
|
||||||
"value": "twitchdev"
|
"value": ""
|
||||||
},
|
},
|
||||||
"tooltip": "Shared Message from twitchdev",
|
"tooltip": "Shared Message from twitchdev",
|
||||||
"trailingSpace": true,
|
"trailingSpace": true,
|
||||||
|
|
|
@ -70,15 +70,15 @@
|
||||||
"images": {
|
"images": {
|
||||||
"1x": ""
|
"1x": ""
|
||||||
},
|
},
|
||||||
"name": "SharedChat_shared_chat_test_01",
|
"name": "",
|
||||||
"tooltip": "Shared Message from shared_chat_test_01"
|
"tooltip": "Shared Message"
|
||||||
},
|
},
|
||||||
"flags": "BadgeSharedChannel",
|
"flags": "BadgeSharedChannel",
|
||||||
"link": {
|
"link": {
|
||||||
"type": "UserInfo",
|
"type": "None",
|
||||||
"value": "shared_chat_test_01"
|
"value": ""
|
||||||
},
|
},
|
||||||
"tooltip": "Shared Message from shared_chat_test_01",
|
"tooltip": "Shared Message",
|
||||||
"trailingSpace": true,
|
"trailingSpace": true,
|
||||||
"type": "BadgeElement"
|
"type": "BadgeElement"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue