commit
76bbc19a5d
2 changed files with 300 additions and 127 deletions
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include "notificationmanager.h"
|
#include "notificationmanager.h"
|
||||||
#include "fernschreiberutils.h"
|
#include "fernschreiberutils.h"
|
||||||
#include <nemonotifications-qt5/notification.h>
|
|
||||||
#include <sailfishapp.h>
|
#include <sailfishapp.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QListIterator>
|
#include <QListIterator>
|
||||||
|
@ -29,8 +28,97 @@
|
||||||
|
|
||||||
#define LOG(x) qDebug() << "[NotificationManager]" << x
|
#define LOG(x) qDebug() << "[NotificationManager]" << x
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const QString _TYPE("@type");
|
||||||
|
const QString TYPE("type");
|
||||||
|
const QString ID("id");
|
||||||
|
const QString CHAT_ID("chat_id");
|
||||||
|
const QString IS_CHANNEL("is_channel");
|
||||||
|
const QString TOTAL_COUNT("total_count");
|
||||||
|
const QString DATE("date");
|
||||||
|
const QString TITLE("title");
|
||||||
|
const QString CONTENT("content");
|
||||||
|
const QString MESSAGE("message");
|
||||||
|
const QString FIRST_NAME("first_name");
|
||||||
|
const QString LAST_NAME("last_name");
|
||||||
|
const QString SENDER_USER_ID("sender_user_id");
|
||||||
|
const QString NOTIFICATIONS("notifications");
|
||||||
|
const QString NOTIFICATION_GROUP_ID("notification_group_id");
|
||||||
|
const QString ADDED_NOTIFICATIONS("added_notifications");
|
||||||
|
const QString REMOVED_NOTIFICATION_IDS("removed_notification_ids");
|
||||||
|
|
||||||
|
const QString CHAT_TYPE_BASIC_GROUP("chatTypeBasicGroup");
|
||||||
|
const QString CHAT_TYPE_SUPERGROUP("chatTypeSupergroup");
|
||||||
|
|
||||||
|
const QString NOTIFICATION_CATEGORY("x-nemo.messaging.im");
|
||||||
|
const QString NGF_EVENT("chat");
|
||||||
|
|
||||||
|
const QString APP_NAME("Fernschreiber");
|
||||||
|
|
||||||
|
// Notification hints
|
||||||
|
const QString HINT_GROUP_ID("x-fernschreiber.group_id"); // int
|
||||||
|
const QString HINT_CHAT_ID("x-fernschreiber.chat_id"); // qlonglong
|
||||||
|
const QString HINT_TOTAL_COUNT("x-fernschreiber.total_count"); // int
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotificationManager::ChatInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ChatInfo(const QVariantMap &info);
|
||||||
|
|
||||||
|
void setChatInfo(const QVariantMap &info);
|
||||||
|
|
||||||
|
public:
|
||||||
|
TDLibWrapper::ChatType type;
|
||||||
|
bool isChannel;
|
||||||
|
QString title;
|
||||||
|
};
|
||||||
|
|
||||||
|
NotificationManager::ChatInfo::ChatInfo(const QVariantMap &chatInfo)
|
||||||
|
{
|
||||||
|
setChatInfo(chatInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationManager::ChatInfo::setChatInfo(const QVariantMap &chatInfo)
|
||||||
|
{
|
||||||
|
const QVariantMap chatTypeInformation = chatInfo.value(TYPE).toMap();
|
||||||
|
type = TDLibWrapper::chatTypeFromString(chatTypeInformation.value(_TYPE).toString());
|
||||||
|
isChannel = chatTypeInformation.value(IS_CHANNEL).toBool();
|
||||||
|
title = chatInfo.value(TITLE).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotificationManager::NotificationGroup
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NotificationGroup(int groupId, qlonglong chatId, int count, Notification *notification);
|
||||||
|
NotificationGroup(Notification *notification);
|
||||||
|
~NotificationGroup();
|
||||||
|
|
||||||
|
public:
|
||||||
|
int notificationGroupId;
|
||||||
|
qlonglong chatId;
|
||||||
|
int totalCount;
|
||||||
|
Notification *nemoNotification;
|
||||||
|
QMap<int,QVariantMap> activeNotifications;
|
||||||
|
QList<int> notificationOrder;
|
||||||
|
};
|
||||||
|
|
||||||
|
NotificationManager::NotificationGroup::NotificationGroup(int group, qlonglong chat, int count, Notification *notification) :
|
||||||
|
notificationGroupId(group),
|
||||||
|
chatId(chat),
|
||||||
|
totalCount(count),
|
||||||
|
nemoNotification(notification)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NotificationManager::NotificationGroup::~NotificationGroup()
|
||||||
|
{
|
||||||
|
delete nemoNotification;
|
||||||
|
}
|
||||||
|
|
||||||
NotificationManager::NotificationManager(TDLibWrapper *tdLibWrapper, AppSettings *appSettings) :
|
NotificationManager::NotificationManager(TDLibWrapper *tdLibWrapper, AppSettings *appSettings) :
|
||||||
mceInterface("com.nokia.mce", "/com/nokia/mce/request", "com.nokia.mce.request", QDBusConnection::systemBus())
|
mceInterface("com.nokia.mce", "/com/nokia/mce/request", "com.nokia.mce.request", QDBusConnection::systemBus()),
|
||||||
|
appIconFile(SailfishApp::pathTo("images/fernschreiber-notification.png").toLocalFile())
|
||||||
{
|
{
|
||||||
LOG("Initializing...");
|
LOG("Initializing...");
|
||||||
this->tdLibWrapper = tdLibWrapper;
|
this->tdLibWrapper = tdLibWrapper;
|
||||||
|
@ -41,6 +129,7 @@ NotificationManager::NotificationManager(TDLibWrapper *tdLibWrapper, AppSettings
|
||||||
connect(this->tdLibWrapper, SIGNAL(notificationGroupUpdated(QVariantMap)), this, SLOT(handleUpdateNotificationGroup(QVariantMap)));
|
connect(this->tdLibWrapper, SIGNAL(notificationGroupUpdated(QVariantMap)), this, SLOT(handleUpdateNotificationGroup(QVariantMap)));
|
||||||
connect(this->tdLibWrapper, SIGNAL(notificationUpdated(QVariantMap)), this, SLOT(handleUpdateNotification(QVariantMap)));
|
connect(this->tdLibWrapper, SIGNAL(notificationUpdated(QVariantMap)), this, SLOT(handleUpdateNotification(QVariantMap)));
|
||||||
connect(this->tdLibWrapper, SIGNAL(newChatDiscovered(QString, QVariantMap)), this, SLOT(handleChatDiscovered(QString, QVariantMap)));
|
connect(this->tdLibWrapper, SIGNAL(newChatDiscovered(QString, QVariantMap)), this, SLOT(handleChatDiscovered(QString, QVariantMap)));
|
||||||
|
connect(this->tdLibWrapper, SIGNAL(chatTitleUpdated(QString, QString)), this, SLOT(handleChatTitleUpdated(QString, QString)));
|
||||||
connect(this->ngfClient, SIGNAL(connectionStatus(bool)), this, SLOT(handleNgfConnectionStatus(bool)));
|
connect(this->ngfClient, SIGNAL(connectionStatus(bool)), this, SLOT(handleNgfConnectionStatus(bool)));
|
||||||
connect(this->ngfClient, SIGNAL(eventCompleted(quint32)), this, SLOT(handleNgfEventCompleted(quint32)));
|
connect(this->ngfClient, SIGNAL(eventCompleted(quint32)), this, SLOT(handleNgfEventCompleted(quint32)));
|
||||||
connect(this->ngfClient, SIGNAL(eventFailed(quint32)), this, SLOT(handleNgfEventFailed(quint32)));
|
connect(this->ngfClient, SIGNAL(eventFailed(quint32)), this, SLOT(handleNgfEventFailed(quint32)));
|
||||||
|
@ -53,176 +142,252 @@ NotificationManager::NotificationManager(TDLibWrapper *tdLibWrapper, AppSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
this->controlLedNotification(false);
|
this->controlLedNotification(false);
|
||||||
|
|
||||||
|
// Restore notifications
|
||||||
|
QList<QObject*> notifications = Notification::notifications();
|
||||||
|
const int n = notifications.count();
|
||||||
|
LOG("Found" << n << "existing notifications");
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
QObject *notificationObject = notifications.at(i);
|
||||||
|
Notification *notification = qobject_cast<Notification *>(notificationObject);
|
||||||
|
if (notification) {
|
||||||
|
bool groupOk, chatOk, countOk;
|
||||||
|
const int groupId = notification->hintValue(HINT_GROUP_ID).toInt(&groupOk);
|
||||||
|
const qlonglong chatId = notification->hintValue(HINT_CHAT_ID).toLongLong(&chatOk);
|
||||||
|
const int totalCount = notification->hintValue(HINT_TOTAL_COUNT).toInt(&countOk);
|
||||||
|
if (groupOk && chatOk && countOk && !notificationGroups.contains(groupId)) {
|
||||||
|
LOG("Restoring notification group" << groupId << "chatId" << chatId << "count" << totalCount);
|
||||||
|
notificationGroups.insert(groupId, new NotificationGroup(groupId, chatId, totalCount, notification));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete notificationObject;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NotificationManager::~NotificationManager()
|
NotificationManager::~NotificationManager()
|
||||||
{
|
{
|
||||||
LOG("Destroying myself...");
|
LOG("Destroying myself...");
|
||||||
|
qDeleteAll(chatMap.values());
|
||||||
|
qDeleteAll(notificationGroups.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::handleUpdateActiveNotifications(const QVariantList notificationGroups)
|
void NotificationManager::handleUpdateActiveNotifications(const QVariantList ¬ificationGroups)
|
||||||
{
|
{
|
||||||
LOG("Received active notifications, number of groups:" << notificationGroups.size());
|
const int n = notificationGroups.size();
|
||||||
|
LOG("Received active notifications, number of groups:" << n);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
const QVariantMap notificationGroupInfo(notificationGroups.at(i).toMap());
|
||||||
|
updateNotificationGroup(notificationGroupInfo.value(ID).toInt(),
|
||||||
|
notificationGroupInfo.value(CHAT_ID).toLongLong(),
|
||||||
|
notificationGroupInfo.value(TOTAL_COUNT).toInt(),
|
||||||
|
notificationGroupInfo.value(NOTIFICATIONS).toList());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::handleUpdateNotificationGroup(const QVariantMap notificationGroupUpdate)
|
void NotificationManager::handleUpdateNotificationGroup(const QVariantMap ¬ificationGroupUpdate)
|
||||||
{
|
{
|
||||||
QString notificationGroupId = notificationGroupUpdate.value("notification_group_id").toString();
|
const int notificationGroupId = notificationGroupUpdate.value(NOTIFICATION_GROUP_ID).toInt();
|
||||||
LOG("Received notification group update, group ID:" << notificationGroupId);
|
const int totalCount = notificationGroupUpdate.value(TOTAL_COUNT).toInt();
|
||||||
QVariantMap notificationGroup = this->notificationGroups.value(notificationGroupId).toMap();
|
LOG("Received notification group update, group ID:" << notificationGroupId << "total count" << totalCount);
|
||||||
|
updateNotificationGroup(notificationGroupId,
|
||||||
|
notificationGroupUpdate.value(CHAT_ID).toLongLong(), totalCount,
|
||||||
|
notificationGroupUpdate.value(ADDED_NOTIFICATIONS).toList(),
|
||||||
|
notificationGroupUpdate.value(REMOVED_NOTIFICATION_IDS).toList(),
|
||||||
|
appSettings->notificationFeedback());
|
||||||
|
}
|
||||||
|
|
||||||
QString chatId = notificationGroupUpdate.value("chat_id").toString();
|
void NotificationManager::updateNotificationGroup(int groupId, qlonglong chatId, int totalCount,
|
||||||
notificationGroup.insert("type", notificationGroupUpdate.value("type"));
|
const QVariantList &addedNotifications, const QVariantList & removedNotificationIds,
|
||||||
notificationGroup.insert("chat_id", chatId);
|
AppSettings::NotificationFeedback feedback)
|
||||||
notificationGroup.insert("notification_group_id", notificationGroupId);
|
{
|
||||||
notificationGroup.insert("notification_settings_chat_id", notificationGroupUpdate.value("notification_settings_chat_id"));
|
bool needFeedback = false;
|
||||||
notificationGroup.insert("is_silent", notificationGroupUpdate.value("is_silent"));
|
NotificationGroup* notificationGroup = notificationGroups.value(groupId);
|
||||||
notificationGroup.insert("total_count", notificationGroupUpdate.value("total_count"));
|
|
||||||
|
|
||||||
QVariantMap activeNotifications = notificationGroup.value("notifications").toMap();
|
LOG("Received notification group update, group ID:" << groupId << "total count" << totalCount);
|
||||||
|
if (totalCount) {
|
||||||
QVariantList removedNotificationIds = notificationGroupUpdate.value("removed_notification_ids").toList();
|
if (notificationGroup) {
|
||||||
QListIterator<QVariant> removedNotificationsIterator(removedNotificationIds);
|
// Notification group already exists
|
||||||
while (removedNotificationsIterator.hasNext()) {
|
notificationGroup->totalCount = totalCount;
|
||||||
QString removedNotificationId = removedNotificationsIterator.next().toString();
|
} else {
|
||||||
QVariantMap notificationInformation = activeNotifications.value(removedNotificationId).toMap();
|
// New notification
|
||||||
if (!notificationInformation.isEmpty()) {
|
Notification *notification = new Notification(this);
|
||||||
this->removeNotification(notificationInformation);
|
notification->setAppName(APP_NAME);
|
||||||
activeNotifications.remove(removedNotificationId);
|
notification->setAppIcon(appIconFile);
|
||||||
|
notification->setHintValue(HINT_GROUP_ID, groupId);
|
||||||
|
notification->setHintValue(HINT_CHAT_ID, chatId);
|
||||||
|
notification->setHintValue(HINT_TOTAL_COUNT, totalCount);
|
||||||
|
notificationGroups.insert(groupId, notificationGroup =
|
||||||
|
new NotificationGroup(groupId, chatId, totalCount, notification));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If we have deleted notifications, we need to update possibly existing ones
|
QListIterator<QVariant> addedNotificationIterator(addedNotifications);
|
||||||
if (!removedNotificationIds.isEmpty() && !activeNotifications.isEmpty()) {
|
while (addedNotificationIterator.hasNext()) {
|
||||||
LOG("Some removals happend, but we have" << activeNotifications.size() << "existing notifications.");
|
const QVariantMap addedNotification = addedNotificationIterator.next().toMap();
|
||||||
QVariantMap firstActiveNotification = activeNotifications.first().toMap();
|
const int addedId = addedNotification.value(ID).toInt();
|
||||||
activeNotifications.remove(firstActiveNotification.value("id").toString());
|
notificationGroup->activeNotifications.insert(addedId, addedNotification);
|
||||||
QVariantMap newFirstActiveNotification = this->sendNotification(chatId, firstActiveNotification, activeNotifications);
|
notificationGroup->notificationOrder.append(addedId);
|
||||||
QVariantMap newActiveNotifications;
|
|
||||||
QListIterator<QVariant> activeNotificationsIterator(activeNotifications.values());
|
|
||||||
while (activeNotificationsIterator.hasNext()) {
|
|
||||||
QVariantMap newActiveNotification = activeNotificationsIterator.next().toMap();
|
|
||||||
newActiveNotification.insert("replaces_id", newFirstActiveNotification.value("replaces_id"));
|
|
||||||
newActiveNotifications.insert(newActiveNotification.value("id").toString(), newActiveNotification);
|
|
||||||
}
|
}
|
||||||
newActiveNotifications.insert(newFirstActiveNotification.value("id").toString(), newFirstActiveNotification);
|
|
||||||
activeNotifications = newActiveNotifications;
|
QListIterator<QVariant> removedNotificationIdsIterator(removedNotificationIds);
|
||||||
|
while (removedNotificationIdsIterator.hasNext()) {
|
||||||
|
const int removedId = removedNotificationIdsIterator.next().toInt();
|
||||||
|
notificationGroup->activeNotifications.remove(removedId);
|
||||||
|
notificationGroup->notificationOrder.removeOne(removedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decide if we need a bzzz
|
||||||
|
switch (feedback) {
|
||||||
|
case AppSettings::NotificationFeedbackNone:
|
||||||
|
break;
|
||||||
|
case AppSettings::NotificationFeedbackNew:
|
||||||
|
// Non-zero replacesId means that notification has already been published
|
||||||
|
needFeedback = !notificationGroup->nemoNotification->replacesId();
|
||||||
|
break;
|
||||||
|
case AppSettings::NotificationFeedbackAll:
|
||||||
|
// Even in this case don't alert the user just about removals
|
||||||
|
needFeedback = !addedNotifications.isEmpty();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Publish new or update the existing notification
|
||||||
|
publishNotification(notificationGroup, needFeedback);
|
||||||
|
} else if (notificationGroup) {
|
||||||
|
// No active notifications left in this group
|
||||||
|
notificationGroup->nemoNotification->close();
|
||||||
|
notificationGroups.remove(groupId);
|
||||||
|
delete notificationGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeNotifications.isEmpty()) {
|
if (notificationGroups.isEmpty()) {
|
||||||
this->controlLedNotification(false);
|
// No active notifications left at all
|
||||||
|
controlLedNotification(false);
|
||||||
|
} else if (needFeedback) {
|
||||||
|
controlLedNotification(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantList addedNotifications = notificationGroupUpdate.value("added_notifications").toList();
|
|
||||||
QListIterator<QVariant> addedNotificationIterator(addedNotifications);
|
|
||||||
while (addedNotificationIterator.hasNext()) {
|
|
||||||
QVariantMap addedNotification = addedNotificationIterator.next().toMap();
|
|
||||||
QVariantMap activeNotification = this->sendNotification(chatId, addedNotification, activeNotifications);
|
|
||||||
activeNotifications.insert(activeNotification.value("id").toString(), activeNotification);
|
|
||||||
}
|
|
||||||
|
|
||||||
notificationGroup.insert("notifications", activeNotifications);
|
|
||||||
this->notificationGroups.insert(notificationGroupId, notificationGroup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::handleUpdateNotification(const QVariantMap updatedNotification)
|
void NotificationManager::handleUpdateNotification(const QVariantMap &updatedNotification)
|
||||||
{
|
{
|
||||||
LOG("Received notification update, group ID:" << updatedNotification.value("notification_group_id").toInt());
|
LOG("Received notification update, group ID:" << updatedNotification.value(NOTIFICATION_GROUP_ID).toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::handleChatDiscovered(const QString &chatId, const QVariantMap &chatInformation)
|
void NotificationManager::handleChatDiscovered(const QString &chatId, const QVariantMap &chatInformation)
|
||||||
{
|
{
|
||||||
LOG("Adding chat to internal map" << chatId);
|
const qlonglong id = chatId.toLongLong();
|
||||||
this->chatMap.insert(chatId, chatInformation);
|
ChatInfo *chat = chatMap.value(id);
|
||||||
|
if (chat) {
|
||||||
|
chat->setChatInfo(chatInformation);
|
||||||
|
LOG("Updated chat information" << id << chat->title);
|
||||||
|
} else {
|
||||||
|
chat = new ChatInfo(chatInformation);
|
||||||
|
chatMap.insert(id, chat);
|
||||||
|
LOG("New chat" << id << chat->title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::handleNgfConnectionStatus(const bool &connected)
|
void NotificationManager::handleChatTitleUpdated(const QString &chatId, const QString &title)
|
||||||
|
{
|
||||||
|
const qlonglong id = chatId.toLongLong();
|
||||||
|
ChatInfo *chat = chatMap.value(id);
|
||||||
|
if (chat) {
|
||||||
|
LOG("Chat" << id << "title changed to" << title);
|
||||||
|
chat->title = title;
|
||||||
|
|
||||||
|
// Silently update notification summary
|
||||||
|
QListIterator<NotificationGroup*> groupsIterator(notificationGroups.values());
|
||||||
|
while (groupsIterator.hasNext()) {
|
||||||
|
const NotificationGroup *group = groupsIterator.next();
|
||||||
|
if (group->chatId == id) {
|
||||||
|
LOG("Updating summary for group ID" << group->notificationGroupId);
|
||||||
|
publishNotification(group, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NotificationManager::handleNgfConnectionStatus(bool connected)
|
||||||
{
|
{
|
||||||
LOG("NGF Daemon connection status changed" << connected);
|
LOG("NGF Daemon connection status changed" << connected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::handleNgfEventFailed(const quint32 &eventId)
|
void NotificationManager::handleNgfEventFailed(quint32 eventId)
|
||||||
{
|
{
|
||||||
LOG("NGF event failed, id:" << eventId);
|
LOG("NGF event failed, id:" << eventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::handleNgfEventCompleted(const quint32 &eventId)
|
void NotificationManager::handleNgfEventCompleted(quint32 eventId)
|
||||||
{
|
{
|
||||||
LOG("NGF event completed, id:" << eventId);
|
LOG("NGF event completed, id:" << eventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::handleNgfEventPlaying(const quint32 &eventId)
|
void NotificationManager::handleNgfEventPlaying(quint32 eventId)
|
||||||
{
|
{
|
||||||
LOG("NGF event playing, id:" << eventId);
|
LOG("NGF event playing, id:" << eventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::handleNgfEventPaused(const quint32 &eventId)
|
void NotificationManager::handleNgfEventPaused(quint32 eventId)
|
||||||
{
|
{
|
||||||
LOG("NGF event paused, id:" << eventId);
|
LOG("NGF event paused, id:" << eventId);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap NotificationManager::sendNotification(const QString &chatId, const QVariantMap ¬ificationInformation, const QVariantMap &activeNotifications)
|
void NotificationManager::publishNotification(const NotificationGroup *notificationGroup, bool needFeedback)
|
||||||
{
|
{
|
||||||
LOG("Sending notification" << notificationInformation.value("id").toString());
|
QVariantMap messageMap;
|
||||||
|
const ChatInfo *chatInformation = chatMap.value(notificationGroup->chatId);
|
||||||
QVariantMap chatInformation = this->chatMap.value(chatId).toMap();
|
if (!notificationGroup->notificationOrder.isEmpty()) {
|
||||||
QString chatType = chatInformation.value("type").toMap().value("@type").toString();
|
const int lastNotificationId = notificationGroup->notificationOrder.last();
|
||||||
bool addAuthor = false;
|
const QVariantMap lastNotification(notificationGroup->activeNotifications.value(lastNotificationId));
|
||||||
if (chatType == "chatTypeBasicGroup" || ( chatType == "chatTypeSupergroup" && !chatInformation.value("type").toMap().value("is_channel").toBool() )) {
|
messageMap = lastNotification.value(TYPE).toMap().value(MESSAGE).toMap();
|
||||||
addAuthor = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantMap updatedNotificationInformation = notificationInformation;
|
Notification *nemoNotification = notificationGroup->nemoNotification;
|
||||||
QUrl appIconUrl = SailfishApp::pathTo("images/fernschreiber-notification.png");
|
if (!messageMap.isEmpty()) {
|
||||||
QVariantMap messageMap = notificationInformation.value("type").toMap().value("message").toMap();
|
nemoNotification->setTimestamp(QDateTime::fromMSecsSinceEpoch(messageMap.value(DATE).toLongLong() * 1000));
|
||||||
Notification nemoNotification;
|
|
||||||
nemoNotification.setAppName("Fernschreiber");
|
|
||||||
nemoNotification.setAppIcon(appIconUrl.toLocalFile());
|
|
||||||
nemoNotification.setSummary(chatInformation.value("title").toString());
|
|
||||||
nemoNotification.setTimestamp(QDateTime::fromMSecsSinceEpoch(messageMap.value("date").toLongLong() * 1000));
|
|
||||||
QVariantList remoteActionArguments;
|
|
||||||
remoteActionArguments.append(chatId);
|
|
||||||
remoteActionArguments.append(messageMap.value("id").toString());
|
|
||||||
nemoNotification.setRemoteAction(Notification::remoteAction("default", "openMessage", "de.ygriega.fernschreiber", "/de/ygriega/fernschreiber", "de.ygriega.fernschreiber", "openMessage", remoteActionArguments));
|
|
||||||
|
|
||||||
bool needFeedback;
|
QVariantList remoteActionArguments;
|
||||||
const AppSettings::NotificationFeedback feedbackStyle = appSettings->notificationFeedback();
|
remoteActionArguments.append(QString::number(notificationGroup->chatId));
|
||||||
|
remoteActionArguments.append(messageMap.value(ID).toString());
|
||||||
|
nemoNotification->setRemoteAction(Notification::remoteAction("default", "openMessage",
|
||||||
|
"de.ygriega.fernschreiber", "/de/ygriega/fernschreiber", "de.ygriega.fernschreiber",
|
||||||
|
"openMessage", remoteActionArguments));
|
||||||
|
}
|
||||||
|
|
||||||
if (activeNotifications.isEmpty()) {
|
QString notificationBody;
|
||||||
QString notificationBody;
|
if (notificationGroup->totalCount == 1 && !messageMap.isEmpty()) {
|
||||||
if (addAuthor) {
|
LOG("Group" << notificationGroup->notificationGroupId << "has 1 notification");
|
||||||
QVariantMap authorInformation = tdLibWrapper->getUserInformation(messageMap.value("sender_user_id").toString());
|
if (chatInformation && (chatInformation->type == TDLibWrapper::ChatTypeBasicGroup ||
|
||||||
QString firstName = authorInformation.value("first_name").toString();
|
(chatInformation->type == TDLibWrapper::ChatTypeSupergroup && !chatInformation->isChannel))) {
|
||||||
QString lastName = authorInformation.value("last_name").toString();
|
// Add author
|
||||||
QString fullName = firstName + " " + lastName;
|
const QVariantMap authorInformation = tdLibWrapper->getUserInformation(messageMap.value(SENDER_USER_ID).toString());
|
||||||
|
const QString firstName = authorInformation.value(FIRST_NAME).toString();
|
||||||
|
const QString lastName = authorInformation.value(LAST_NAME).toString();
|
||||||
|
const QString fullName = firstName + " " + lastName;
|
||||||
notificationBody = notificationBody + fullName.trimmed() + ": ";
|
notificationBody = notificationBody + fullName.trimmed() + ": ";
|
||||||
}
|
}
|
||||||
notificationBody = notificationBody + this->getNotificationText(messageMap.value("content").toMap());
|
notificationBody += getNotificationText(messageMap.value(CONTENT).toMap());
|
||||||
nemoNotification.setBody(notificationBody);
|
nemoNotification->setBody(notificationBody);
|
||||||
needFeedback = (feedbackStyle != AppSettings::NotificationFeedbackNone);
|
|
||||||
} else {
|
} else {
|
||||||
nemoNotification.setReplacesId(activeNotifications.first().toMap().value("replaces_id").toUInt());
|
// Either we have more than one notification or we have no content to display
|
||||||
nemoNotification.setBody(tr("%1 unread messages").arg(activeNotifications.size() + 1));
|
LOG("Group" << notificationGroup->notificationGroupId << "has" << notificationGroup->totalCount << "notifications");
|
||||||
needFeedback = (feedbackStyle == AppSettings::NotificationFeedbackAll);
|
notificationBody = tr("%1 unread messages").arg(notificationGroup->totalCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nemoNotification->setBody(notificationBody);
|
||||||
|
nemoNotification->setSummary(chatInformation ? chatInformation->title : QString());
|
||||||
if (needFeedback) {
|
if (needFeedback) {
|
||||||
nemoNotification.setCategory("x-nemo.messaging.im");
|
nemoNotification->setCategory(NOTIFICATION_CATEGORY);
|
||||||
ngfClient->play("chat");
|
nemoNotification->setPreviewBody(nemoNotification->body());
|
||||||
|
nemoNotification->setPreviewSummary(nemoNotification->summary());
|
||||||
|
ngfClient->play(NGF_EVENT);
|
||||||
|
} else {
|
||||||
|
nemoNotification->setCategory(QString());
|
||||||
|
nemoNotification->setPreviewBody(QString());
|
||||||
|
nemoNotification->setPreviewSummary(QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
nemoNotification.publish();
|
nemoNotification->publish();
|
||||||
this->controlLedNotification(true);
|
|
||||||
updatedNotificationInformation.insert("replaces_id", nemoNotification.replacesId());
|
|
||||||
return updatedNotificationInformation;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NotificationManager::removeNotification(const QVariantMap ¬ificationInformation)
|
|
||||||
{
|
|
||||||
LOG("Removing notification" << notificationInformation.value("id").toString());
|
|
||||||
Notification nemoNotification;
|
|
||||||
nemoNotification.setReplacesId(notificationInformation.value("replaces_id").toUInt());
|
|
||||||
nemoNotification.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString NotificationManager::getNotificationText(const QVariantMap ¬ificationContent)
|
QString NotificationManager::getNotificationText(const QVariantMap ¬ificationContent)
|
||||||
|
@ -232,7 +397,7 @@ QString NotificationManager::getNotificationText(const QVariantMap ¬ification
|
||||||
return FernschreiberUtils::getMessageShortText(notificationContent, false);
|
return FernschreiberUtils::getMessageShortText(notificationContent, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NotificationManager::controlLedNotification(const bool &enabled)
|
void NotificationManager::controlLedNotification(bool enabled)
|
||||||
{
|
{
|
||||||
static const QString PATTERN("PatternCommunicationIM");
|
static const QString PATTERN("PatternCommunicationIM");
|
||||||
static const QString ACTIVATE("req_led_pattern_activate");
|
static const QString ACTIVATE("req_led_pattern_activate");
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QDBusInterface>
|
#include <QDBusInterface>
|
||||||
|
#include <nemonotifications-qt5/notification.h>
|
||||||
#include <ngf-qt5/NgfClient>
|
#include <ngf-qt5/NgfClient>
|
||||||
#include "tdlibwrapper.h"
|
#include "tdlibwrapper.h"
|
||||||
#include "appsettings.h"
|
#include "appsettings.h"
|
||||||
|
@ -29,39 +30,46 @@
|
||||||
class NotificationManager : public QObject
|
class NotificationManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
class ChatInfo;
|
||||||
|
class NotificationGroup;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
NotificationManager(TDLibWrapper *tdLibWrapper, AppSettings *appSettings);
|
NotificationManager(TDLibWrapper *tdLibWrapper, AppSettings *appSettings);
|
||||||
~NotificationManager() override;
|
~NotificationManager() override;
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void handleUpdateActiveNotifications(const QVariantList notificationGroups);
|
void handleUpdateActiveNotifications(const QVariantList ¬ificationGroups);
|
||||||
void handleUpdateNotificationGroup(const QVariantMap notificationGroupUpdate);
|
void handleUpdateNotificationGroup(const QVariantMap ¬ificationGroupUpdate);
|
||||||
void handleUpdateNotification(const QVariantMap updatedNotification);
|
void handleUpdateNotification(const QVariantMap &updatedNotification);
|
||||||
void handleChatDiscovered(const QString &chatId, const QVariantMap &chatInformation);
|
void handleChatDiscovered(const QString &chatId, const QVariantMap &chatInformation);
|
||||||
void handleNgfConnectionStatus(const bool &connected);
|
void handleChatTitleUpdated(const QString &chatId, const QString &title);
|
||||||
void handleNgfEventFailed(const quint32 &eventId);
|
void handleNgfConnectionStatus(bool connected);
|
||||||
void handleNgfEventCompleted(const quint32 &eventId);
|
void handleNgfEventFailed(quint32 eventId);
|
||||||
void handleNgfEventPlaying(const quint32 &eventId);
|
void handleNgfEventCompleted(quint32 eventId);
|
||||||
void handleNgfEventPaused(const quint32 &eventId);
|
void handleNgfEventPlaying(quint32 eventId);
|
||||||
|
void handleNgfEventPaused(quint32 eventId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
QVariantMap sendNotification(const QString &chatId, const QVariantMap ¬ificationInformation, const QVariantMap &activeNotifications);
|
void publishNotification(const NotificationGroup *notificationGroup, bool needFeedback);
|
||||||
void removeNotification(const QVariantMap ¬ificationInformation);
|
|
||||||
QString getNotificationText(const QVariantMap ¬ificationContent);
|
QString getNotificationText(const QVariantMap ¬ificationContent);
|
||||||
void controlLedNotification(const bool &enabled);
|
void controlLedNotification(bool enabled);
|
||||||
|
void updateNotificationGroup(int groupId, qlonglong chatId, int totalCount,
|
||||||
|
const QVariantList &addedNotifications,
|
||||||
|
const QVariantList &removedNotificationIds = QVariantList(),
|
||||||
|
AppSettings::NotificationFeedback feedback = AppSettings::NotificationFeedbackNone);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TDLibWrapper *tdLibWrapper;
|
TDLibWrapper *tdLibWrapper;
|
||||||
AppSettings *appSettings;
|
AppSettings *appSettings;
|
||||||
Ngf::Client *ngfClient;
|
Ngf::Client *ngfClient;
|
||||||
QVariantMap chatMap;
|
QMap<qlonglong,ChatInfo*> chatMap;
|
||||||
QVariantMap notificationGroups;
|
QMap<int,NotificationGroup*> notificationGroups;
|
||||||
QDBusInterface mceInterface;
|
QDBusInterface mceInterface;
|
||||||
|
QString appIconFile;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue