mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-10-30 09:30:47 +03:00
Clear notifications when event is read
This commit is contained in:
parent
537cc966cc
commit
2022775dd0
7 changed files with 95 additions and 3 deletions
|
@ -829,6 +829,7 @@ Cache::filterReadEvents(const QString &room_id,
|
|||
void
|
||||
Cache::updateReadReceipt(lmdb::txn &txn, const std::string &room_id, const Receipts &receipts)
|
||||
{
|
||||
auto user_id = this->localUserId_.toStdString();
|
||||
for (const auto &receipt : receipts) {
|
||||
const auto event_id = receipt.first;
|
||||
auto event_receipts = receipt.second;
|
||||
|
@ -857,8 +858,13 @@ Cache::updateReadReceipt(lmdb::txn &txn, const std::string &room_id, const Recei
|
|||
}
|
||||
|
||||
// Append the new ones.
|
||||
for (const auto &event_receipt : event_receipts)
|
||||
saved_receipts.emplace(event_receipt.first, event_receipt.second);
|
||||
for (const auto &[read_by, timestamp] : event_receipts) {
|
||||
if (read_by == user_id) {
|
||||
emit removeNotification(QString::fromStdString(room_id),
|
||||
QString::fromStdString(event_id));
|
||||
}
|
||||
saved_receipts.emplace(read_by, timestamp);
|
||||
}
|
||||
|
||||
// Save back the merged (or only the new) receipts.
|
||||
nlohmann::json json_updated_value = saved_receipts;
|
||||
|
|
|
@ -229,6 +229,7 @@ public:
|
|||
signals:
|
||||
void newReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
|
||||
void roomReadStatus(const std::map<QString, bool> &status);
|
||||
void removeNotification(const QString &room_id, const QString &event_id);
|
||||
|
||||
private:
|
||||
//! Save an invited room.
|
||||
|
|
|
@ -645,6 +645,11 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token)
|
|||
connect(
|
||||
cache::client(), &Cache::roomReadStatus, room_list_, &RoomList::updateReadStatus);
|
||||
|
||||
connect(cache::client(),
|
||||
&Cache::removeNotification,
|
||||
¬ificationsManager,
|
||||
&NotificationsManager::removeNotification);
|
||||
|
||||
const bool isInitialized = cache::isInitialized();
|
||||
const bool isValid = cache::isFormatValid();
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <QHash>
|
||||
#include <QImage>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
@ -15,6 +16,27 @@ struct roomEventId
|
|||
QString eventId;
|
||||
};
|
||||
|
||||
inline bool
|
||||
operator<(const roomEventId &a, const roomEventId &b)
|
||||
{
|
||||
if (a.roomId == b.roomId)
|
||||
return a.eventId < b.eventId;
|
||||
else
|
||||
return a.roomId < b.roomId;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(const roomEventId &a, const roomEventId &b)
|
||||
{
|
||||
return a.roomId == b.roomId && a.eventId == b.eventId;
|
||||
}
|
||||
|
||||
inline uint
|
||||
qHash(const roomEventId &v, uint seed)
|
||||
{
|
||||
return qHash(v.roomId, seed) ^ qHash(v.eventId, seed);
|
||||
}
|
||||
|
||||
class NotificationsManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -31,13 +53,21 @@ public:
|
|||
signals:
|
||||
void notificationClicked(const QString roomId, const QString eventId);
|
||||
|
||||
public slots:
|
||||
void removeNotification(const QString &roomId, const QString &eventId);
|
||||
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
|
||||
public:
|
||||
void closeNotifications(QString roomId);
|
||||
|
||||
private:
|
||||
QDBusInterface dbus;
|
||||
uint showNotification(const QString summary, const QString text, const QImage image);
|
||||
void closeNotification(uint id);
|
||||
|
||||
// notification ID to (room ID, event ID)
|
||||
QMap<uint, roomEventId> notificationIds;
|
||||
QHash<roomEventId, uint> eventToNotificationId;
|
||||
#endif
|
||||
|
||||
// these slots are platform specific (D-Bus only)
|
||||
|
|
|
@ -40,6 +40,7 @@ NotificationsManager::postNotification(const QString &roomid,
|
|||
{
|
||||
uint id = showNotification(roomname, sender + ": " + text, icon);
|
||||
notificationIds[id] = roomEventId{roomid, eventid};
|
||||
eventToNotificationId[roomEventId{roomid, eventid}] = id;
|
||||
}
|
||||
/**
|
||||
* This function is based on code from
|
||||
|
@ -54,6 +55,7 @@ NotificationsManager::showNotification(const QString summary,
|
|||
{
|
||||
QVariantMap hints;
|
||||
hints["image-data"] = image;
|
||||
hints["sound-name"] = "message-new-instant";
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << "nheko"; // app_name
|
||||
argumentList << (uint)0; // replace_id
|
||||
|
@ -78,6 +80,44 @@ NotificationsManager::showNotification(const QString summary,
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::closeNotification(uint id)
|
||||
{
|
||||
QList<QVariant> argumentList;
|
||||
argumentList << (uint)id; // replace_id
|
||||
|
||||
static QDBusInterface closeCall("org.freedesktop.Notifications",
|
||||
"/org/freedesktop/Notifications",
|
||||
"org.freedesktop.Notifications");
|
||||
QDBusMessage reply =
|
||||
closeCall.callWithArgumentList(QDBus::AutoDetect, "CloseNotification", argumentList);
|
||||
if (reply.type() == QDBusMessage::ErrorMessage) {
|
||||
qDebug() << "D-Bus Error:" << reply.errorMessage();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::removeNotification(const QString &roomId, const QString &eventId)
|
||||
{
|
||||
roomEventId reId = {roomId, eventId};
|
||||
if (eventToNotificationId.contains(reId)) {
|
||||
for (auto elem = notificationIds.begin(); elem != notificationIds.end(); ++elem) {
|
||||
if (elem.value().roomId != roomId)
|
||||
continue;
|
||||
|
||||
// close all notifications matching the eventId or having a lower
|
||||
// notificationId
|
||||
// This relies on the notificationId not wrapping around. This allows for
|
||||
// approximately 2,147,483,647 notifications, so it is a bit unlikely.
|
||||
// Otherwise we would need to store a 64bit counter instead.
|
||||
closeNotification(elem.key());
|
||||
|
||||
if (elem.value() == reId)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::actionInvoked(uint id, QString action)
|
||||
{
|
||||
|
@ -91,7 +131,7 @@ void
|
|||
NotificationsManager::notificationClosed(uint id, uint reason)
|
||||
{
|
||||
Q_UNUSED(reason);
|
||||
notificationIds.remove(id);
|
||||
eventToNotificationId.remove(notificationIds.take(id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,3 +46,8 @@ void
|
|||
NotificationsManager::notificationClosed(uint, uint)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
NotificationsManager::removeNotification(const QString &roomId, const QString &eventId)
|
||||
{}
|
||||
|
||||
|
|
|
@ -63,3 +63,8 @@ NotificationsManager::postNotification(const QString &room_id,
|
|||
void NotificationsManager::actionInvoked(uint, QString) {}
|
||||
|
||||
void NotificationsManager::notificationClosed(uint, uint) {}
|
||||
|
||||
void
|
||||
NotificationsManager::removeNotification(const QString &roomId, const QString &eventId)
|
||||
{}
|
||||
|
||||
|
|
Loading…
Reference in a new issue