Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add shared chat badge #5661

Merged
merged 20 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- Major: Improve high-DPI support on Windows. (#4868, #5391, #5664, #5666)
- Major: Added transparent overlay window (default keybind: <kbd>CTRL</kbd> + <kbd>ALT</kbd> + <kbd>N</kbd>). (#4746, #5643, #5659)
- Minor: Removed the Ctrl+Shift+L hotkey for toggling the "live only" tab visibility state. (#5530)
- Minor: Add support for Shared Chat messages. Shared chat messages can be filtered with the `flags.shared` filter variable, or with search using `is:shared`. Some messages like subscriptions are filtered on purpose to avoid confusion for the broadcaster. If you have both channels participating in Shared Chat open, only one of the message triggering your highlight will trigger. (#5606, #5625)
- Minor: Add support for Shared Chat messages. Shared chat messages can be filtered with the `flags.shared` filter variable, or with search using `is:shared`. Some messages like subscriptions are filtered on purpose to avoid confusion for the broadcaster. If you have both channels participating in Shared Chat open, only one of the message triggering your highlight will trigger. (#5606, #5625, #5661)
- Minor: Moved tab visibility control to a submenu, without any toggle actions. (#5530)
- Minor: Add option to customise Moderation buttons with images. (#5369)
- Minor: Colored usernames now update on the fly when changing the "Color @usernames" setting. (#5300)
Expand Down
7 changes: 7 additions & 0 deletions mocks/include/mocks/BaseApplication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "common/Args.hpp"
#include "mocks/DisabledStreamerMode.hpp"
#include "mocks/EmptyApplication.hpp"
#include "mocks/TwitchUsers.hpp"
#include "providers/bttv/BttvLiveUpdates.hpp"
#include "singletons/Fonts.hpp"
#include "singletons/Settings.hpp"
Expand Down Expand Up @@ -55,6 +56,11 @@ class BaseApplication : public EmptyApplication
return &this->fonts;
}

ITwitchUsers *getTwitchUsers() override
{
return &this->twitchUsers;
}

BttvLiveUpdates *getBttvLiveUpdates() override
{
return nullptr;
Expand All @@ -71,6 +77,7 @@ class BaseApplication : public EmptyApplication
DisabledStreamerMode streamerMode;
Theme theme;
Fonts fonts;
TwitchUsers twitchUsers;
};

} // namespace chatterino::mock
24 changes: 24 additions & 0 deletions mocks/include/mocks/TwitchUsers.hpp
Original file line number Diff line number Diff line change
@@ -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
Binary file added resources/twitch/sharedChat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions src/messages/MessageBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "providers/twitch/TwitchChannel.hpp"
#include "providers/twitch/TwitchIrc.hpp"
#include "providers/twitch/TwitchIrcServer.hpp"
#include "providers/twitch/TwitchUsers.hpp"
#include "singletons/Emotes.hpp"
#include "singletons/Resources.hpp"
#include "singletons/Settings.hpp"
Expand Down Expand Up @@ -380,6 +381,18 @@ EmotePtr makeAutoModBadge()
Url{"https://dashboard.twitch.tv/settings/moderation/automod"}});
}

EmotePtr makeSharedChatBadge(const QString &sourceName)
{
return std::make_shared<Emote>(Emote{
.name = EmoteName{},
.images = ImageSet{Image::fromResourcePixmap(
getResources().twitch.sharedChat, 0.25)},
.tooltip = Tooltip{"Shared Message" +
(sourceName.isEmpty() ? "" : " from " + sourceName)},
.homePage = Url{"https://link.twitch.tv/SharedChatViewer"},
});
}

std::tuple<std::optional<EmotePtr>, MessageElementFlags, bool> parseEmote(
TwitchChannel *twitchChannel, const EmoteName &name)
{
Expand Down Expand Up @@ -2751,6 +2764,28 @@ void MessageBuilder::appendTwitchBadges(const QVariantMap &tags,
return;
}

if (this->message().flags.has(MessageFlag::SharedMessage))
{
const QString sourceId = tags["source-room-id"].toString();
QString sourceName;
if (sourceId.isEmpty())
{
sourceName = "";
}
else if (twitchChannel->roomId() == sourceId)
{
sourceName = twitchChannel->getName();
pajlada marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
sourceName =
getApp()->getTwitchUsers()->resolveID({sourceId})->displayName;
}

this->emplace<BadgeElement>(makeSharedChatBadge(sourceName),
MessageElementFlag::BadgeSharedChannel);
}

auto badgeInfos = parseBadgeInfoTag(tags);
auto badges = parseBadgeTag(tags);
appendBadges(this, badges, badgeInfos, twitchChannel);
Expand Down
6 changes: 5 additions & 1 deletion src/messages/MessageElement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ enum class MessageElementFlag : int64_t {
BitsStatic = (1LL << 11),
BitsAnimated = (1LL << 12),

// Slot 0: Twitch
// - Shared Channel indicator badge
BadgeSharedChannel = (1LL << 37),

// Slot 1: Twitch
// - Staff badge
// - Admin badge
Expand Down Expand Up @@ -119,7 +123,7 @@ enum class MessageElementFlag : int64_t {

Badges = BadgeGlobalAuthority | BadgePredictions | BadgeChannelAuthority |
BadgeSubscription | BadgeVanity | BadgeChatterino | BadgeSevenTV |
BadgeFfz,
BadgeFfz | BadgeSharedChannel,

ChannelName = (1LL << 20),

Expand Down
1 change: 1 addition & 0 deletions src/singletons/WindowManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ void WindowManager::updateWordTypeMask()
flags.set(settings->animateEmotes ? MEF::BitsAnimated : MEF::BitsStatic);

// badges
flags.set(MEF::BadgeSharedChannel);
iProdigy marked this conversation as resolved.
Show resolved Hide resolved
flags.set(settings->showBadgesGlobalAuthority ? MEF::BadgeGlobalAuthority
: MEF::None);
flags.set(settings->showBadgesPredictions ? MEF::BadgePredictions
Expand Down
5 changes: 5 additions & 0 deletions src/widgets/helper/ChannelView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2408,6 +2408,11 @@ void ChannelView::handleMouseClick(QMouseEvent *event,
return;
}

if (link.value.startsWith("id:"))
{
return;
}

// Insert @username into split input
const bool commaMention =
getSettings()->mentionUsersWithComma;
Expand Down
18 changes: 18 additions & 0 deletions tests/snapshots/IrcMessageHandler/shared-chat-announcement.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,24 @@
"trailingSpace": true,
"type": "TwitchModerationElement"
},
{
"emote": {
"homePage": "https://link.twitch.tv/SharedChatViewer",
"images": {
"1x": ""
},
"name": "",
"tooltip": "Shared Message"
},
"flags": "BadgeSharedChannel",
"link": {
"type": "None",
"value": ""
},
"tooltip": "Shared Message",
"trailingSpace": true,
"type": "BadgeElement"
},
{
"emote": {
"homePage": "https://www.twitch.tv/jobs?ref=chat_badge",
Expand Down
18 changes: 18 additions & 0 deletions tests/snapshots/IrcMessageHandler/shared-chat-emotes.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,24 @@
"trailingSpace": true,
"type": "TwitchModerationElement"
},
{
"emote": {
"homePage": "https://link.twitch.tv/SharedChatViewer",
"images": {
"1x": ""
},
"name": "",
"tooltip": "Shared Message from twitchdev"
},
"flags": "BadgeSharedChannel",
"link": {
"type": "None",
"value": ""
},
"tooltip": "Shared Message from twitchdev",
"trailingSpace": true,
"type": "BadgeElement"
},
{
"color": "#ffff0000",
"flags": "Username",
Expand Down
18 changes: 18 additions & 0 deletions tests/snapshots/IrcMessageHandler/shared-chat-known.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,24 @@
"trailingSpace": true,
"type": "TwitchModerationElement"
},
{
"emote": {
"homePage": "https://link.twitch.tv/SharedChatViewer",
"images": {
"1x": ""
},
"name": "",
"tooltip": "Shared Message from twitchdev"
},
"flags": "BadgeSharedChannel",
"link": {
"type": "None",
"value": ""
},
"tooltip": "Shared Message from twitchdev",
"trailingSpace": true,
"type": "BadgeElement"
},
{
"emote": {
"homePage": "https://www.twitch.tv/jobs?ref=chat_badge",
Expand Down
18 changes: 18 additions & 0 deletions tests/snapshots/IrcMessageHandler/shared-chat-unknown.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,24 @@
"trailingSpace": true,
"type": "TwitchModerationElement"
},
{
"emote": {
"homePage": "https://link.twitch.tv/SharedChatViewer",
"images": {
"1x": ""
},
"name": "",
"tooltip": "Shared Message"
},
"flags": "BadgeSharedChannel",
"link": {
"type": "None",
"value": ""
},
"tooltip": "Shared Message",
"trailingSpace": true,
"type": "BadgeElement"
},
{
"emote": {
"homePage": "https://www.twitch.tv/jobs?ref=chat_badge",
Expand Down
Loading