feat(notifications): implement actions for Linux (#5976)
This commit is contained in:
+1
-1
@@ -9,7 +9,7 @@
|
|||||||
- Minor: When (re-)connecting, visible channels are now joined first. (#5850)
|
- 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: 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: Improved error messaging of the `/clip` command. (#5879)
|
||||||
- Minor: Added Linux support for Live Notifications toasts. (#5881, #5971)
|
- 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)
|
- Minor: Messages can now be deleted from the context menu in a channel. (#5956)
|
||||||
- Minor: Overlay windows now inherit the global zoom level and can be zoomed independently. (#6016)
|
- Minor: Overlay windows now inherit the global zoom level and can be zoomed independently. (#6016)
|
||||||
- Bugfix: Fixed a potential way to escape the Lua Plugin sandbox. (#5846)
|
- Bugfix: Fixed a potential way to escape the Lua Plugin sandbox. (#5846)
|
||||||
|
|||||||
+101
-20
@@ -63,6 +63,67 @@ Q_SIGNALS:
|
|||||||
void downloadComplete();
|
void downloadComplete();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void performReaction(const ToastReaction &reaction, const QString &channelName)
|
||||||
|
{
|
||||||
|
switch (reaction)
|
||||||
|
{
|
||||||
|
case ToastReaction::OpenInBrowser:
|
||||||
|
QDesktopServices::openUrl(
|
||||||
|
QUrl(u"https://www.twitch.tv/" % channelName));
|
||||||
|
break;
|
||||||
|
case ToastReaction::OpenInPlayer:
|
||||||
|
QDesktopServices::openUrl(QUrl(TWITCH_PLAYER_URL.arg(channelName)));
|
||||||
|
break;
|
||||||
|
case ToastReaction::OpenInStreamlink: {
|
||||||
|
openStreamlinkForChannel(channelName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ToastReaction::DontOpen:
|
||||||
|
// nothing should happen
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CHATTERINO_WITH_LIBNOTIFY
|
||||||
|
void onAction(NotifyNotification *notif, const char *actionRaw, void *userData)
|
||||||
|
{
|
||||||
|
QString action(actionRaw);
|
||||||
|
auto *channelName = static_cast<QString *>(userData);
|
||||||
|
|
||||||
|
// by default we perform the action that is specified in the settings
|
||||||
|
auto toastReaction =
|
||||||
|
static_cast<ToastReaction>(getSettings()->openFromToast.getValue());
|
||||||
|
|
||||||
|
if (action == OPEN_IN_BROWSER)
|
||||||
|
{
|
||||||
|
toastReaction = ToastReaction::OpenInBrowser;
|
||||||
|
}
|
||||||
|
else if (action == OPEN_PLAYER_IN_BROWSER)
|
||||||
|
{
|
||||||
|
toastReaction = ToastReaction::OpenInPlayer;
|
||||||
|
}
|
||||||
|
else if (action == OPEN_IN_STREAMLINK)
|
||||||
|
{
|
||||||
|
toastReaction = ToastReaction::OpenInStreamlink;
|
||||||
|
}
|
||||||
|
|
||||||
|
performReaction(toastReaction, *channelName);
|
||||||
|
|
||||||
|
notify_notification_close(notif, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onActionClosed(NotifyNotification *notif, void * /*userData*/)
|
||||||
|
{
|
||||||
|
g_object_unref(notif);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onNotificationDestroyed(void *data)
|
||||||
|
{
|
||||||
|
auto *channelNameHeap = static_cast<QString *>(data);
|
||||||
|
delete channelNameHeap;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
@@ -182,24 +243,7 @@ public:
|
|||||||
auto toastReaction =
|
auto toastReaction =
|
||||||
static_cast<ToastReaction>(getSettings()->openFromToast.getValue());
|
static_cast<ToastReaction>(getSettings()->openFromToast.getValue());
|
||||||
|
|
||||||
switch (toastReaction)
|
performReaction(toastReaction, channelName_);
|
||||||
{
|
|
||||||
case ToastReaction::OpenInBrowser:
|
|
||||||
QDesktopServices::openUrl(
|
|
||||||
QUrl(u"https://www.twitch.tv/" % channelName_));
|
|
||||||
break;
|
|
||||||
case ToastReaction::OpenInPlayer:
|
|
||||||
QDesktopServices::openUrl(
|
|
||||||
QUrl(TWITCH_PLAYER_URL.arg(channelName_)));
|
|
||||||
break;
|
|
||||||
case ToastReaction::OpenInStreamlink: {
|
|
||||||
openStreamlinkForChannel(channelName_);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ToastReaction::DontOpen:
|
|
||||||
// nothing should happen
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void toastActivated(int actionIndex) const override
|
void toastActivated(int actionIndex) const override
|
||||||
@@ -310,6 +354,38 @@ void Toasts::sendLibnotify(const QString &channelName,
|
|||||||
NotifyNotification *notif = notify_notification_new(
|
NotifyNotification *notif = notify_notification_new(
|
||||||
str.toUtf8().constData(), channelTitle.toUtf8().constData(), nullptr);
|
str.toUtf8().constData(), channelTitle.toUtf8().constData(), nullptr);
|
||||||
|
|
||||||
|
// this will be freed in onNotificationDestroyed
|
||||||
|
auto *channelNameHeap = new QString(channelName);
|
||||||
|
|
||||||
|
// we only set onNotificationDestroyed as free_func in the first action
|
||||||
|
// because all free_funcs will be called once the notification is destroyed
|
||||||
|
// which would cause a double-free otherwise
|
||||||
|
notify_notification_add_action(notif, OPEN_IN_BROWSER.toUtf8().constData(),
|
||||||
|
OPEN_IN_BROWSER.toUtf8().constData(),
|
||||||
|
(NotifyActionCallback)onAction,
|
||||||
|
channelNameHeap, onNotificationDestroyed);
|
||||||
|
notify_notification_add_action(
|
||||||
|
notif, OPEN_PLAYER_IN_BROWSER.toUtf8().constData(),
|
||||||
|
OPEN_PLAYER_IN_BROWSER.toUtf8().constData(),
|
||||||
|
(NotifyActionCallback)onAction, channelNameHeap, nullptr);
|
||||||
|
notify_notification_add_action(
|
||||||
|
notif, OPEN_IN_STREAMLINK.toUtf8().constData(),
|
||||||
|
OPEN_IN_STREAMLINK.toUtf8().constData(), (NotifyActionCallback)onAction,
|
||||||
|
channelNameHeap, nullptr);
|
||||||
|
|
||||||
|
auto defaultToastReaction =
|
||||||
|
static_cast<ToastReaction>(getSettings()->openFromToast.getValue());
|
||||||
|
|
||||||
|
if (defaultToastReaction != ToastReaction::DontOpen)
|
||||||
|
{
|
||||||
|
notify_notification_add_action(
|
||||||
|
notif, "default",
|
||||||
|
Toasts::findStringFromReaction(defaultToastReaction)
|
||||||
|
.toUtf8()
|
||||||
|
.constData(),
|
||||||
|
(NotifyActionCallback)onAction, channelNameHeap, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
GdkPixbuf *img = gdk_pixbuf_new_from_file(
|
GdkPixbuf *img = gdk_pixbuf_new_from_file(
|
||||||
avatarFilePath(channelName).toUtf8().constData(), nullptr);
|
avatarFilePath(channelName).toUtf8().constData(), nullptr);
|
||||||
if (img == nullptr)
|
if (img == nullptr)
|
||||||
@@ -322,8 +398,13 @@ void Toasts::sendLibnotify(const QString &channelName,
|
|||||||
g_object_unref(img);
|
g_object_unref(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_notification_show(notif, nullptr);
|
g_signal_connect(notif, "closed", (GCallback)onActionClosed, nullptr);
|
||||||
g_object_unref(notif);
|
|
||||||
|
gboolean success = notify_notification_show(notif, nullptr);
|
||||||
|
if (success == 0)
|
||||||
|
{
|
||||||
|
g_object_unref(notif);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,7 @@ NotificationPage::NotificationPage()
|
|||||||
#if defined(Q_OS_WIN) || defined(CHATTERINO_WITH_LIBNOTIFY)
|
#if defined(Q_OS_WIN) || defined(CHATTERINO_WITH_LIBNOTIFY)
|
||||||
settings.append(this->createCheckBox(
|
settings.append(this->createCheckBox(
|
||||||
"Show notification", getSettings()->notificationToast));
|
"Show notification", getSettings()->notificationToast));
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
auto openIn = settings.emplace<QHBoxLayout>().withoutMargin();
|
auto openIn = settings.emplace<QHBoxLayout>().withoutMargin();
|
||||||
{
|
{
|
||||||
openIn
|
openIn
|
||||||
|
|||||||
Reference in New Issue
Block a user