feat: improve handling of shared chat messages (#5606)
Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
This commit is contained in:
+110
-31
@@ -2677,6 +2677,26 @@ void MessageBuilder::parseRoomID()
|
||||
{
|
||||
this->twitchChannel->setRoomId(this->roomID_);
|
||||
}
|
||||
|
||||
if (auto it = this->tags.find("source-room-id"); it != this->tags.end())
|
||||
{
|
||||
auto sourceRoom = it.value().toString();
|
||||
if (this->roomID_ != sourceRoom)
|
||||
{
|
||||
this->message().flags.set(MessageFlag::SharedMessage);
|
||||
|
||||
auto sourceChan =
|
||||
getApp()->getTwitch()->getChannelOrEmptyByID(sourceRoom);
|
||||
if (sourceChan)
|
||||
{
|
||||
this->sourceChannel =
|
||||
dynamic_cast<TwitchChannel *>(sourceChan.get());
|
||||
// avoid duplicate pings
|
||||
this->message().flags.set(
|
||||
MessageFlag::DoNotTriggerNotification);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2894,18 +2914,19 @@ void MessageBuilder::appendUsername()
|
||||
}
|
||||
}
|
||||
|
||||
Outcome MessageBuilder::tryAppendEmote(const EmoteName &name)
|
||||
const TwitchChannel *MessageBuilder::getSourceChannel() const
|
||||
{
|
||||
auto *app = getApp();
|
||||
if (this->sourceChannel != nullptr)
|
||||
{
|
||||
return this->sourceChannel;
|
||||
}
|
||||
|
||||
const auto *globalBttvEmotes = app->getBttvEmotes();
|
||||
const auto *globalFfzEmotes = app->getFfzEmotes();
|
||||
const auto *globalSeventvEmotes = app->getSeventvEmotes();
|
||||
|
||||
auto flags = MessageElementFlags();
|
||||
auto emote = std::optional<EmotePtr>{};
|
||||
bool zeroWidth = false;
|
||||
return this->twitchChannel;
|
||||
}
|
||||
|
||||
std::tuple<std::optional<EmotePtr>, MessageElementFlags, bool>
|
||||
MessageBuilder::parseEmote(const EmoteName &name) const
|
||||
{
|
||||
// Emote order:
|
||||
// - FrankerFaceZ Channel
|
||||
// - BetterTTV Channel
|
||||
@@ -2913,36 +2934,93 @@ Outcome MessageBuilder::tryAppendEmote(const EmoteName &name)
|
||||
// - FrankerFaceZ Global
|
||||
// - BetterTTV Global
|
||||
// - 7TV Global
|
||||
if (this->twitchChannel && (emote = this->twitchChannel->ffzEmote(name)))
|
||||
|
||||
const auto *globalFfzEmotes = getApp()->getFfzEmotes();
|
||||
const auto *globalBttvEmotes = getApp()->getBttvEmotes();
|
||||
const auto *globalSeventvEmotes = getApp()->getSeventvEmotes();
|
||||
|
||||
const auto *sourceChannel = this->getSourceChannel();
|
||||
|
||||
std::optional<EmotePtr> emote{};
|
||||
|
||||
if (sourceChannel != nullptr)
|
||||
{
|
||||
flags = MessageElementFlag::FfzEmote;
|
||||
// Check for channel emotes
|
||||
|
||||
emote = sourceChannel->ffzEmote(name);
|
||||
if (emote)
|
||||
{
|
||||
return {
|
||||
emote,
|
||||
MessageElementFlag::FfzEmote,
|
||||
false,
|
||||
};
|
||||
}
|
||||
|
||||
emote = sourceChannel->bttvEmote(name);
|
||||
if (emote)
|
||||
{
|
||||
return {
|
||||
emote,
|
||||
MessageElementFlag::BttvEmote,
|
||||
false,
|
||||
};
|
||||
}
|
||||
|
||||
emote = sourceChannel->seventvEmote(name);
|
||||
if (emote)
|
||||
{
|
||||
return {
|
||||
emote,
|
||||
MessageElementFlag::SevenTVEmote,
|
||||
emote.value()->zeroWidth,
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (this->twitchChannel &&
|
||||
(emote = this->twitchChannel->bttvEmote(name)))
|
||||
|
||||
// Check for global emotes
|
||||
|
||||
emote = globalFfzEmotes->emote(name);
|
||||
if (emote)
|
||||
{
|
||||
flags = MessageElementFlag::BttvEmote;
|
||||
return {
|
||||
emote,
|
||||
MessageElementFlag::FfzEmote,
|
||||
false,
|
||||
};
|
||||
}
|
||||
else if (this->twitchChannel != nullptr &&
|
||||
(emote = this->twitchChannel->seventvEmote(name)))
|
||||
|
||||
emote = globalBttvEmotes->emote(name);
|
||||
if (emote)
|
||||
{
|
||||
flags = MessageElementFlag::SevenTVEmote;
|
||||
zeroWidth = emote.value()->zeroWidth;
|
||||
return {
|
||||
emote,
|
||||
MessageElementFlag::BttvEmote,
|
||||
zeroWidthEmotes.contains(name.string),
|
||||
};
|
||||
}
|
||||
else if ((emote = globalFfzEmotes->emote(name)))
|
||||
|
||||
emote = globalSeventvEmotes->globalEmote(name);
|
||||
if (emote)
|
||||
{
|
||||
flags = MessageElementFlag::FfzEmote;
|
||||
}
|
||||
else if ((emote = globalBttvEmotes->emote(name)))
|
||||
{
|
||||
flags = MessageElementFlag::BttvEmote;
|
||||
zeroWidth = zeroWidthEmotes.contains(name.string);
|
||||
}
|
||||
else if ((emote = globalSeventvEmotes->globalEmote(name)))
|
||||
{
|
||||
flags = MessageElementFlag::SevenTVEmote;
|
||||
zeroWidth = emote.value()->zeroWidth;
|
||||
return {
|
||||
emote,
|
||||
MessageElementFlag::SevenTVEmote,
|
||||
emote.value()->zeroWidth,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
{},
|
||||
{},
|
||||
false,
|
||||
};
|
||||
}
|
||||
|
||||
Outcome MessageBuilder::tryAppendEmote(const EmoteName &name)
|
||||
{
|
||||
const auto [emote, flags, zeroWidth] = this->parseEmote(name);
|
||||
|
||||
if (emote)
|
||||
{
|
||||
if (zeroWidth && getSettings()->enableZeroWidthEmotes &&
|
||||
@@ -3128,7 +3206,8 @@ Outcome MessageBuilder::tryParseCheermote(const QString &string)
|
||||
return Failure;
|
||||
}
|
||||
|
||||
auto cheerOpt = this->twitchChannel->cheerEmote(string);
|
||||
const auto *chan = this->getSourceChannel();
|
||||
auto cheerOpt = chan->cheerEmote(string);
|
||||
|
||||
if (!cheerOpt)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
|
||||
@@ -164,7 +165,10 @@ public:
|
||||
|
||||
QString userName;
|
||||
|
||||
/// The Twitch Channel the message was received in
|
||||
TwitchChannel *twitchChannel = nullptr;
|
||||
/// The Twitch Channel the message was sent in, according to the Shared Chat feature
|
||||
TwitchChannel *sourceChannel = nullptr;
|
||||
|
||||
Message *operator->();
|
||||
Message &message();
|
||||
@@ -278,6 +282,15 @@ protected:
|
||||
void appendChannelName();
|
||||
void appendUsername();
|
||||
|
||||
/// Return the Twitch Channel this message originated from
|
||||
///
|
||||
/// Useful to handle messages from the "Shared Chat" feature
|
||||
///
|
||||
/// Can return nullptr
|
||||
const TwitchChannel *getSourceChannel() const;
|
||||
|
||||
std::tuple<std::optional<EmotePtr>, MessageElementFlags, bool> parseEmote(
|
||||
const EmoteName &name) const;
|
||||
Outcome tryAppendEmote(const EmoteName &name);
|
||||
|
||||
void addWords(const QStringList &words,
|
||||
|
||||
@@ -50,6 +50,8 @@ enum class MessageFlag : std::int64_t {
|
||||
MonitoredMessage = (1LL << 35),
|
||||
/// The message is an ACTION message (/me)
|
||||
Action = (1LL << 36),
|
||||
/// The message is sent in a different source channel as part of a Shared Chat session
|
||||
SharedMessage = (1LL << 37),
|
||||
};
|
||||
using MessageFlags = FlagsEnum<MessageFlag>;
|
||||
|
||||
|
||||
@@ -58,6 +58,10 @@ MessageFlagsPredicate::MessageFlagsPredicate(const QString &flags, bool negate)
|
||||
{
|
||||
this->flags_.set(MessageFlag::MonitoredMessage);
|
||||
}
|
||||
else if (flag == "shared")
|
||||
{
|
||||
this->flags_.set(MessageFlag::SharedMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user