diff --git a/CMakeLists.txt b/CMakeLists.txt index 905e6159..e0d9b5a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -297,6 +297,9 @@ set(SRC_FILES src/ui/UserProfile.cpp src/ui/RoomSettings.cpp + # Generic notification stuff + src/notifications/Manager.cpp + src/AvatarProvider.cpp src/BlurhashProvider.cpp src/Cache.cpp @@ -557,7 +560,7 @@ set(TRANSLATION_DEPS ${LANG_QRC} ${QRC} ${QM_SRC}) if (APPLE) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Foundation -framework Cocoa") - set(SRC_FILES ${SRC_FILES} src/notifications/ManagerMac.mm src/emoji/MacHelper.mm) + set(SRC_FILES ${SRC_FILES} src/notifications/ManagerMac.mm src/notifications/ManagerMac.cpp src/emoji/MacHelper.mm) if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0") set_source_files_properties( src/notifications/ManagerMac.mm src/emoji/MacHelper.mm PROPERTIES SKIP_PRECOMPILE_HEADERS ON) endif() diff --git a/src/notifications/Manager.cpp b/src/notifications/Manager.cpp new file mode 100644 index 00000000..03ce345f --- /dev/null +++ b/src/notifications/Manager.cpp @@ -0,0 +1,27 @@ +#include "notifications/Manager.h" + +#include "Cache.h" +#include "EventAccessors.h" +#include "Utils.h" +#include + +void +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 room_name = + QString::fromStdString(cache::singleRoomInfo(notification.room_id).name); + const auto sender = cache::displayName( + room_id, QString::fromStdString(mtx::accessors::sender(notification.event))); + + QString text; + if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Emote) + text = + "* " + sender + " " + formatNotification(utils::event_body(notification.event)); + else + text = sender + ":" + formatNotification(utils::event_body(notification.event)); + + systemPostNotification(room_id, event_id, room_name, sender, text, icon); +} diff --git a/src/notifications/Manager.h b/src/notifications/Manager.h index e2b3236a..372e4998 100644 --- a/src/notifications/Manager.h +++ b/src/notifications/Manager.h @@ -42,6 +42,16 @@ signals: public slots: void removeNotification(const QString &roomId, const QString &eventId); +private: + void systemPostNotification(const QString &room_id, + const QString &event_id, + const QString &roomName, + const QString &sender, + const QString &text, + const QImage &icon); + + QString formatNotification(const QString &text); + #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_HAIKU) public: void closeNotifications(QString roomId); diff --git a/src/notifications/ManagerLinux.cpp b/src/notifications/ManagerLinux.cpp index e81500a0..35975f53 100644 --- a/src/notifications/ManagerLinux.cpp +++ b/src/notifications/ManagerLinux.cpp @@ -9,12 +9,7 @@ #include #include -#include "Cache.h" -#include "EventAccessors.h" -#include "MatrixClient.h" #include "Utils.h" -#include -#include NotificationsManager::NotificationsManager(QObject *parent) : QObject(parent) @@ -52,35 +47,24 @@ NotificationsManager::NotificationsManager(QObject *parent) // SPDX-License-Identifier: GPL-3.0-or-later void -NotificationsManager::postNotification(const mtx::responses::Notification ¬ification, - const QImage &icon) +NotificationsManager::systemPostNotification(const QString &room_id, + const QString &event_id, + const QString &roomName, + const QString &sender, + const QString &text, + 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); - auto formattedText = utils::markdownToHtml(text); - - auto capabilites = dbus.call("GetCapabilites"); - if (!capabilites.arguments().contains("body-markup")) - formattedText = QTextDocumentFragment::fromHtml(formattedText).toPlainText(); + Q_UNUSED(sender) 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 << QString::fromStdString( - cache::singleRoomInfo(notification.room_id).name); // summary - - // body - if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Emote) - argumentList << "* " + sender + " " + formattedText; - else - argumentList << sender + ": " + formattedText; + argumentList << "nheko"; // app_name + argumentList << (uint)0; // replace_id + argumentList << ""; // app_icon + argumentList << roomName; // summary + argumentList << text; // body // 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. @@ -167,6 +151,16 @@ NotificationsManager::notificationClosed(uint id, uint reason) notificationIds.remove(id); } +QString +NotificationsManager::formatNotification(const QString &text) +{ + static auto capabilites = dbus.call("GetCapabilites"); + if (capabilites.arguments().contains("body-markup")) + return utils::markdownToHtml(text); + else + return QTextDocumentFragment::fromHtml(utils::markdownToHtml(text)).toPlainText(); +} + /** * Automatic marshaling of a QImage for org.freedesktop.Notifications.Notify * diff --git a/src/notifications/ManagerMac.cpp b/src/notifications/ManagerMac.cpp new file mode 100644 index 00000000..41aea0d1 --- /dev/null +++ b/src/notifications/ManagerMac.cpp @@ -0,0 +1,11 @@ +#include "Manager.h" + +#include + +#include "Utils.h" + +QString +NotificationsManager::formatNotification(const QString &text) +{ + return utils::markdownToHtml(text); +} diff --git a/src/notifications/ManagerMac.mm b/src/notifications/ManagerMac.mm index af0b5a02..3372c5af 100644 --- a/src/notifications/ManagerMac.mm +++ b/src/notifications/ManagerMac.mm @@ -3,13 +3,6 @@ #include #include -#include "Cache.h" -#include "EventAccessors.h" -#include "MatrixClient.h" -#include "Utils.h" -#include -#include - @interface NSUserNotification (CFIPrivate) - (void)set_identityImage:(NSImage *)image; @end @@ -20,23 +13,22 @@ NotificationsManager::NotificationsManager(QObject *parent): QObject(parent) } void -NotificationsManager::postNotification(const mtx::responses::Notification ¬ification, - const QImage &icon) +NotificationsManager::systemPostNotification(const QString &room_id, + const QString &event_id, + const QString &roomName, + const QString &sender, + const QString &text, + const QImage &icon) { - 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); - const auto formattedText = cmark_markdown_to_html(text.toStdString().c_str(), text.length(), CMARK_OPT_UNSAFE); + Q_UNUSED(room_id) + Q_UNUSED(event_id) + Q_UNUSED(icon) NSUserNotification * notif = [[NSUserNotification alloc] init]; - notif.title = QString::fromStdString(cache::singleRoomInfo(notification.room_id).name).toNSString(); + notif.title = roomName.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(formattedText).toNSString(); - else - notif.informativeText = formattedText.toNSString(); + notif.informativeText = text.toNSString(); notif.soundName = NSUserNotificationDefaultSoundName; [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification: notif]; diff --git a/src/notifications/ManagerWin.cpp b/src/notifications/ManagerWin.cpp index 2ddb48cc..42289b84 100644 --- a/src/notifications/ManagerWin.cpp +++ b/src/notifications/ManagerWin.cpp @@ -7,12 +7,7 @@ #include -#include "Cache.h" -#include "EventAccessors.h" -#include "MatrixClient.h" #include "Utils.h" -#include -#include using namespace WinToastLib; @@ -45,36 +40,27 @@ NotificationsManager::NotificationsManager(QObject *parent) {} void -NotificationsManager::postNotification(const mtx::responses::Notification ¬ification, - const QImage &icon) +NotificationsManager::systemPostNotification(const QString &room_id, + const QString &event_id, + const QString &roomName, + const QString &sender, + const QString &text, + 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); - const auto formattedText = QTextDocumentFragment::fromHtml(utils::markdownToHtml(text)).toPlainText(); - if (!isInitialized) init(); auto templ = WinToastTemplate(WinToastTemplate::ImageAndText02); - if (room_name != sender) - templ.setTextField(QString("%1 - %2").arg(sender).arg(room_name).toStdWString(), + if (roomName != sender) + templ.setTextField(QString("%1 - %2").arg(sender).arg(roomName).toStdWString(), WinToastTemplate::FirstLine); else - templ.setTextField(QString("%1").arg(sender).toStdWString(), - WinToastTemplate::FirstLine); - if (mtx::accessors::msg_type(notification.event) == mtx::events::MessageType::Emote) - templ.setTextField( - QString("* ").append(sender).append(" ").append(formattedText).toStdWString(), - WinToastTemplate::SecondLine); - else - templ.setTextField(QString("%1").arg(formattedText).toStdWString(), - WinToastTemplate::SecondLine); + templ.setTextField(sender.toStdWString(), WinToastTemplate::FirstLine); + templ.setTextField(text.toStdWString(), WinToastTemplate::SecondLine); // TODO: implement room or user avatar // templ.setImagePath(L"C:/example.png"); @@ -89,3 +75,9 @@ void NotificationsManager::notificationClosed(uint, uint) {} void NotificationsManager::removeNotification(const QString &, const QString &) {} + +QString +NotificationsManager::formatNotification(const QString &text) +{ + return QTextDocumentFragment::fromHtml(utils::markdownToHtml(text)).toPlainText(); +}