Remove deleted notifications from pending updates.

GitOrigin-RevId: 8061a9c0ba1814444fa9b906f4cbeb31da197dcb
This commit is contained in:
levlam 2018-11-22 20:17:26 +03:00
parent 949874c953
commit 0362a95b7a
4 changed files with 82 additions and 3 deletions

View File

@ -22056,7 +22056,7 @@ void MessagesManager::process_get_channel_difference_updates(
// if last message is pretty old, we might have missed the update // if last message is pretty old, we might have missed the update
bool need_repair_unread_count = bool need_repair_unread_count =
!new_messages.empty() && get_message_date(new_messages.back()) < G()->unix_time() - 2 * 86400; !new_messages.empty() && get_message_date(new_messages[0]) < G()->unix_time() - 2 * 86400;
for (auto &message : new_messages) { for (auto &message : new_messages) {
on_get_message(std::move(message), true, true, true, true, "get channel difference"); on_get_message(std::move(message), true, true, true, true, "get channel difference");

View File

@ -17,6 +17,7 @@
#include <algorithm> #include <algorithm>
#include <tuple> #include <tuple>
#include <unordered_set>
namespace td { namespace td {
@ -301,6 +302,10 @@ void NotificationManager::flush_pending_updates(int32 group_id) {
std::unordered_map<int32, size_t> notification_pos; std::unordered_map<int32, size_t> notification_pos;
size_t cur_pos = 1; size_t cur_pos = 1;
for (auto &update : updates) { for (auto &update : updates) {
if (update == nullptr) {
is_changed = true;
continue;
}
if (update->get_id() == td_api::updateNotificationGroup::ID) { if (update->get_id() == td_api::updateNotificationGroup::ID) {
auto update_ptr = static_cast<td_api::updateNotificationGroup *>(update.get()); auto update_ptr = static_cast<td_api::updateNotificationGroup *>(update.get());
bool is_deletion = !update_ptr->removed_notification_ids_.empty() && bool is_deletion = !update_ptr->removed_notification_ids_.empty() &&
@ -368,15 +373,18 @@ void NotificationManager::flush_pending_updates(int32 group_id) {
if (updates[i - 1] != nullptr && updates[i - 1]->get_id() == td_api::updateNotificationGroup::ID) { if (updates[i - 1] != nullptr && updates[i - 1]->get_id() == td_api::updateNotificationGroup::ID) {
auto previous_update_ptr = static_cast<td_api::updateNotificationGroup *>(updates[i - 1].get()); auto previous_update_ptr = static_cast<td_api::updateNotificationGroup *>(updates[i - 1].get());
previous_update_ptr->total_count_ = update_ptr->total_count_; previous_update_ptr->total_count_ = update_ptr->total_count_;
is_changed = true;
update = nullptr; update = nullptr;
break; break;
} }
} }
if (update != nullptr && update_ptr->total_count_ == 0) { if (update != nullptr && (cur_pos == 1 || update_ptr->total_count_ == 0)) {
is_changed = true;
update = nullptr; update = nullptr;
} }
} }
} else { } else {
CHECK(update->get_id() == td_api::updateNotification::ID);
auto update_ptr = static_cast<td_api::updateNotification *>(update.get()); auto update_ptr = static_cast<td_api::updateNotification *>(update.get());
auto notification_id = update_ptr->notification_->id_; auto notification_id = update_ptr->notification_->id_;
auto &pos = notification_pos[notification_id]; auto &pos = notification_pos[notification_id];
@ -722,6 +730,52 @@ void NotificationManager::on_notifications_removed(
*/ */
} }
void NotificationManager::remove_added_notifications_from_pending_updates(
NotificationGroupId group_id,
std::function<bool(const td_api::object_ptr<td_api::notification> &notification)> is_removed) {
auto it = pending_updates_.find(group_id.get());
if (it == pending_updates_.end()) {
return;
}
std::unordered_set<int32> removed_notification_ids;
for (auto &update : it->second) {
if (update == nullptr) {
continue;
}
if (update->get_id() == td_api::updateNotificationGroup::ID) {
auto update_ptr = static_cast<td_api::updateNotificationGroup *>(update.get());
if (!removed_notification_ids.empty() && !update_ptr->removed_notification_ids_.empty()) {
update_ptr->removed_notification_ids_.erase(
std::remove_if(update_ptr->removed_notification_ids_.begin(), update_ptr->removed_notification_ids_.end(),
[&removed_notification_ids](auto &notification_id) {
return removed_notification_ids.count(notification_id) == 1;
}),
update_ptr->removed_notification_ids_.end());
}
for (auto &notification : update_ptr->added_notifications_) {
if (is_removed(notification)) {
removed_notification_ids.insert(notification->id_);
VLOG(notifications) << "Remove " << NotificationId(notification->id_) << " in " << group_id;
notification = nullptr;
}
}
update_ptr->added_notifications_.erase(
std::remove_if(update_ptr->added_notifications_.begin(), update_ptr->added_notifications_.end(),
[](auto &notification) { return notification == nullptr; }),
update_ptr->added_notifications_.end());
} else {
CHECK(update->get_id() == td_api::updateNotification::ID);
auto update_ptr = static_cast<td_api::updateNotification *>(update.get());
if (is_removed(update_ptr->notification_)) {
removed_notification_ids.insert(update_ptr->notification_->id_);
VLOG(notifications) << "Remove " << NotificationId(update_ptr->notification_->id_) << " in " << group_id;
update = nullptr;
}
}
}
}
void NotificationManager::remove_notification(NotificationGroupId group_id, NotificationId notification_id, void NotificationManager::remove_notification(NotificationGroupId group_id, NotificationId notification_id,
bool is_permanent, Promise<Unit> &&promise) { bool is_permanent, Promise<Unit> &&promise) {
if (!notification_id.is_valid()) { if (!notification_id.is_valid()) {
@ -792,6 +846,11 @@ void NotificationManager::remove_notification(NotificationGroupId group_id, Noti
on_notifications_removed(std::move(group_it), std::move(added_notifications), std::move(removed_notification_ids)); on_notifications_removed(std::move(group_it), std::move(added_notifications), std::move(removed_notification_ids));
} }
remove_added_notifications_from_pending_updates(
group_id, [notification_id](const td_api::object_ptr<td_api::notification> &notification) {
return notification->id_ == notification_id.get();
});
promise.set_value(Unit()); promise.set_value(Unit());
} }
@ -881,6 +940,21 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id
VLOG(notifications) << "Have new_total_count = " << new_total_count << " and " << removed_notification_ids.size() VLOG(notifications) << "Have new_total_count = " << new_total_count << " and " << removed_notification_ids.size()
<< " removed notifications"; << " removed notifications";
} }
if (max_notification_id.is_valid()) {
remove_added_notifications_from_pending_updates(
group_id, [max_notification_id](const td_api::object_ptr<td_api::notification> &notification) {
return notification->id_ <= max_notification_id.get();
});
} else {
remove_added_notifications_from_pending_updates(
group_id, [max_message_id](const td_api::object_ptr<td_api::notification> &notification) {
return notification->type_->get_id() == td_api::notificationTypeNewMessage::ID &&
static_cast<const td_api::notificationTypeNewMessage *>(notification->type_.get())->message_->id_ <=
max_message_id.get();
});
}
promise.set_value(Unit()); promise.set_value(Unit());
} }

View File

@ -20,6 +20,7 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
#include <functional>
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
@ -177,6 +178,10 @@ class NotificationManager : public Actor {
vector<td_api::object_ptr<td_api::notification>> &&added_notifications, vector<td_api::object_ptr<td_api::notification>> &&added_notifications,
vector<int32> &&removed_notification_ids); vector<int32> &&removed_notification_ids);
void remove_added_notifications_from_pending_updates(
NotificationGroupId group_id,
std::function<bool(const td_api::object_ptr<td_api::notification> &notification)> is_removed);
void flush_pending_updates(int32 group_id); void flush_pending_updates(int32 group_id);
NotificationId current_notification_id_; NotificationId current_notification_id_;

View File

@ -75,7 +75,7 @@ class NotificationTypeCall : public NotificationType {
} }
MessageId get_message_id() const override { MessageId get_message_id() const override {
return MessageId(); return MessageId::max();
} }
td_api::object_ptr<td_api::NotificationType> get_notification_type_object(DialogId dialog_id) const override { td_api::object_ptr<td_api::NotificationType> get_notification_type_object(DialogId dialog_id) const override {