diff --git a/imports/Spectral/Page/Room.qml b/imports/Spectral/Page/Room.qml index dbcda44..f87ba95 100644 --- a/imports/Spectral/Page/Room.qml +++ b/imports/Spectral/Page/Room.qml @@ -1,5 +1,5 @@ import QtQuick 2.9 RoomForm { - roomListModel.onNewMessage: if (!window.visible) spectralController.postNotification(roomId, eventId, roomName, senderName, text, icon) + roomListModel.onNewMessage: if (!window.visible) spectralController.postNotification(roomId, eventId, roomName, senderName, text, icon, iconPath) } diff --git a/src/controller.cpp b/src/controller.cpp index 8d83a65..3b10d1b 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -244,7 +244,8 @@ void Controller::setColor(QString userId, QColor newColor) { void Controller::postNotification(const QString& roomId, const QString& eventId, const QString& roomName, const QString& senderName, - const QString& text, const QImage& icon) { + const QString& text, const QImage& icon, + const QUrl& iconPath) { notificationsManager.postNotification(roomId, eventId, roomName, senderName, - text, icon); + text, icon, iconPath); } diff --git a/src/controller.h b/src/controller.h index 95ff024..18d2532 100644 --- a/src/controller.h +++ b/src/controller.h @@ -73,7 +73,7 @@ class Controller : public QObject { void playAudio(QUrl localFile); void postNotification(const QString& roomId, const QString& eventId, const QString& roomName, const QString& senderName, - const QString& text, const QImage& icon); + const QString& text, const QImage& icon, const QUrl& iconPath); static QImage safeImage(QImage image); }; diff --git a/src/notifications/manager.h b/src/notifications/manager.h index bdc06d4..b55eac2 100644 --- a/src/notifications/manager.h +++ b/src/notifications/manager.h @@ -4,6 +4,7 @@ #include #include #include +#include #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) #include @@ -22,7 +23,7 @@ class NotificationsManager : public QObject { void postNotification(const QString &roomId, const QString &eventId, const QString &roomName, const QString &senderName, - const QString &text, const QImage &icon); + const QString &text, const QImage &icon, const QUrl &iconPath); signals: void notificationClicked(const QString roomId, const QString eventId); @@ -39,7 +40,7 @@ class NotificationsManager : public QObject { // these slots are platform specific (D-Bus only) // but Qt slot declarations can not be inside an ifdef! - private slots: + public slots: void actionInvoked(uint id, QString action); void notificationClosed(uint id, uint reason); }; diff --git a/src/notifications/managerlinux.cpp b/src/notifications/managerlinux.cpp index 368cd02..5312cc4 100644 --- a/src/notifications/managerlinux.cpp +++ b/src/notifications/managerlinux.cpp @@ -25,7 +25,7 @@ NotificationsManager::NotificationsManager(QObject *parent) void NotificationsManager::postNotification( const QString &roomid, const QString &eventid, const QString &roomname, - const QString &sender, const QString &text, const QImage &icon) { + const QString &sender, const QString &text, const QImage &icon, const QUrl &iconPath) { uint id = showNotification(roomname, sender + ": " + text, icon); notificationIds[id] = roomEventId{roomid, eventid}; } diff --git a/src/notifications/managermac.mm b/src/notifications/managermac.mm index 782be1f..2ddc939 100644 --- a/src/notifications/managermac.mm +++ b/src/notifications/managermac.mm @@ -19,11 +19,13 @@ NotificationsManager::postNotification( const QString &roomName, const QString &senderName, const QString &text, - const QImage &icon) + const QImage &icon, + const QUrl &iconPath) { Q_UNUSED(roomId); Q_UNUSED(eventId); Q_UNUSED(icon); + Q_UNUSED(iconPath); NSUserNotification * notif = [[NSUserNotification alloc] init]; diff --git a/src/notifications/managerwin.cpp b/src/notifications/managerwin.cpp index 87b8bd2..70d943c 100644 --- a/src/notifications/managerwin.cpp +++ b/src/notifications/managerwin.cpp @@ -1,25 +1,30 @@ #include "manager.h" #include "wintoastlib.h" +#include + using namespace WinToastLib; -class CustomHandler : public QObject, public IWinToastHandler { - Q_OBJECT +class CustomHandler : public IWinToastHandler { public: - void toastActivated() { emit activated(notificationID); } - void toastActivated(int) { emit activated(notificationID); } + CustomHandler(uint id, NotificationsManager *parent) + : notificationID(id), notificationsManager(parent) {} + void toastActivated() { + notificationsManager->actionInvoked(notificationID, ""); + } + void toastActivated(int) { + notificationsManager->actionInvoked(notificationID, ""); + } void toastFailed() { std::wcout << L"Error showing current toast" << std::endl; } void toastDismissed(WinToastDismissalReason) { - emit dismissed(notificationID); + notificationsManager->notificationClosed(notificationID, 0); } + private: uint notificationID; - - signals: - void activated(uint id); - void dismissed(uint id); + NotificationsManager *notificationsManager; }; namespace { @@ -41,7 +46,8 @@ NotificationsManager::NotificationsManager(QObject *parent) : 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 QString &sender, const QString &text, const QImage &icon, + const QUrl &iconPath) { Q_UNUSED(room_id) Q_UNUSED(event_id) Q_UNUSED(icon) @@ -58,17 +64,13 @@ void NotificationsManager::postNotification( WinToastTemplate::FirstLine); templ.setTextField(QString("%1").arg(text).toStdWString(), WinToastTemplate::SecondLine); - // TODO: implement room or user avatar - // templ.setImagePath(L"C:/example.png"); - CustomHandler *customHandler = new CustomHandler(); + templ.setImagePath( + reinterpret_cast(QDir::toNativeSeparators(iconPath.toLocalFile()).utf16())); + count++; - customHandler->notificationID = count; + CustomHandler *customHandler = new CustomHandler(count, this); notificationIds[count] = roomEventId{room_id, event_id}; - connect(customHandler, &CustomHandler::activated, this, - [=](uint id) { this->actionInvoked(id, ""); }); - connect(customHandler, &CustomHandler::dismissed, this, - [=](uint id) { this->notificationClosed(id, 0); }); WinToast::instance()->showToast(templ, customHandler); } diff --git a/src/roomlistmodel.cpp b/src/roomlistmodel.cpp index 1c1ec87..a6f39cd 100644 --- a/src/roomlistmodel.cpp +++ b/src/roomlistmodel.cpp @@ -4,6 +4,7 @@ #include "events/roomevent.h" +#include #include #include #include @@ -74,17 +75,20 @@ void RoomListModel::connectRoomSignals(SpectralRoom* room) { [=] { refresh(room, {AvatarRole}); }); connect(room, &Room::addedMessages, this, [=] { refresh(room, {LastEventRole}); }); - connect(room, &Room::aboutToAddNewMessages, this, - [=](QMatrixClient::RoomEventsRange eventsRange) { - RoomEvent* event = (eventsRange.end() - 1)->get(); - if (event->isStateEvent()) return; - User* sender = room->user(event->senderId()); - if (sender == room->localUser()) return; - emit newMessage(room->id(), event->id(), room->displayName(), - sender->displayname(), - event->contentJson().value("body").toString(), - room->avatar(128)); - }); + connect( + room, &Room::aboutToAddNewMessages, this, + [=](QMatrixClient::RoomEventsRange eventsRange) { + RoomEvent* event = (eventsRange.end() - 1)->get(); + if (event->isStateEvent()) return; + User* sender = room->user(event->senderId()); + if (sender == room->localUser()) return; + QUrl _url = room->avatarUrl(); + emit newMessage( + room->id(), event->id(), room->displayName(), sender->displayname(), + event->contentJson().value("body").toString(), room->avatar(128), + QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + + "/avatar/" + _url.authority() + '_' + _url.fileName() + ".png")); + }); } void RoomListModel::updateRoom(Room* room, Room* prev) { diff --git a/src/roomlistmodel.h b/src/roomlistmodel.h index 9da486d..40b0f04 100644 --- a/src/roomlistmodel.h +++ b/src/roomlistmodel.h @@ -76,7 +76,7 @@ class RoomListModel : public QAbstractListModel { void roomAdded(SpectralRoom* room); void newMessage(const QString& roomId, const QString& eventId, const QString& roomName, const QString& senderName, - const QString& text, const QImage& icon); + const QString& text, const QImage& icon, const QUrl& iconPath); }; #endif // ROOMLISTMODEL_H