From 4455255d9b884ef6ec0cc5ce0c47ca3d154793f1 Mon Sep 17 00:00:00 2001 From: levlam Date: Fri, 25 Aug 2023 02:04:44 +0300 Subject: [PATCH] Add class NotificationObjectId. --- CMakeLists.txt | 1 + td/telegram/MessagesManager.cpp | 18 +++-- td/telegram/NotificationManager.cpp | 119 +++++++++++++++------------- td/telegram/NotificationManager.h | 15 ++-- td/telegram/NotificationObjectId.h | 71 +++++++++++++++++ td/telegram/NotificationType.cpp | 12 +-- td/telegram/NotificationType.h | 4 +- td/telegram/Td.cpp | 3 +- 8 files changed, 162 insertions(+), 81 deletions(-) create mode 100644 td/telegram/NotificationObjectId.h diff --git a/CMakeLists.txt b/CMakeLists.txt index affd6ca02..884ebe0ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -723,6 +723,7 @@ set(TDLIB_SOURCE td/telegram/NotificationGroupType.h td/telegram/NotificationId.h td/telegram/NotificationManager.h + td/telegram/NotificationObjectId.h td/telegram/NotificationSettingsScope.h td/telegram/NotificationSettingsManager.h td/telegram/NotificationSound.h diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index dac77ed08..2e6e1a15a 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -52,6 +52,7 @@ #include "td/telegram/NotificationGroupInfo.hpp" #include "td/telegram/NotificationGroupType.h" #include "td/telegram/NotificationManager.h" +#include "td/telegram/NotificationObjectId.h" #include "td/telegram/NotificationSettingsManager.h" #include "td/telegram/NotificationSound.h" #include "td/telegram/NotificationType.h" @@ -15320,7 +15321,7 @@ void MessagesManager::set_dialog_pinned_message_notification(Dialog *d, MessageI remove_message_notification_id(d, m, true, false, true); on_message_changed(d, m, false, source); } else { - send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_message_id, + send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_object_id, notification_info->mention_notification_group_.get_group_id(), old_message_id, false, source); } } @@ -29285,11 +29286,12 @@ void MessagesManager::try_add_pinned_message_notification(Dialog *d, vectornotification_id, m->date, m->disable_notification, create_new_message_notification(message_id, is_message_preview_enabled(d, m, true))); - while (pos > 0 && res[pos - 1].type->get_message_id() < message_id) { + NotificationObjectId object_id(message_id); + while (pos > 0 && res[pos - 1].type->get_object_id() < object_id) { std::swap(res[pos - 1], res[pos]); pos--; } - if (pos > 0 && res[pos - 1].type->get_message_id() == message_id) { + if (pos > 0 && res[pos - 1].type->get_object_id() == object_id) { res.erase(res.begin() + pos); // notification was already there } if (res.size() > static_cast(limit)) { @@ -29732,10 +29734,10 @@ void MessagesManager::remove_message_notifications_by_message_ids(DialogId dialo if (message == nullptr) { LOG(INFO) << "Can't delete " << message_id << " because it is not found"; // call synchronously to remove them before ProcessPush returns - td_->notification_manager_->remove_temporary_notification_by_message_id( + td_->notification_manager_->remove_temporary_notification_by_object_id( d->notification_info->message_notification_group_.get_group_id(), message_id, true, "remove_message_notifications_by_message_ids"); - td_->notification_manager_->remove_temporary_notification_by_message_id( + td_->notification_manager_->remove_temporary_notification_by_object_id( d->notification_info->mention_notification_group_.get_group_id(), message_id, true, "remove_message_notifications_by_message_ids"); continue; @@ -35561,10 +35563,10 @@ void MessagesManager::delete_message_from_database(Dialog *d, MessageId message_ } } } else if (!message_id.is_scheduled() && message_id > d->last_new_message_id && d->notification_info != nullptr) { - send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_message_id, + send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_object_id, d->notification_info->message_notification_group_.get_group_id(), message_id, false, "delete_message_from_database"); - send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_message_id, + send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_object_id, d->notification_info->mention_notification_group_.get_group_id(), message_id, false, "delete_message_from_database"); } @@ -36733,7 +36735,7 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab d->notification_info->mention_notification_group_.is_removed_object_id(pinned_message_id.get())) { VLOG(notifications) << "Remove disabled pinned message notification in " << pinned_message_id << " in " << dialog_id; - send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_message_id, + send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_object_id, d->notification_info->mention_notification_group_.get_group_id(), pinned_message_id, true, "fix pinned message notification"); d->notification_info->pinned_message_notification_message_id_ = MessageId(); diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 08b35c862..391705ddb 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -512,49 +512,49 @@ NotificationId NotificationManager::get_last_notification_id(const NotificationG return NotificationId(); } -MessageId NotificationManager::get_first_message_id(const NotificationGroup &group) { - // it's fine to return MessageId() if first notification has no message_id, because - // non-message notification can't be mixed with message notifications +NotificationObjectId NotificationManager::get_first_object_id(const NotificationGroup &group) { + // it's fine to return NotificationObjectId() if first notification has no object_id, because + // object_id is from the same scope within a notification group if (!group.notifications.empty()) { - return group.notifications[0].type->get_message_id(); + return group.notifications[0].type->get_object_id(); } if (!group.pending_notifications.empty()) { - return group.pending_notifications[0].type->get_message_id(); + return group.pending_notifications[0].type->get_object_id(); } - return MessageId(); + return NotificationObjectId(); } -MessageId NotificationManager::get_last_message_id(const NotificationGroup &group) { - // it's fine to return MessageId() if last notification has no message_id, because - // non-message notification can't be mixed with message notifications +NotificationObjectId NotificationManager::get_last_object_id(const NotificationGroup &group) { + // it's fine to return NotificationObjectId() if last notification has no object_id, because + // object_id is from the same scope within a notification group if (!group.pending_notifications.empty()) { - return group.pending_notifications.back().type->get_message_id(); + return group.pending_notifications.back().type->get_object_id(); } if (!group.notifications.empty()) { - return group.notifications.back().type->get_message_id(); + return group.notifications.back().type->get_object_id(); } - return MessageId(); + return NotificationObjectId(); } -MessageId NotificationManager::get_last_message_id_by_notification_id(const NotificationGroup &group, - NotificationId max_notification_id) { +NotificationObjectId NotificationManager::get_last_object_id_by_notification_id(const NotificationGroup &group, + NotificationId max_notification_id) { for (auto ¬ification : reversed(group.pending_notifications)) { if (notification.notification_id.get() <= max_notification_id.get()) { - auto message_id = notification.type->get_message_id(); - if (message_id.is_valid()) { - return message_id; + auto object_id = notification.type->get_object_id(); + if (object_id.is_valid()) { + return object_id; } } } for (auto ¬ification : reversed(group.notifications)) { if (notification.notification_id.get() <= max_notification_id.get()) { - auto message_id = notification.type->get_message_id(); - if (message_id.is_valid()) { - return message_id; + auto object_id = notification.type->get_object_id(); + if (object_id.is_valid()) { + return object_id; } } } - return MessageId(); + return NotificationObjectId(); } void NotificationManager::load_message_notifications_from_database(const NotificationGroupKey &group_key, @@ -573,13 +573,13 @@ void NotificationManager::load_message_notifications_from_database(const Notific size_t limit = desired_size - group.notifications.size(); auto first_notification_id = get_first_notification_id(group); auto from_notification_id = first_notification_id.is_valid() ? first_notification_id : NotificationId::max(); + auto first_object_id = get_first_object_id(group); switch (group.type) { case NotificationGroupType::SecretChat: case NotificationGroupType::Messages: case NotificationGroupType::Mentions: { - auto first_message_id = get_first_message_id(group); - auto from_message_id = first_message_id.is_valid() ? first_message_id : MessageId::max(); + auto from_message_id = first_object_id.is_valid() ? MessageId(first_object_id.get()) : MessageId::max(); send_closure(G()->messages_manager(), &MessagesManager::get_message_notifications_from_database, group_key.dialog_id, group_key.group_id, from_notification_id, from_message_id, static_cast(limit), @@ -623,9 +623,9 @@ void NotificationManager::on_get_message_notifications_from_database(Notificatio notifications.pop_back(); } } - auto first_message_id = get_first_message_id(group); - if (first_message_id.is_valid()) { - while (!notifications.empty() && notifications.back().type->get_message_id() >= first_message_id) { + auto first_object_id = get_first_object_id(group); + if (first_object_id.is_valid()) { + while (!notifications.empty() && notifications.back().type->get_object_id() >= first_object_id) { // possible if notifications was added after the database request was sent notifications.pop_back(); } @@ -912,11 +912,11 @@ void NotificationManager::add_notification(NotificationGroupId group_id, Notific on_notification_removed(notification_id); return; } - auto message_id = type->get_message_id(); - if (message_id.is_valid() && message_id <= get_last_message_id(group)) { + auto object_id = type->get_object_id(); + if (object_id.is_valid() && object_id <= get_last_object_id(group)) { LOG(ERROR) << "Failed to add " << notification_id << " of type " << *type << " to " << group_id << " of type " << group_type << " in " << dialog_id << ", because have already added notification about " - << get_last_message_id(group); + << get_last_object_id(group); on_notification_removed(notification_id); return; } @@ -1665,7 +1665,7 @@ void NotificationManager::edit_notification(NotificationGroupId group_id, Notifi for (size_t i = 0; i < group.notifications.size(); i++) { auto ¬ification = group.notifications[i]; if (notification.notification_id == notification_id) { - if (notification.type->get_message_id() != type->get_message_id() || + if (notification.type->get_object_id() != type->get_object_id() || notification.type->is_temporary() != type->is_temporary()) { LOG(ERROR) << "Ignore edit of " << notification_id << " with " << *type << ", because previous type is " << *notification.type; @@ -1683,7 +1683,7 @@ void NotificationManager::edit_notification(NotificationGroupId group_id, Notifi } for (auto ¬ification : group.pending_notifications) { if (notification.notification_id == notification_id) { - if (notification.type->get_message_id() != type->get_message_id() || + if (notification.type->get_object_id() != type->get_object_id() || notification.type->is_temporary() != type->is_temporary()) { LOG(ERROR) << "Ignore edit of " << notification_id << " with " << *type << ", because previous type is " << *notification.type; @@ -1972,44 +1972,44 @@ void NotificationManager::remove_notification(NotificationGroupId group_id, Noti promise.set_value(Unit()); } -void NotificationManager::remove_temporary_notification_by_message_id(NotificationGroupId group_id, - MessageId message_id, bool force_update, - const char *source) { +void NotificationManager::remove_temporary_notification_by_object_id(NotificationGroupId group_id, + NotificationObjectId object_id, bool force_update, + const char *source) { if (!group_id.is_valid()) { return; } - VLOG(notifications) << "Remove notification for " << message_id << " in " << group_id << " from " << source; - CHECK(message_id.is_valid()); + VLOG(notifications) << "Remove notification for " << object_id << " in " << group_id << " from " << source; + CHECK(object_id.is_valid()); auto group_it = get_group(group_id); if (group_it == groups_.end()) { return; } - auto remove_notification_by_message_id = [&](auto ¬ifications) { + auto remove_notification_by_object_id = [&](auto ¬ifications) { for (auto ¬ification : notifications) { - if (notification.type->get_message_id() == message_id) { + if (notification.type->get_object_id() == object_id) { for (auto file_id : notification.type->get_file_ids(td_)) { - this->td_->file_manager_->delete_file(file_id, Promise<>(), "remove_temporary_notification_by_message_id"); + this->td_->file_manager_->delete_file(file_id, Promise<>(), "remove_temporary_notification_by_object_id"); } return this->remove_notification(group_id, notification.notification_id, true, force_update, Auto(), - "remove_temporary_notification_by_message_id"); + "remove_temporary_notification_by_object_id"); } } }; - remove_notification_by_message_id(group_it->second.pending_notifications); - remove_notification_by_message_id(group_it->second.notifications); + remove_notification_by_object_id(group_it->second.pending_notifications); + remove_notification_by_object_id(group_it->second.notifications); } void NotificationManager::remove_notification_group(NotificationGroupId group_id, NotificationId max_notification_id, - MessageId max_message_id, int32 new_total_count, bool force_update, - Promise &&promise) { + NotificationObjectId max_object_id, int32 new_total_count, + bool force_update, Promise &&promise) { if (!group_id.is_valid()) { return promise.set_error(Status::Error(400, "Group identifier is invalid")); } - if (!max_notification_id.is_valid() && !max_message_id.is_valid()) { + if (!max_notification_id.is_valid() && !max_object_id.is_valid()) { return promise.set_error(Status::Error(400, "Notification identifier is invalid")); } @@ -2021,7 +2021,7 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id remove_temporary_notifications(group_id, "remove_notification_group"); } - VLOG(notifications) << "Remove " << group_id << " up to " << max_notification_id << " or " << max_message_id + VLOG(notifications) << "Remove " << group_id << " up to " << max_notification_id << " or " << max_object_id << " with new_total_count = " << new_total_count << " and force_update = " << force_update; auto group_it = get_group_force(group_id); @@ -2040,7 +2040,7 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id case NotificationGroupType::SecretChat: td_->messages_manager_->remove_message_notifications( group_it->first.dialog_id, group_id, max_notification_id, - get_last_message_id_by_notification_id(group_it->second, max_notification_id)); + MessageId(get_last_object_id_by_notification_id(group_it->second, max_notification_id).get())); break; case NotificationGroupType::Calls: // nothing to do @@ -2055,7 +2055,7 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id for (auto it = group_it->second.pending_notifications.begin(); it != group_it->second.pending_notifications.end(); ++it) { if (it->notification_id.get() <= max_notification_id.get() || - (max_message_id.is_valid() && it->type->get_message_id() <= max_message_id)) { + (max_object_id.is_valid() && it->type->get_object_id() <= max_object_id)) { pending_delete_end = it + 1; on_notification_removed(it->notification_id); } @@ -2084,7 +2084,7 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id for (size_t pos = 0; pos < notification_delete_end; pos++) { auto ¬ification = group_it->second.notifications[pos]; if (notification.notification_id.get() > max_notification_id.get() && - (!max_message_id.is_valid() || notification.type->get_message_id() > max_message_id)) { + (!max_object_id.is_valid() || notification.type->get_object_id() > max_object_id)) { notification_delete_end = pos; } else { on_notification_removed(notification.notification_id); @@ -2135,10 +2135,10 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id }); } else { remove_added_notifications_from_pending_updates( - group_id, [max_message_id](const td_api::object_ptr ¬ification) { + group_id, [max_object_id](const td_api::object_ptr ¬ification) { return notification->type_->get_id() == td_api::notificationTypeNewMessage::ID && static_cast(notification->type_.get())->message_->id_ <= - max_message_id.get(); + max_object_id.get(); }); } @@ -2308,17 +2308,22 @@ vector NotificationManager::get_notification_group_message_ids(Notifi return {}; } + if (group_it->second.type != NotificationGroupType::Mentions && + group_it->second.type != NotificationGroupType::Messages) { + return {}; + } + vector message_ids; for (auto ¬ification : group_it->second.notifications) { - auto message_id = notification.type->get_message_id(); - if (message_id.is_valid()) { - message_ids.push_back(message_id); + auto object_id = notification.type->get_object_id(); + if (object_id.is_valid()) { + message_ids.push_back(MessageId(object_id.get())); } } for (auto ¬ification : group_it->second.pending_notifications) { - auto message_id = notification.type->get_message_id(); - if (message_id.is_valid()) { - message_ids.push_back(message_id); + auto object_id = notification.type->get_object_id(); + if (object_id.is_valid()) { + message_ids.push_back(MessageId(object_id.get())); } } diff --git a/td/telegram/NotificationManager.h b/td/telegram/NotificationManager.h index 2d4414b4b..6ed59b005 100644 --- a/td/telegram/NotificationManager.h +++ b/td/telegram/NotificationManager.h @@ -16,6 +16,7 @@ #include "td/telegram/NotificationGroupKey.h" #include "td/telegram/NotificationGroupType.h" #include "td/telegram/NotificationId.h" +#include "td/telegram/NotificationObjectId.h" #include "td/telegram/NotificationType.h" #include "td/telegram/Photo.h" #include "td/telegram/td_api.h" @@ -82,11 +83,11 @@ class NotificationManager final : public Actor { void remove_temporary_notifications(NotificationGroupId group_id, const char *source); - void remove_temporary_notification_by_message_id(NotificationGroupId group_id, MessageId message_id, - bool force_update, const char *source); + void remove_temporary_notification_by_object_id(NotificationGroupId group_id, NotificationObjectId object_id, + bool force_update, const char *source); void remove_notification_group(NotificationGroupId group_id, NotificationId max_notification_id, - MessageId max_message_id, int32 new_total_count, bool force_update, + NotificationObjectId max_object_id, int32 new_total_count, bool force_update, Promise &&promise); void set_notification_total_count(NotificationGroupId group_id, int32 new_total_count); @@ -238,12 +239,12 @@ class NotificationManager final : public Actor { static NotificationId get_last_notification_id(const NotificationGroup &group); - static MessageId get_first_message_id(const NotificationGroup &group); + static NotificationObjectId get_first_object_id(const NotificationGroup &group); - static MessageId get_last_message_id(const NotificationGroup &group); + static NotificationObjectId get_last_object_id(const NotificationGroup &group); - static MessageId get_last_message_id_by_notification_id(const NotificationGroup &group, - NotificationId max_notification_id); + static NotificationObjectId get_last_object_id_by_notification_id(const NotificationGroup &group, + NotificationId max_notification_id); static int32 get_temporary_notification_total_count(const NotificationGroup &group); diff --git a/td/telegram/NotificationObjectId.h b/td/telegram/NotificationObjectId.h new file mode 100644 index 000000000..7f38727de --- /dev/null +++ b/td/telegram/NotificationObjectId.h @@ -0,0 +1,71 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageId.h" + +#include "td/utils/common.h" + +namespace td { + +class NotificationObjectId { + int64 id = 0; + + public: + NotificationObjectId() = default; + + NotificationObjectId(MessageId message_id) : id(message_id.get()) { + } + + static NotificationObjectId max() { + return NotificationObjectId(MessageId::max()); + } + + int64 get() const { + return id; + } + + bool is_valid() const { + return id > 0; + } + + bool operator==(const NotificationObjectId &other) const { + return id == other.id; + } + + bool operator!=(const NotificationObjectId &other) const { + return id != other.id; + } + + friend bool operator<(const NotificationObjectId &lhs, const NotificationObjectId &rhs) { + return lhs.id < rhs.id; + } + + friend bool operator>(const NotificationObjectId &lhs, const NotificationObjectId &rhs) { + return lhs.id > rhs.id; + } + + friend bool operator<=(const NotificationObjectId &lhs, const NotificationObjectId &rhs) { + return lhs.id <= rhs.id; + } + + friend bool operator>=(const NotificationObjectId &lhs, const NotificationObjectId &rhs) { + return lhs.id >= rhs.id; + } +}; + +struct NotificationObjectIdHash { + uint32 operator()(NotificationObjectId notification_object_id) const { + return Hash()(notification_object_id.get()); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, NotificationObjectId notification_object_id) { + return string_builder << "notification object " << notification_object_id.get(); +} + +} // namespace td diff --git a/td/telegram/NotificationType.cpp b/td/telegram/NotificationType.cpp index 34bc04cc8..09e85a66b 100644 --- a/td/telegram/NotificationType.cpp +++ b/td/telegram/NotificationType.cpp @@ -34,7 +34,7 @@ class NotificationTypeMessage final : public NotificationType { return false; } - MessageId get_message_id() const final { + NotificationObjectId get_object_id() const final { return message_id_; } @@ -73,8 +73,8 @@ class NotificationTypeSecretChat final : public NotificationType { return false; } - MessageId get_message_id() const final { - return MessageId(); + NotificationObjectId get_object_id() const final { + return NotificationObjectId(); } vector get_file_ids(const Td *td) const final { @@ -103,8 +103,8 @@ class NotificationTypeCall final : public NotificationType { return false; } - MessageId get_message_id() const final { - return MessageId::max(); + NotificationObjectId get_object_id() const final { + return NotificationObjectId::max(); } vector get_file_ids(const Td *td) const final { @@ -135,7 +135,7 @@ class NotificationTypePushMessage final : public NotificationType { return true; } - MessageId get_message_id() const final { + NotificationObjectId get_object_id() const final { return message_id_; } diff --git a/td/telegram/NotificationType.h b/td/telegram/NotificationType.h index 9f7242e89..cb732ea68 100644 --- a/td/telegram/NotificationType.h +++ b/td/telegram/NotificationType.h @@ -10,7 +10,7 @@ #include "td/telegram/DialogId.h" #include "td/telegram/Document.h" #include "td/telegram/files/FileId.h" -#include "td/telegram/MessageId.h" +#include "td/telegram/NotificationObjectId.h" #include "td/telegram/Photo.h" #include "td/telegram/td_api.h" #include "td/telegram/UserId.h" @@ -33,7 +33,7 @@ class NotificationType { virtual bool is_temporary() const = 0; - virtual MessageId get_message_id() const = 0; + virtual NotificationObjectId get_object_id() const = 0; virtual vector get_file_ids(const Td *td) const = 0; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index c7e5ef8c2..656bb232a 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -96,6 +96,7 @@ #include "td/telegram/NotificationGroupId.h" #include "td/telegram/NotificationId.h" #include "td/telegram/NotificationManager.h" +#include "td/telegram/NotificationObjectId.h" #include "td/telegram/NotificationSettingsManager.h" #include "td/telegram/NotificationSettingsScope.h" #include "td/telegram/OptionManager.h" @@ -5406,7 +5407,7 @@ void Td::on_request(uint64 id, const td_api::removeNotificationGroup &request) { CREATE_OK_REQUEST_PROMISE(); send_closure(notification_manager_actor_, &NotificationManager::remove_notification_group, NotificationGroupId(request.notification_group_id_), NotificationId(request.max_notification_id_), - MessageId(), -1, true, std::move(promise)); + NotificationObjectId(), -1, true, std::move(promise)); } void Td::on_request(uint64 id, const td_api::deleteMessages &request) {