diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a9ae87a..09e3f0f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Minor: When (re-)connecting, visible channels are now joined first. (#5850) - Minor: Added the ability to filter on messages by the author's user ID (example: `author.user_id == "22484632"`). (#5862) - Minor: Improved error messaging of the `/clip` command. (#5879) +- Minor: Clicking on a live notification can now open the channel in a custom player. (#5880) - Minor: Added searchable hotkeys to global search and make keybinds searchable in the Hotkeys settings. (#5884) - Minor: Added Linux support for Live Notifications toasts. (#5881, #5971, #5976) - Minor: Messages can now be deleted from the context menu in a channel. (#5956) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3612c34f..a8362688 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -501,6 +501,8 @@ set(SOURCE_FILES util/ChannelHelpers.hpp util/Clipboard.cpp util/Clipboard.hpp + util/CustomPlayer.cpp + util/CustomPlayer.hpp util/DebugCount.cpp util/DebugCount.hpp util/DisplayBadge.cpp diff --git a/src/singletons/Toasts.cpp b/src/singletons/Toasts.cpp index f0bcf13f..e6c88d9b 100644 --- a/src/singletons/Toasts.cpp +++ b/src/singletons/Toasts.cpp @@ -11,6 +11,7 @@ #include "singletons/Paths.hpp" #include "singletons/Settings.hpp" #include "singletons/StreamerMode.hpp" +#include "util/CustomPlayer.hpp" #include "util/StreamLink.hpp" #include "widgets/helper/CommonTexts.hpp" @@ -78,6 +79,10 @@ void performReaction(const ToastReaction &reaction, const QString &channelName) openStreamlinkForChannel(channelName); break; } + case ToastReaction::OpenInCustomPlayer: { + openInCustomPlayer(channelName); + break; + } case ToastReaction::DontOpen: // nothing should happen break; @@ -106,6 +111,10 @@ void onAction(NotifyNotification *notif, const char *actionRaw, void *userData) { toastReaction = ToastReaction::OpenInStreamlink; } + else if (action == OPEN_IN_CUSTOM_PLAYER) + { + toastReaction = ToastReaction::OpenInCustomPlayer; + } performReaction(toastReaction, *channelName); @@ -172,6 +181,9 @@ QString Toasts::findStringFromReaction(const ToastReaction &reaction) case ToastReaction::OpenInStreamlink: return OPEN_IN_STREAMLINK; case ToastReaction::DontOpen: + return DONT_OPEN; + case ToastReaction::OpenInCustomPlayer: + return OPEN_IN_CUSTOM_PLAYER; default: return DONT_OPEN; } @@ -372,6 +384,13 @@ void Toasts::sendLibnotify(const QString &channelName, notif, OPEN_IN_STREAMLINK.toUtf8().constData(), OPEN_IN_STREAMLINK.toUtf8().constData(), (NotifyActionCallback)onAction, channelNameHeap, nullptr); + if (!getSettings()->customURIScheme.getValue().isEmpty()) + { + notify_notification_add_action( + notif, OPEN_IN_CUSTOM_PLAYER.toUtf8().constData(), + OPEN_IN_CUSTOM_PLAYER.toUtf8().constData(), + (NotifyActionCallback)onAction, channelNameHeap, nullptr); + } auto defaultToastReaction = static_cast(getSettings()->openFromToast.getValue()); diff --git a/src/singletons/Toasts.hpp b/src/singletons/Toasts.hpp index 25d9ee59..96b87410 100644 --- a/src/singletons/Toasts.hpp +++ b/src/singletons/Toasts.hpp @@ -9,7 +9,8 @@ enum class ToastReaction { OpenInBrowser = 0, OpenInPlayer = 1, OpenInStreamlink = 2, - DontOpen = 3 + DontOpen = 3, + OpenInCustomPlayer = 4, }; class Toasts final diff --git a/src/util/CustomPlayer.cpp b/src/util/CustomPlayer.cpp new file mode 100644 index 00000000..ea5be1fa --- /dev/null +++ b/src/util/CustomPlayer.cpp @@ -0,0 +1,28 @@ +#include "util/CustomPlayer.hpp" + +#include "common/QLogging.hpp" +#include "singletons/Settings.hpp" + +#include +#include +#include +#include + +namespace chatterino { + +void openInCustomPlayer(QStringView channelName) +{ + QString scheme = getSettings()->customURIScheme.getValue(); + if (scheme.isEmpty()) + { + qCWarning(chatterinoApp) + << "Can't open" << channelName + << "in custom player because no URI scheme is set"; + return; + } + + QDesktopServices::openUrl( + QUrl{scheme % u"https://twitch.tv/" % channelName}); +} + +} // namespace chatterino diff --git a/src/util/CustomPlayer.hpp b/src/util/CustomPlayer.hpp new file mode 100644 index 00000000..63f06183 --- /dev/null +++ b/src/util/CustomPlayer.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace chatterino { + +void openInCustomPlayer(QStringView channel); + +} // namespace chatterino diff --git a/src/widgets/helper/CommonTexts.hpp b/src/widgets/helper/CommonTexts.hpp index 2d05250e..72995d55 100644 --- a/src/widgets/helper/CommonTexts.hpp +++ b/src/widgets/helper/CommonTexts.hpp @@ -10,6 +10,8 @@ inline const QString OPEN_PLAYER_IN_BROWSER = inline const QString OPEN_MOD_VIEW_IN_BROWSER = QStringLiteral("Open mod view in browser"); inline const QString OPEN_IN_STREAMLINK = QStringLiteral("Open in streamlink"); +inline const QString OPEN_IN_CUSTOM_PLAYER = + QStringLiteral("Open in custom player"); inline const QString DONT_OPEN = QStringLiteral("Don't open"); inline const QString OPEN_WHISPERS_IN_BROWSER = QStringLiteral("Open whispers in browser"); diff --git a/src/widgets/settingspages/NotificationPage.cpp b/src/widgets/settingspages/NotificationPage.cpp index 9006d3b9..e8e33a85 100644 --- a/src/widgets/settingspages/NotificationPage.cpp +++ b/src/widgets/settingspages/NotificationPage.cpp @@ -127,7 +127,8 @@ QComboBox *NotificationPage::createToastReactionComboBox() { QComboBox *toastReactionOptions = new QComboBox(); - for (int i = 0; i <= static_cast(ToastReaction::DontOpen); i++) + for (int i = 0; i <= static_cast(ToastReaction::OpenInCustomPlayer); + i++) { toastReactionOptions->insertItem( i, Toasts::findStringFromReaction(static_cast(i))); diff --git a/src/widgets/splits/Split.cpp b/src/widgets/splits/Split.cpp index 26b4820d..7c3383f1 100644 --- a/src/widgets/splits/Split.cpp +++ b/src/widgets/splits/Split.cpp @@ -21,6 +21,7 @@ #include "singletons/Theme.hpp" #include "singletons/WindowManager.hpp" #include "util/Clipboard.hpp" +#include "util/CustomPlayer.hpp" #include "util/Helpers.hpp" #include "util/StreamLink.hpp" #include "widgets/dialogs/QualityPopup.hpp" @@ -1252,19 +1253,11 @@ void Split::openInStreamlink() void Split::openWithCustomScheme() { - QString scheme = getSettings()->customURIScheme.getValue(); - if (scheme.isEmpty()) - { - return; - } - auto *const channel = this->getChannel().get(); if (auto *const twitchChannel = dynamic_cast(channel)) { - QDesktopServices::openUrl(QString("%1https://twitch.tv/%2") - .arg(scheme) - .arg(twitchChannel->getName())); + openInCustomPlayer(twitchChannel->getName()); } }