From 299c486a2bd1aff872fcf0b2e76300b569920fc5 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Fri, 12 Feb 2021 11:28:41 -0500 Subject: [PATCH 1/4] Display notifications for emote messages properly --- src/ChatPage.cpp | 9 ++++++++- src/notifications/Manager.h | 3 ++- src/notifications/ManagerLinux.cpp | 18 ++++++++++++------ src/notifications/ManagerMac.mm | 8 ++++++-- src/notifications/ManagerWin.cpp | 11 +++++++++-- 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 6d67e6f2..656ddab0 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -691,13 +691,20 @@ ChatPage::sendNotifications(const mtx::responses::Notifications &res) this, [this, room_id, event_id, item, user_id, info]( QPixmap image) { + bool isEmote = false; + auto ev = cache::client()->getEvent( + room_id.toStdString(), event_id); + if (ev && mtx::accessors::msg_type(ev->data) == + mtx::events::MessageType::Emote) + isEmote = true; notificationsManager.postNotification( room_id, QString::fromStdString(event_id), QString::fromStdString(info.name), cache::displayName(room_id, user_id), utils::event_body(item.event), - image.toImage()); + image.toImage(), + isEmote); }); } } diff --git a/src/notifications/Manager.h b/src/notifications/Manager.h index 2b869efc..46f398d7 100644 --- a/src/notifications/Manager.h +++ b/src/notifications/Manager.h @@ -32,7 +32,8 @@ public: const QString &roomName, const QString &senderName, const QString &text, - const QImage &icon); + const QImage &icon, + const bool &isEmoteMsg = false); signals: void notificationClicked(const QString roomId, const QString eventId); diff --git a/src/notifications/ManagerLinux.cpp b/src/notifications/ManagerLinux.cpp index 8f7261e6..7dbf663d 100644 --- a/src/notifications/ManagerLinux.cpp +++ b/src/notifications/ManagerLinux.cpp @@ -50,17 +50,23 @@ NotificationsManager::postNotification(const QString &roomid, const QString &roomname, const QString &sender, const QString &text, - const QImage &icon) + const QImage &icon, + const bool &isEmoteMessage) { QVariantMap hints; hints["image-data"] = icon; hints["sound-name"] = "message-new-instant"; QList argumentList; - argumentList << "nheko"; // app_name - argumentList << (uint)0; // replace_id - argumentList << ""; // app_icon - argumentList << roomname; // summary - argumentList << sender + ": " + text; // body + argumentList << "nheko"; // app_name + argumentList << (uint)0; // replace_id + argumentList << ""; // app_icon + argumentList << roomname; // summary + + // body + if (isEmoteMessage) + argumentList << "* " + sender + " " + text; + else + argumentList << sender + ": " + text; // The list of actions has always the action name and then a localized version of that // action. Currently we just use an empty string for that. // TODO(Nico): Look into what to actually put there. diff --git a/src/notifications/ManagerMac.mm b/src/notifications/ManagerMac.mm index c09e894c..e21cc904 100644 --- a/src/notifications/ManagerMac.mm +++ b/src/notifications/ManagerMac.mm @@ -19,7 +19,8 @@ NotificationsManager::postNotification( const QString &roomName, const QString &senderName, const QString &text, - const QImage &icon) + const QImage &icon, + const bool &isEmoteMessage) { Q_UNUSED(roomId); Q_UNUSED(eventId); @@ -29,7 +30,10 @@ NotificationsManager::postNotification( notif.title = roomName.toNSString(); notif.subtitle = QString("%1 sent a message").arg(senderName).toNSString(); - notif.informativeText = text.toNSString(); + if (isEmoteMessage) + notif.informativeText = QString("* ").append(senderName).append(" ").append(text).toNSString(); + else + notif.informativeText = text.toNSString(); notif.soundName = NSUserNotificationDefaultSoundName; [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification: notif]; diff --git a/src/notifications/ManagerWin.cpp b/src/notifications/ManagerWin.cpp index cc61c645..43e6517b 100644 --- a/src/notifications/ManagerWin.cpp +++ b/src/notifications/ManagerWin.cpp @@ -37,7 +37,8 @@ NotificationsManager::postNotification(const QString &room_id, const QString &room_name, const QString &sender, const QString &text, - const QImage &icon) + const QImage &icon, + const bool &isEmoteMessage) { Q_UNUSED(room_id) Q_UNUSED(event_id) @@ -53,7 +54,13 @@ NotificationsManager::postNotification(const QString &room_id, else templ.setTextField(QString("%1").arg(sender).toStdWString(), WinToastTemplate::FirstLine); - templ.setTextField(QString("%1").arg(text).toStdWString(), WinToastTemplate::SecondLine); + if (isEmoteMessage) + templ.setTextField( + QString("* ").append(sender).append(" ").append(text).toStdWString(), + WinToastTemplate::SecondLine); + else + templ.setTextField(QString("%1").arg(text).toStdWString(), + WinToastTemplate::SecondLine); // TODO: implement room or user avatar // templ.setImagePath(L"C:/example.png"); From 9f9c499cb2a136aaa5e74fa20c931d8c70885351 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 13 Feb 2021 10:58:09 -0500 Subject: [PATCH 2/4] Fix typo --- src/notifications/ManagerWin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/notifications/ManagerWin.cpp b/src/notifications/ManagerWin.cpp index 43e6517b..1a4058b3 100644 --- a/src/notifications/ManagerWin.cpp +++ b/src/notifications/ManagerWin.cpp @@ -23,7 +23,7 @@ init() WinToast::instance()->setAppName(L"Nheko"); WinToast::instance()->setAppUserModelId(WinToast::configureAUMI(L"nheko", L"nheko")); if (!WinToast::instance()->initialize()) - std::wcout << "Your system in not compatible with toast notifications\n"; + std::wcout << "Your system is not compatible with toast notifications\n"; } } From 567b2d05effd32c8804e3039250e3b44d4e7c91e Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 13 Feb 2021 12:10:49 -0500 Subject: [PATCH 3/4] Move notification parsing into postNotification --- src/ChatPage.cpp | 19 ++------------- src/notifications/Manager.h | 10 +++----- src/notifications/ManagerLinux.cpp | 37 +++++++++++++++++++----------- src/notifications/ManagerMac.mm | 29 ++++++++++++----------- src/notifications/ManagerWin.cpp | 26 +++++++++++++-------- 5 files changed, 59 insertions(+), 62 deletions(-) diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 656ddab0..45802789 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -668,8 +668,6 @@ ChatPage::sendNotifications(const mtx::responses::Notifications &res) if (!cache::isNotificationSent(event_id)) { const auto room_id = QString::fromStdString(item.room_id); - const auto user_id = - QString::fromStdString(mtx::accessors::sender(item.event)); // We should only sent one notification per event. cache::markSentNotification(event_id); @@ -689,22 +687,9 @@ ChatPage::sendNotifications(const mtx::responses::Notifications &res) QString::fromStdString(info.avatar_url), 96, this, - [this, room_id, event_id, item, user_id, info]( - QPixmap image) { - bool isEmote = false; - auto ev = cache::client()->getEvent( - room_id.toStdString(), event_id); - if (ev && mtx::accessors::msg_type(ev->data) == - mtx::events::MessageType::Emote) - isEmote = true; + [this, item](QPixmap image) { notificationsManager.postNotification( - room_id, - QString::fromStdString(event_id), - QString::fromStdString(info.name), - cache::displayName(room_id, user_id), - utils::event_body(item.event), - image.toImage(), - isEmote); + item, image.toImage()); }); } } diff --git a/src/notifications/Manager.h b/src/notifications/Manager.h index 46f398d7..e2f9f431 100644 --- a/src/notifications/Manager.h +++ b/src/notifications/Manager.h @@ -4,6 +4,8 @@ #include #include +#include + #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_HAIKU) #include #include @@ -27,13 +29,7 @@ class NotificationsManager : public QObject public: NotificationsManager(QObject *parent = nullptr); - void postNotification(const QString &roomId, - const QString &eventId, - const QString &roomName, - const QString &senderName, - const QString &text, - const QImage &icon, - const bool &isEmoteMsg = false); + void postNotification(const mtx::responses::Notification ¬ification, const QImage &icon); signals: void notificationClicked(const QString roomId, const QString eventId); diff --git a/src/notifications/ManagerLinux.cpp b/src/notifications/ManagerLinux.cpp index 7dbf663d..66592c99 100644 --- a/src/notifications/ManagerLinux.cpp +++ b/src/notifications/ManagerLinux.cpp @@ -8,6 +8,12 @@ #include #include +#include "Cache.h" +#include "EventAccessors.h" +#include "MatrixClient.h" +#include "Utils.h" +#include + NotificationsManager::NotificationsManager(QObject *parent) : QObject(parent) , dbus("org.freedesktop.Notifications", @@ -45,28 +51,31 @@ NotificationsManager::NotificationsManager(QObject *parent) * Licensed under the GNU General Public License, version 3 */ void -NotificationsManager::postNotification(const QString &roomid, - const QString &eventid, - const QString &roomname, - const QString &sender, - const QString &text, - const QImage &icon, - const bool &isEmoteMessage) +NotificationsManager::postNotification(const mtx::responses::Notification ¬ification, + const QImage &icon) { + const auto room_id = QString::fromStdString(notification.room_id); + const auto event_id = QString::fromStdString(mtx::accessors::event_id(notification.event)); + const auto sender = cache::displayName( + room_id, QString::fromStdString(mtx::accessors::sender(notification.event))); + const auto text = utils::event_body(notification.event); + QVariantMap hints; hints["image-data"] = icon; hints["sound-name"] = "message-new-instant"; QList argumentList; - argumentList << "nheko"; // app_name - argumentList << (uint)0; // replace_id - argumentList << ""; // app_icon - argumentList << roomname; // summary + argumentList << "nheko"; // app_name + argumentList << (uint)0; // replace_id + argumentList << ""; // app_icon + argumentList << QString::fromStdString( + cache::singleRoomInfo(notification.room_id).name); // summary // body - if (isEmoteMessage) + if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Emote) argumentList << "* " + sender + " " + text; else argumentList << sender + ": " + text; + // The list of actions has always the action name and then a localized version of that // action. Currently we just use an empty string for that. // TODO(Nico): Look into what to actually put there. @@ -82,12 +91,12 @@ NotificationsManager::postNotification(const QString &roomid, QDBusPendingCall call = notifyApp.asyncCallWithArgumentList("Notify", argumentList); auto watcher = new QDBusPendingCallWatcher{call, this}; connect( - watcher, &QDBusPendingCallWatcher::finished, this, [watcher, this, roomid, eventid]() { + watcher, &QDBusPendingCallWatcher::finished, this, [watcher, this, room_id, event_id]() { if (watcher->reply().type() == QDBusMessage::ErrorMessage) qDebug() << "D-Bus Error:" << watcher->reply().errorMessage(); else notificationIds[watcher->reply().arguments().first().toUInt()] = - roomEventId{roomid, eventid}; + roomEventId{room_id, event_id}; watcher->deleteLater(); }); } diff --git a/src/notifications/ManagerMac.mm b/src/notifications/ManagerMac.mm index e21cc904..e50bee89 100644 --- a/src/notifications/ManagerMac.mm +++ b/src/notifications/ManagerMac.mm @@ -3,6 +3,12 @@ #include #include +#include "Cache.h" +#include "EventAccessors.h" +#include "MatrixClient.h" +#include "Utils.h" +#include + @interface NSUserNotification (CFIPrivate) - (void)set_identityImage:(NSImage *)image; @end @@ -13,25 +19,20 @@ NotificationsManager::NotificationsManager(QObject *parent): QObject(parent) } void -NotificationsManager::postNotification( - const QString &roomId, - const QString &eventId, - const QString &roomName, - const QString &senderName, - const QString &text, - const QImage &icon, - const bool &isEmoteMessage) +NotificationsManager::postNotification(const mtx::responses::Notification ¬ification, + const QImage &icon) { - Q_UNUSED(roomId); - Q_UNUSED(eventId); Q_UNUSED(icon); + const auto sender = cache::displayName(QString::fromStdString(notification.room_id), QString::fromStdString(mtx::accessors::sender(notification.event))); + const auto text = utils::event_body(notification.event); + NSUserNotification * notif = [[NSUserNotification alloc] init]; - notif.title = roomName.toNSString(); - notif.subtitle = QString("%1 sent a message").arg(senderName).toNSString(); - if (isEmoteMessage) - notif.informativeText = QString("* ").append(senderName).append(" ").append(text).toNSString(); + notif.title = QString::fromStdString(cache::singleRoomInfo(notification.room_id).name).toNSString(); + notif.subtitle = QString("%1 sent a message").arg(sender).toNSString(); + if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Emote) + notif.informativeText = QString("* ").append(sender).append(" ").append(text).toNSString(); else notif.informativeText = text.toNSString(); notif.soundName = NSUserNotificationDefaultSoundName; diff --git a/src/notifications/ManagerWin.cpp b/src/notifications/ManagerWin.cpp index 1a4058b3..7df11308 100644 --- a/src/notifications/ManagerWin.cpp +++ b/src/notifications/ManagerWin.cpp @@ -1,6 +1,12 @@ #include "notifications/Manager.h" #include "wintoastlib.h" +#include "Cache.h" +#include "EventAccessors.h" +#include "MatrixClient.h" +#include "Utils.h" +#include + using namespace WinToastLib; class CustomHandler : public IWinToastHandler @@ -32,18 +38,18 @@ NotificationsManager::NotificationsManager(QObject *parent) {} void -NotificationsManager::postNotification(const QString &room_id, - const QString &event_id, - const QString &room_name, - const QString &sender, - const QString &text, - const QImage &icon, - const bool &isEmoteMessage) +NotificationsManager::postNotification(const mtx::responses::Notification ¬ification, + const QImage &icon) { - Q_UNUSED(room_id) - Q_UNUSED(event_id) Q_UNUSED(icon) + const auto room_name = + QString::fromStdString(cache::singleRoomInfo(notification.room_id).name); + const auto sender = + cache::displayName(QString::fromStdString(notification.room_id), + QString::fromStdString(mtx::accessors::sender(notification.event))); + const auto text = utils::event_body(notification.event); + if (!isInitialized) init(); @@ -54,7 +60,7 @@ NotificationsManager::postNotification(const QString &room_id, else templ.setTextField(QString("%1").arg(sender).toStdWString(), WinToastTemplate::FirstLine); - if (isEmoteMessage) + if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Emote) templ.setTextField( QString("* ").append(sender).append(" ").append(text).toStdWString(), WinToastTemplate::SecondLine); From 8c62df1bab3f19d0cdef140e7f8a27edd355d9e6 Mon Sep 17 00:00:00 2001 From: Loren Burkholder Date: Sat, 13 Feb 2021 12:59:50 -0500 Subject: [PATCH 4/4] Include notifications header instead of responses header --- src/notifications/Manager.h | 2 +- src/notifications/ManagerLinux.cpp | 2 +- src/notifications/ManagerMac.mm | 2 +- src/notifications/ManagerWin.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/notifications/Manager.h b/src/notifications/Manager.h index e2f9f431..950740ba 100644 --- a/src/notifications/Manager.h +++ b/src/notifications/Manager.h @@ -4,7 +4,7 @@ #include #include -#include +#include #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_HAIKU) #include diff --git a/src/notifications/ManagerLinux.cpp b/src/notifications/ManagerLinux.cpp index 66592c99..fb424b2a 100644 --- a/src/notifications/ManagerLinux.cpp +++ b/src/notifications/ManagerLinux.cpp @@ -12,7 +12,7 @@ #include "EventAccessors.h" #include "MatrixClient.h" #include "Utils.h" -#include +#include NotificationsManager::NotificationsManager(QObject *parent) : QObject(parent) diff --git a/src/notifications/ManagerMac.mm b/src/notifications/ManagerMac.mm index e50bee89..5609d3de 100644 --- a/src/notifications/ManagerMac.mm +++ b/src/notifications/ManagerMac.mm @@ -7,7 +7,7 @@ #include "EventAccessors.h" #include "MatrixClient.h" #include "Utils.h" -#include +#include @interface NSUserNotification (CFIPrivate) - (void)set_identityImage:(NSImage *)image; diff --git a/src/notifications/ManagerWin.cpp b/src/notifications/ManagerWin.cpp index 7df11308..85abe642 100644 --- a/src/notifications/ManagerWin.cpp +++ b/src/notifications/ManagerWin.cpp @@ -5,7 +5,7 @@ #include "EventAccessors.h" #include "MatrixClient.h" #include "Utils.h" -#include +#include using namespace WinToastLib;