Hide native notifications of deleted messages.

This commit is contained in:
John Preston 2021-10-15 17:57:27 +04:00
parent 1f95e00793
commit d361f5c6b0
7 changed files with 108 additions and 16 deletions

View File

@ -828,6 +828,7 @@ public:
const QString &msg,
DisplayOptions options);
void clearAll();
void clearFromItem(not_null<HistoryItem*> item);
void clearFromHistory(not_null<History*> history);
void clearFromSession(not_null<Main::Session*> session);
void clearNotification(NotificationId id);
@ -943,6 +944,30 @@ void Manager::Private::clearAll() {
}
}
void Manager::Private::clearFromItem(not_null<HistoryItem*> item) {
if (!Supported()) {
return;
}
const auto key = FullPeer{
.sessionId = item->history()->session().uniqueId(),
.peerId = item->history()->peer->id
};
const auto i = _notifications.find(key);
if (i == _notifications.cend()) {
return;
}
const auto j = i->second.find(item->id);
if (j == i->second.end()) {
return;
}
const auto taken = base::take(j->second);
i->second.erase(j);
if (i->second.empty()) {
_notifications.erase(i);
}
taken->close();
}
void Manager::Private::clearFromHistory(not_null<History*> history) {
if (!Supported()) {
return;
@ -952,7 +977,7 @@ void Manager::Private::clearFromHistory(not_null<History*> history) {
.sessionId = history->session().uniqueId(),
.peerId = history->peer->id
};
auto i = _notifications.find(key);
const auto i = _notifications.find(key);
if (i != _notifications.cend()) {
const auto temp = base::take(i->second);
_notifications.erase(i);
@ -1033,6 +1058,10 @@ void Manager::doClearAllFast() {
_private->clearAll();
}
void Manager::doClearFromItem(not_null<HistoryItem*> item) {
_private->clearFromItem(item);
}
void Manager::doClearFromHistory(not_null<History*> history) {
_private->clearFromHistory(history);
}

View File

@ -28,6 +28,7 @@ protected:
const QString &msg,
DisplayOptions options) override;
void doClearAllFast() override;
void doClearFromItem(not_null<HistoryItem*> item) override;
void doClearFromHistory(not_null<History*> history) override;
void doClearFromSession(not_null<Main::Session*> session) override;
bool doSkipAudio() const override;

View File

@ -28,6 +28,7 @@ protected:
const QString &msg,
DisplayOptions options) override;
void doClearAllFast() override;
void doClearFromItem(not_null<HistoryItem*> item) override;
void doClearFromHistory(not_null<History*> history) override;
void doClearFromSession(not_null<Main::Session*> session) override;
QString accountNameSeparator() override;

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/platform/mac/base_utilities_mac.h"
#include "base/random.h"
#include "history/history.h"
#include "history/history_item.h"
#include "ui/empty_userpic.h"
#include "main/main_session.h"
#include "mainwindow.h"
@ -107,7 +108,7 @@ using Manager = Platform::Notifications::Manager;
}
NSNumber *msgObject = [notificationUserInfo objectForKey:@"msgid"];
const auto notificationMsgId = msgObject ? [msgObject intValue] : 0;
const auto notificationMsgId = msgObject ? [msgObject longLongValue] : 0LL;
const auto my = Window::Notifications::Manager::NotificationId{
.full = Manager::FullPeer{
@ -186,6 +187,7 @@ public:
const QString &msg,
DisplayOptions options);
void clearAll();
void clearFromItem(not_null<HistoryItem*> item);
void clearFromHistory(not_null<History*> history);
void clearFromSession(not_null<Main::Session*> session);
void updateDelegate();
@ -207,6 +209,9 @@ private:
std::mutex _clearingMutex;
std::condition_variable _clearingCondition;
struct ClearFromItem {
NotificationId id;
};
struct ClearFromHistory {
FullPeer fullPeer;
};
@ -218,6 +223,7 @@ private:
struct ClearFinish {
};
using ClearTask = std::variant<
ClearFromItem,
ClearFromHistory,
ClearFromSession,
ClearAll,
@ -268,7 +274,7 @@ void Manager::Private::showNotification(
@"session",
[NSNumber numberWithUnsignedLongLong:peer->id.value],
@"peer",
[NSNumber numberWithInt:msgId.bare],
[NSNumber numberWithLongLong:msgId.bare],
@"msgid",
[NSNumber numberWithUnsignedLongLong:_managerId],
@"manager",
@ -305,6 +311,7 @@ void Manager::Private::clearingThreadLoop() {
auto finished = false;
while (!finished) {
auto clearAll = false;
auto clearFromItems = base::flat_set<NotificationId>();
auto clearFromPeers = base::flat_set<FullPeer>();
auto clearFromSessions = base::flat_set<uint64>();
{
@ -318,6 +325,8 @@ void Manager::Private::clearingThreadLoop() {
clearAll = true;
}, [&](ClearAll) {
clearAll = true;
}, [&](const ClearFromItem &value) {
clearFromItems.emplace(value.id);
}, [&](const ClearFromHistory &value) {
clearFromPeers.emplace(value.fullPeer);
}, [&](const ClearFromSession &value) {
@ -335,17 +344,21 @@ void Manager::Private::clearingThreadLoop() {
if (!notificationSessionId) {
return true;
}
if (NSNumber *peerObject = [notificationUserInfo objectForKey:@"peer"]) {
const auto notificationPeerId = [peerObject unsignedLongLongValue];
if (notificationPeerId) {
return clearFromSessions.contains(notificationSessionId)
|| clearFromPeers.contains(FullPeer{
.sessionId = notificationSessionId,
.peerId = PeerId(notificationPeerId)
});
}
NSNumber *peerObject = [notificationUserInfo objectForKey:@"peer"];
const auto notificationPeerId = peerObject ? [peerObject unsignedLongLongValue] : 0;
if (!notificationPeerId) {
return true;
}
return true;
NSNumber *msgObject = [notificationUserInfo objectForKey:@"msgid"];
const auto msgId = msgObject ? [msgObject longLongValue] : 0LL;
const auto full = FullPeer{
.sessionId = notificationSessionId,
.peerId = PeerId(notificationPeerId)
};
const auto id = NotificationId{ full, MsgId(msgId) };
return clearFromSessions.contains(notificationSessionId)
|| clearFromPeers.contains(full)
|| (msgId && clearFromItems.contains(id));
};
NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter];
@ -380,6 +393,13 @@ void Manager::Private::clearAll() {
putClearTask(ClearAll());
}
void Manager::Private::clearFromItem(not_null<HistoryItem*> item) {
putClearTask(ClearFromItem { FullPeer{
.sessionId = history->session().uniqueId(),
.peerId = history->peer->id
}, item->id });
}
void Manager::Private::clearFromHistory(not_null<History*> history) {
putClearTask(ClearFromHistory { FullPeer{
.sessionId = history->session().uniqueId(),
@ -434,6 +454,10 @@ void Manager::doClearAllFast() {
_private->clearAll();
}
void Manager::doClearFromItem(not_null<HistoryItem*> item) {
_private->clearFromItem(item);
}
void Manager::doClearFromHistory(not_null<History*> history) {
_private->clearFromHistory(history);
}

View File

@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "platform/win/windows_dlls.h"
#include "platform/win/specific_win.h"
#include "history/history.h"
#include "history/history_item.h"
#include "core/application.h"
#include "core/core_settings.h"
#include "main/main_session.h"
@ -418,6 +419,7 @@ public:
const QString &msg,
DisplayOptions options);
void clearAll();
void clearFromItem(not_null<HistoryItem*> item);
void clearFromHistory(not_null<History*> history);
void clearFromSession(not_null<Main::Session*> session);
void beforeNotificationActivated(NotificationId id);
@ -489,6 +491,30 @@ void Manager::Private::clearAll() {
}
}
void Manager::Private::clearFromItem(not_null<HistoryItem*> item) {
if (!_notifier) {
return;
}
auto i = _notifications.find(FullPeer{
.sessionId = item->history()->session().uniqueId(),
.peerId = item->history()->peer->id
});
if (i == _notifications.cend()) {
return;
}
const auto j = i->second.find(item->id);
if (j == end(i->second)) {
return;
}
const auto taken = std::exchange(j->second, nullptr);
i->second.erase(j);
if (i->second.empty()) {
_notifications.erase(i);
}
_notifier.Hide(taken);
}
void Manager::Private::clearFromHistory(not_null<History*> history) {
if (!_notifier) {
return;
@ -499,7 +525,7 @@ void Manager::Private::clearFromHistory(not_null<History*> history) {
.peerId = history->peer->id
});
if (i != _notifications.cend()) {
auto temp = base::take(i->second);
const auto temp = base::take(i->second);
_notifications.erase(i);
for (const auto &[msgId, notification] : temp) {
@ -842,6 +868,10 @@ void Manager::doClearAllFast() {
_private->clearAll();
}
void Manager::doClearFromItem(not_null<HistoryItem*> item) {
_private->clearFromItem(item);
}
void Manager::doClearFromHistory(not_null<History*> history) {
_private->clearFromHistory(history);
}

View File

@ -36,6 +36,7 @@ protected:
const QString &msg,
DisplayOptions options) override;
void doClearAllFast() override;
void doClearFromItem(not_null<HistoryItem*> item) override;
void doClearFromHistory(not_null<History*> history) override;
void doClearFromSession(not_null<Main::Session*> session) override;
void onBeforeNotificationActivated(NotificationId id) override;

View File

@ -162,6 +162,12 @@ public:
struct NotificationId {
FullPeer full;
MsgId msgId = 0;
friend inline bool operator<(
const NotificationId &a,
const NotificationId &b) {
return std::tie(a.full, a.msgId) < std::tie(b.full, b.msgId);
}
};
explicit Manager(not_null<System*> system) : _system(system) {
@ -275,8 +281,6 @@ protected:
void doClearAll() override {
doClearAllFast();
}
void doClearFromItem(not_null<HistoryItem*> item) override {
}
void doShowNotification(
not_null<HistoryItem*> item,
int forwardedCount) override;
@ -314,6 +318,8 @@ protected:
}
void doClearAllFast() override {
}
void doClearFromItem(not_null<HistoryItem*> item) override {
}
void doClearFromHistory(not_null<History*> history) override {
}
void doClearFromSession(not_null<Main::Session*> session) override {