Don't post unwanted feedback for removed notifications
Also, don't turn off PatternCommunicationIM pattern when some (but not all) notifications are removed, don't keep empty notification groups in notificationGroups map, reuse already posted notification after restarting the client, handle chat title change and more...
This commit is contained in:
parent
9504b24d5c
commit
45180b64b4
2 changed files with 260 additions and 118 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>
|
||||||
|
@ -34,9 +33,7 @@ namespace {
|
||||||
const QString TYPE("type");
|
const QString TYPE("type");
|
||||||
const QString ID("id");
|
const QString ID("id");
|
||||||
const QString CHAT_ID("chat_id");
|
const QString CHAT_ID("chat_id");
|
||||||
const QString IS_SILENT("is_silent");
|
|
||||||
const QString IS_CHANNEL("is_channel");
|
const QString IS_CHANNEL("is_channel");
|
||||||
const QString REPLACES_ID("replaces_id");
|
|
||||||
const QString TOTAL_COUNT("total_count");
|
const QString TOTAL_COUNT("total_count");
|
||||||
const QString DATE("date");
|
const QString DATE("date");
|
||||||
const QString TITLE("title");
|
const QString TITLE("title");
|
||||||
|
@ -47,7 +44,6 @@ namespace {
|
||||||
const QString SENDER_USER_ID("sender_user_id");
|
const QString SENDER_USER_ID("sender_user_id");
|
||||||
const QString NOTIFICATIONS("notifications");
|
const QString NOTIFICATIONS("notifications");
|
||||||
const QString NOTIFICATION_GROUP_ID("notification_group_id");
|
const QString NOTIFICATION_GROUP_ID("notification_group_id");
|
||||||
const QString NOTIFICATION_SETTINGS_CHAT_ID("notification_settings_chat_id");
|
|
||||||
const QString ADDED_NOTIFICATIONS("added_notifications");
|
const QString ADDED_NOTIFICATIONS("added_notifications");
|
||||||
const QString REMOVED_NOTIFICATION_IDS("removed_notification_ids");
|
const QString REMOVED_NOTIFICATION_IDS("removed_notification_ids");
|
||||||
|
|
||||||
|
@ -58,6 +54,66 @@ namespace {
|
||||||
const QString NGF_EVENT("chat");
|
const QString NGF_EVENT("chat");
|
||||||
|
|
||||||
const QString APP_NAME("Fernschreiber");
|
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) :
|
||||||
|
@ -73,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)));
|
||||||
|
@ -85,87 +142,169 @@ 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)
|
||||||
{
|
{
|
||||||
const QString chatId = notificationGroupUpdate.value(CHAT_ID).toString();
|
const int notificationGroupId = notificationGroupUpdate.value(NOTIFICATION_GROUP_ID).toInt();
|
||||||
const QString notificationGroupId = notificationGroupUpdate.value(NOTIFICATION_GROUP_ID).toString();
|
const int totalCount = notificationGroupUpdate.value(TOTAL_COUNT).toInt();
|
||||||
LOG("Received notification group update, group ID:" << notificationGroupId);
|
LOG("Received notification group update, group ID:" << notificationGroupId << "total count" << totalCount);
|
||||||
|
updateNotificationGroup(notificationGroupId,
|
||||||
QVariantMap notificationGroup = this->notificationGroups.value(notificationGroupId).toMap();
|
notificationGroupUpdate.value(CHAT_ID).toLongLong(), totalCount,
|
||||||
notificationGroup.insert(TYPE, notificationGroupUpdate.value(TYPE));
|
notificationGroupUpdate.value(ADDED_NOTIFICATIONS).toList(),
|
||||||
notificationGroup.insert(CHAT_ID, chatId);
|
notificationGroupUpdate.value(REMOVED_NOTIFICATION_IDS).toList(),
|
||||||
notificationGroup.insert(NOTIFICATION_GROUP_ID, notificationGroupId);
|
appSettings->notificationFeedback());
|
||||||
notificationGroup.insert(NOTIFICATION_SETTINGS_CHAT_ID, notificationGroupUpdate.value(NOTIFICATION_SETTINGS_CHAT_ID));
|
|
||||||
notificationGroup.insert(IS_SILENT, notificationGroupUpdate.value(IS_SILENT));
|
|
||||||
notificationGroup.insert(TOTAL_COUNT, notificationGroupUpdate.value(TOTAL_COUNT));
|
|
||||||
|
|
||||||
QVariantMap activeNotifications = notificationGroup.value(NOTIFICATIONS).toMap();
|
|
||||||
|
|
||||||
const QVariantList removedNotificationIds = notificationGroupUpdate.value(REMOVED_NOTIFICATION_IDS).toList();
|
|
||||||
QListIterator<QVariant> removedNotificationsIterator(removedNotificationIds);
|
|
||||||
while (removedNotificationsIterator.hasNext()) {
|
|
||||||
const QString removedNotificationId = removedNotificationsIterator.next().toString();
|
|
||||||
const QVariantMap notificationInformation = activeNotifications.value(removedNotificationId).toMap();
|
|
||||||
if (!notificationInformation.isEmpty()) {
|
|
||||||
this->removeNotification(notificationInformation);
|
|
||||||
activeNotifications.remove(removedNotificationId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have deleted notifications, we need to update possibly existing ones
|
|
||||||
if (!removedNotificationIds.isEmpty() && !activeNotifications.isEmpty()) {
|
|
||||||
LOG("Some removals happend, but we have" << activeNotifications.size() << "existing notifications.");
|
|
||||||
const QVariantMap firstActiveNotification = activeNotifications.first().toMap();
|
|
||||||
activeNotifications.remove(firstActiveNotification.value(ID).toString());
|
|
||||||
QVariantMap newFirstActiveNotification = this->sendNotification(chatId, firstActiveNotification, activeNotifications);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (activeNotifications.isEmpty()) {
|
|
||||||
this->controlLedNotification(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QVariantList addedNotifications = notificationGroupUpdate.value(ADDED_NOTIFICATIONS).toList();
|
|
||||||
QListIterator<QVariant> addedNotificationIterator(addedNotifications);
|
|
||||||
while (addedNotificationIterator.hasNext()) {
|
|
||||||
const QVariantMap addedNotification = addedNotificationIterator.next().toMap();
|
|
||||||
const 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::updateNotificationGroup(int groupId, qlonglong chatId, int totalCount,
|
||||||
|
const QVariantList &addedNotifications, const QVariantList & removedNotificationIds,
|
||||||
|
AppSettings::NotificationFeedback feedback)
|
||||||
|
{
|
||||||
|
bool needFeedback = false;
|
||||||
|
NotificationGroup* notificationGroup = notificationGroups.value(groupId);
|
||||||
|
|
||||||
|
LOG("Received notification group update, group ID:" << groupId << "total count" << totalCount);
|
||||||
|
if (totalCount) {
|
||||||
|
if (notificationGroup) {
|
||||||
|
// Notification group already exists
|
||||||
|
notificationGroup->totalCount = totalCount;
|
||||||
|
} else {
|
||||||
|
// New notification
|
||||||
|
Notification *notification = new Notification(this);
|
||||||
|
notification->setAppName(APP_NAME);
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
QListIterator<QVariant> addedNotificationIterator(addedNotifications);
|
||||||
|
while (addedNotificationIterator.hasNext()) {
|
||||||
|
const QVariantMap addedNotification = addedNotificationIterator.next().toMap();
|
||||||
|
const int addedId = addedNotification.value(ID).toInt();
|
||||||
|
notificationGroup->activeNotifications.insert(addedId, addedNotification);
|
||||||
|
notificationGroup->notificationOrder.append(addedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (notificationGroups.isEmpty()) {
|
||||||
|
// No active notifications left at all
|
||||||
|
controlLedNotification(false);
|
||||||
|
} else if (needFeedback) {
|
||||||
|
controlLedNotification(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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::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)
|
void NotificationManager::handleNgfConnectionStatus(bool connected)
|
||||||
|
@ -193,66 +332,62 @@ 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);
|
||||||
|
if (!notificationGroup->notificationOrder.isEmpty()) {
|
||||||
|
const int lastNotificationId = notificationGroup->notificationOrder.last();
|
||||||
|
const QVariantMap lastNotification(notificationGroup->activeNotifications.value(lastNotificationId));
|
||||||
|
messageMap = lastNotification.value(TYPE).toMap().value(MESSAGE).toMap();
|
||||||
|
}
|
||||||
|
|
||||||
const QVariantMap chatInformation = this->chatMap.value(chatId).toMap();
|
Notification *nemoNotification = notificationGroup->nemoNotification;
|
||||||
const QVariantMap chatTypeInformation = chatInformation.value(TYPE).toMap();
|
if (!messageMap.isEmpty()) {
|
||||||
const QString chatType = chatTypeInformation.value(_TYPE).toString();
|
nemoNotification->setTimestamp(QDateTime::fromMSecsSinceEpoch(messageMap.value(DATE).toLongLong() * 1000));
|
||||||
const bool addAuthor = (chatType == CHAT_TYPE_BASIC_GROUP || ( chatType == CHAT_TYPE_SUPERGROUP && !chatTypeInformation.value(IS_CHANNEL).toBool() ));
|
|
||||||
|
|
||||||
const QVariantMap messageMap = notificationInformation.value(TYPE).toMap().value(MESSAGE).toMap();
|
QVariantList remoteActionArguments;
|
||||||
Notification nemoNotification;
|
remoteActionArguments.append(QString::number(notificationGroup->chatId));
|
||||||
nemoNotification.setAppName(APP_NAME);
|
remoteActionArguments.append(messageMap.value(ID).toString());
|
||||||
nemoNotification.setAppIcon(appIconFile);
|
nemoNotification->setRemoteAction(Notification::remoteAction("default", "openMessage",
|
||||||
nemoNotification.setSummary(chatInformation.value(TITLE).toString());
|
"de.ygriega.fernschreiber", "/de/ygriega/fernschreiber", "de.ygriega.fernschreiber",
|
||||||
nemoNotification.setTimestamp(QDateTime::fromMSecsSinceEpoch(messageMap.value(DATE).toLongLong() * 1000));
|
"openMessage", remoteActionArguments));
|
||||||
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;
|
QString notificationBody;
|
||||||
const AppSettings::NotificationFeedback feedbackStyle = appSettings->notificationFeedback();
|
if (notificationGroup->totalCount == 1 && !messageMap.isEmpty()) {
|
||||||
|
LOG("Group" << notificationGroup->notificationGroupId << "has 1 notification");
|
||||||
if (activeNotifications.isEmpty()) {
|
if (chatInformation && (chatInformation->type == TDLibWrapper::ChatTypeBasicGroup ||
|
||||||
QString notificationBody;
|
(chatInformation->type == TDLibWrapper::ChatTypeSupergroup && !chatInformation->isChannel))) {
|
||||||
if (addAuthor) {
|
// Add author
|
||||||
const QVariantMap authorInformation = tdLibWrapper->getUserInformation(messageMap.value(SENDER_USER_ID).toString());
|
const QVariantMap authorInformation = tdLibWrapper->getUserInformation(messageMap.value(SENDER_USER_ID).toString());
|
||||||
const QString firstName = authorInformation.value(FIRST_NAME).toString();
|
const QString firstName = authorInformation.value(FIRST_NAME).toString();
|
||||||
const QString lastName = authorInformation.value(LAST_NAME).toString();
|
const QString lastName = authorInformation.value(LAST_NAME).toString();
|
||||||
const QString fullName = firstName + " " + lastName;
|
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(NOTIFICATION_CATEGORY);
|
nemoNotification->setCategory(NOTIFICATION_CATEGORY);
|
||||||
|
nemoNotification->setPreviewBody(nemoNotification->body());
|
||||||
|
nemoNotification->setPreviewSummary(nemoNotification->summary());
|
||||||
ngfClient->play(NGF_EVENT);
|
ngfClient->play(NGF_EVENT);
|
||||||
|
} else {
|
||||||
|
nemoNotification->setCategory(QString());
|
||||||
|
nemoNotification->setPreviewBody(QString());
|
||||||
|
nemoNotification->setPreviewSummary(QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
nemoNotification.publish();
|
nemoNotification->publish();
|
||||||
this->controlLedNotification(true);
|
|
||||||
|
|
||||||
QVariantMap updatedNotificationInformation = notificationInformation;
|
|
||||||
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)
|
||||||
|
|
|
@ -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,18 +30,21 @@
|
||||||
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 handleChatTitleUpdated(const QString &chatId, const QString &title);
|
||||||
void handleNgfConnectionStatus(bool connected);
|
void handleNgfConnectionStatus(bool connected);
|
||||||
void handleNgfEventFailed(quint32 eventId);
|
void handleNgfEventFailed(quint32 eventId);
|
||||||
void handleNgfEventCompleted(quint32 eventId);
|
void handleNgfEventCompleted(quint32 eventId);
|
||||||
|
@ -49,18 +53,21 @@ public slots:
|
||||||
|
|
||||||
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(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;
|
QString appIconFile;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue