From 506cf680728bd7f9124354be8ec6112d973fdac6 Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Sat, 5 May 2018 22:40:24 +0300 Subject: [PATCH] Implement desktop notification for mac --- CMakeLists.txt | 13 +++++++++-- include/Cache.h | 2 ++ include/notifications/Manager.h | 12 ++++++++++ src/Cache.cc | 36 +++++++++++++++++++++++++++++- src/ChatPage.cc | 15 +++++++++---- src/notifications/ManagerLinux.cpp | 7 ++++++ src/notifications/ManagerMac.mm | 22 ++++++++++++++++++ src/notifications/ManagerWin.cpp | 7 ++++++ 8 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 include/notifications/Manager.h create mode 100644 src/notifications/ManagerLinux.cpp create mode 100644 src/notifications/ManagerMac.mm create mode 100644 src/notifications/ManagerWin.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a199713d..b72408ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,8 +24,8 @@ fix_project_version() # Set additional project information set(COMPANY "Nheko") -set(COPYRIGHT "Copyright (c) 2017 Mujx") -set(IDENTIFIER "com.mujx.nheko") +set(COPYRIGHT "Copyright (c) 2017 Nheko Contributors") +set(IDENTIFIER "com.github.mujx.nheko") add_project_meta(META_FILES_TO_INCLUDE) @@ -305,6 +305,15 @@ else() set(NHEKO_LIBS ${COMMON_LIBS} ${LMDB_LIBRARY}) endif() +if (APPLE) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Foundation") + set(SRC_FILES ${SRC_FILES} src/notifications/ManagerMac.mm) +elseif (WIN32) + set(SRC_FILES ${SRC_FILES} src/notifications/ManagerWin.cpp) +else () + set(SRC_FILES ${SRC_FILES} src/notifications/ManagerLinux.cpp) +endif () + set(NHEKO_DEPS ${SRC_FILES} ${UI_HEADERS} diff --git a/include/Cache.h b/include/Cache.h index 1fa6c430..7ecc5d59 100644 --- a/include/Cache.h +++ b/include/Cache.h @@ -196,6 +196,7 @@ public: //! Retrieves the saved room avatar. QImage getRoomAvatar(const QString &id); + QImage getRoomAvatar(const std::string &id); //! Adds a user to the read list for the given event. //! @@ -220,6 +221,7 @@ public: } void saveImage(const QString &url, const QByteArray &data); + RoomInfo singleRoomInfo(const std::string &room_id); std::vector roomsWithStateUpdates(const mtx::responses::Sync &res); std::map getRoomInfo(const std::vector &rooms); std::map roomUpdates(const mtx::responses::Sync &sync) diff --git a/include/notifications/Manager.h b/include/notifications/Manager.h new file mode 100644 index 00000000..4ee4cb98 --- /dev/null +++ b/include/notifications/Manager.h @@ -0,0 +1,12 @@ +#pragma once + +#include +#include + +class NotificationsManager +{ +public: + static void postNotification(const QString &room, + const QString &user, + const QString &message); +}; diff --git a/src/Cache.cc b/src/Cache.cc index 8b00a828..8964c0e0 100644 --- a/src/Cache.cc +++ b/src/Cache.cc @@ -528,6 +528,34 @@ Cache::roomsWithStateUpdates(const mtx::responses::Sync &res) return rooms; } +RoomInfo +Cache::singleRoomInfo(const std::string &room_id) +{ + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + + lmdb::val data; + + // Check if the room is joined. + if (lmdb::dbi_get(txn, roomsDb_, lmdb::val(room_id), data)) { + try { + RoomInfo tmp = json::parse(std::string(data.data(), data.size())); + tmp.member_count = getMembersDb(txn, room_id).size(txn); + + txn.commit(); + + return tmp; + } catch (const json::exception &e) { + qWarning() + << "failed to parse room info:" << QString::fromStdString(room_id) + << QString::fromStdString(std::string(data.data(), data.size())); + } + } + + txn.commit(); + + return RoomInfo(); +} + std::map Cache::getRoomInfo(const std::vector &rooms) { @@ -892,12 +920,18 @@ Cache::getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &db) QImage Cache::getRoomAvatar(const QString &room_id) +{ + return getRoomAvatar(room_id.toStdString()); +} + +QImage +Cache::getRoomAvatar(const std::string &room_id) { auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); lmdb::val response; - if (!lmdb::dbi_get(txn, roomsDb_, lmdb::val(room_id.toStdString()), response)) { + if (!lmdb::dbi_get(txn, roomsDb_, lmdb::val(room_id), response)) { txn.commit(); return QImage(); } diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 4750e67a..b4691fdd 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -38,6 +38,8 @@ #include "UserSettingsPage.h" #include "Utils.h" +#include "notifications/Manager.h" + #include "dialogs/ReadReceipts.h" #include "timeline/TimelineViewManager.h" @@ -864,12 +866,17 @@ ChatPage::sendDesktopNotifications(const mtx::responses::Notifications &res) } if (!cache_->isNotificationSent(event_id)) { - // TODO: send desktop notification - // qDebug() << "sender" << utils::event_sender(item.event); - // qDebug() << "body" << utils::event_body(item.event); + const auto room_id = QString::fromStdString(item.room_id); + const auto user_id = utils::event_sender(item.event); + const auto body = utils::event_body(item.event); // We should only sent one notification per event. - // cache_->markSentNotification(event_id); + cache_->markSentNotification(event_id); + + NotificationsManager::postNotification( + QString::fromStdString(cache_->singleRoomInfo(item.room_id).name), + Cache::displayName(room_id, user_id), + body); } } catch (const lmdb::error &e) { qWarning() << e.what(); diff --git a/src/notifications/ManagerLinux.cpp b/src/notifications/ManagerLinux.cpp new file mode 100644 index 00000000..a913128e --- /dev/null +++ b/src/notifications/ManagerLinux.cpp @@ -0,0 +1,7 @@ +#include "notifications/Manager.h" + +void +NotificationsManager::postNotification(const QString &, const QString &, const QString &) +{ + // TODO: To be implemented +} diff --git a/src/notifications/ManagerMac.mm b/src/notifications/ManagerMac.mm new file mode 100644 index 00000000..48fb46ca --- /dev/null +++ b/src/notifications/ManagerMac.mm @@ -0,0 +1,22 @@ +#include "notifications/Manager.h" + +#include +#include + +@interface NSUserNotification (CFIPrivate) +- (void)set_identityImage:(NSImage *)image; +@end + +void +NotificationsManager::postNotification(const QString &roomName, const QString &userName, const QString &message) +{ + NSUserNotification * notif = [[NSUserNotification alloc] init]; + + notif.title = roomName.toNSString(); + notif.subtitle = QString("%1 sent a message").arg(userName).toNSString(); + notif.informativeText = message.toNSString(); + notif.soundName = NSUserNotificationDefaultSoundName; + + [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification: notif]; + [notif autorelease]; +} diff --git a/src/notifications/ManagerWin.cpp b/src/notifications/ManagerWin.cpp new file mode 100644 index 00000000..a913128e --- /dev/null +++ b/src/notifications/ManagerWin.cpp @@ -0,0 +1,7 @@ +#include "notifications/Manager.h" + +void +NotificationsManager::postNotification(const QString &, const QString &, const QString &) +{ + // TODO: To be implemented +}