Add td_api::notificationTypeNewPushMessage.
GitOrigin-RevId: 4708329ff77a23c82d7786d83f4e4c936c3dbee2
This commit is contained in:
parent
508889fadf
commit
e28d0eb3c0
@ -1944,13 +1944,17 @@ notificationTypeNewSecretChat = NotificationType;
|
||||
//@description New call was received @call_id Call identifier
|
||||
notificationTypeNewCall call_id:int32 = NotificationType;
|
||||
|
||||
//@description New message was received through a push notification @message_id The message identifier @sender_user_id Sender of the message. Corresponding user may be inaccessible
|
||||
//@content_type Notification content type @argument Optional argument for the notification content type
|
||||
notificationTypeNewPushMessage message_id:int53 sender_user_id:int32 content_type:string argument:string = NotificationType;
|
||||
|
||||
|
||||
//@class NotificationGroupType @description Describes type of notifications in the group
|
||||
|
||||
//@description A group containing notifications of type notificationTypeNewMessage with ordinary unread messages
|
||||
//@description A group containing notifications of type notificationTypeNewMessage and notificationTypeNewPushMessage with ordinary unread messages
|
||||
notificationGroupTypeMessages = NotificationGroupType;
|
||||
|
||||
//@description A group containing notifications of type notificationTypeNewMessage with unread mentions of the current user, replies to their messages, or a pinned message
|
||||
//@description A group containing notifications of type notificationTypeNewMessage and notificationTypeNewPushMessage with unread mentions of the current user, replies to their messages, or a pinned message
|
||||
notificationGroupTypeMentions = NotificationGroupType;
|
||||
|
||||
//@description A group containing a notification of type notificationTypeSecretChat
|
||||
|
Binary file not shown.
@ -462,6 +462,16 @@ NotificationId NotificationManager::get_first_notification_id(const Notification
|
||||
return NotificationId();
|
||||
}
|
||||
|
||||
NotificationId NotificationManager::get_last_notification_id(const NotificationGroup &group) {
|
||||
if (!group.pending_notifications.empty()) {
|
||||
return group.pending_notifications.back().notification_id;
|
||||
}
|
||||
if (!group.notifications.empty()) {
|
||||
return group.notifications.back().notification_id;
|
||||
}
|
||||
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
|
||||
@ -474,6 +484,18 @@ MessageId NotificationManager::get_first_message_id(const NotificationGroup &gro
|
||||
return MessageId();
|
||||
}
|
||||
|
||||
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
|
||||
if (!group.pending_notifications.empty()) {
|
||||
return group.pending_notifications.back().type->get_message_id();
|
||||
}
|
||||
if (!group.notifications.empty()) {
|
||||
return group.notifications.back().type->get_message_id();
|
||||
}
|
||||
return MessageId();
|
||||
}
|
||||
|
||||
void NotificationManager::load_message_notifications_from_database(const NotificationGroupKey &group_key,
|
||||
NotificationGroup &group, size_t desired_size) {
|
||||
if (!G()->parameters().use_message_db) {
|
||||
@ -787,6 +809,10 @@ void NotificationManager::add_notification(NotificationGroupId group_id, Notific
|
||||
<< dialog_id << " with settings from " << notification_settings_dialog_id
|
||||
<< (is_silent ? " silently" : " with sound") << ": " << *type;
|
||||
|
||||
if (!type->is_temporary()) {
|
||||
remove_temporary_notifications(group_id);
|
||||
}
|
||||
|
||||
auto group_it = get_group_force(group_id);
|
||||
if (group_it == groups_.end()) {
|
||||
group_it = add_group(NotificationGroupKey(group_id, dialog_id, 0), NotificationGroup());
|
||||
@ -796,6 +822,20 @@ void NotificationManager::add_notification(NotificationGroupId group_id, Notific
|
||||
}
|
||||
CHECK(group_it->second.type == group_type);
|
||||
|
||||
NotificationGroup &group = group_it->second;
|
||||
if (notification_id.get() <= get_last_notification_id(group).get()) {
|
||||
LOG(ERROR) << "Failed to add " << notification_id << " to " << group_id << " of type " << group_type << " in "
|
||||
<< dialog_id << ", because have already added " << get_last_notification_id(group);
|
||||
return;
|
||||
}
|
||||
auto message_id = type->get_message_id();
|
||||
if (message_id.is_valid() && message_id.get() <= get_last_message_id(group).get()) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
PendingNotification notification;
|
||||
notification.date = date;
|
||||
notification.settings_dialog_id = notification_settings_dialog_id;
|
||||
@ -807,7 +847,6 @@ void NotificationManager::add_notification(NotificationGroupId group_id, Notific
|
||||
VLOG(notifications) << "Delay " << notification_id << " for " << delay_ms << " milliseconds";
|
||||
auto flush_time = delay_ms * 0.001 + Time::now();
|
||||
|
||||
NotificationGroup &group = group_it->second;
|
||||
if (group.pending_notifications_flush_time == 0 || flush_time < group.pending_notifications_flush_time) {
|
||||
group.pending_notifications_flush_time = flush_time;
|
||||
flush_pending_notifications_timeout_.set_timeout_at(group_id.get(), group.pending_notifications_flush_time);
|
||||
@ -1268,10 +1307,10 @@ void NotificationManager::flush_all_pending_updates(bool include_delayed_chats,
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationManager::do_flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group,
|
||||
bool NotificationManager::do_flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group,
|
||||
vector<PendingNotification> &pending_notifications) {
|
||||
if (pending_notifications.empty()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
VLOG(notifications) << "Do flush " << pending_notifications.size() << " pending notifications in " << group_key
|
||||
@ -1281,6 +1320,7 @@ void NotificationManager::do_flush_pending_notifications(NotificationGroupKey &g
|
||||
size_t old_notification_count = group.notifications.size();
|
||||
size_t shown_notification_count = min(old_notification_count, max_notification_group_size_);
|
||||
|
||||
bool force_update = false;
|
||||
vector<td_api::object_ptr<td_api::notification>> added_notifications;
|
||||
added_notifications.reserve(pending_notifications.size());
|
||||
for (auto &pending_notification : pending_notifications) {
|
||||
@ -1290,6 +1330,9 @@ void NotificationManager::do_flush_pending_notifications(NotificationGroupKey &g
|
||||
if (added_notifications.back()->type_ == nullptr) {
|
||||
added_notifications.pop_back();
|
||||
} else {
|
||||
if (!notification.type->can_be_delayed()) {
|
||||
force_update = true;
|
||||
}
|
||||
group.notifications.push_back(std::move(notification));
|
||||
}
|
||||
}
|
||||
@ -1318,6 +1361,7 @@ void NotificationManager::do_flush_pending_notifications(NotificationGroupKey &g
|
||||
CHECK(removed_notification_ids.empty());
|
||||
}
|
||||
pending_notifications.clear();
|
||||
return force_update;
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::updateNotificationGroup> NotificationManager::get_remove_group_update(
|
||||
@ -1399,6 +1443,7 @@ void NotificationManager::flush_pending_notifications(NotificationGroupId group_
|
||||
auto last_group_key = get_last_updated_group_key();
|
||||
bool was_updated = group_key.last_notification_date != 0 && group_key < last_group_key;
|
||||
bool is_updated = final_group_key < last_group_key;
|
||||
bool force_update = false;
|
||||
|
||||
if (!is_updated) {
|
||||
CHECK(!was_updated);
|
||||
@ -1426,13 +1471,17 @@ void NotificationManager::flush_pending_notifications(NotificationGroupId group_
|
||||
for (auto &pending_notification : group.pending_notifications) {
|
||||
if (notification_settings_dialog_id != pending_notification.settings_dialog_id ||
|
||||
is_silent != pending_notification.is_silent) {
|
||||
do_flush_pending_notifications(group_key, group, grouped_notifications);
|
||||
if (do_flush_pending_notifications(group_key, group, grouped_notifications)) {
|
||||
force_update = true;
|
||||
}
|
||||
notification_settings_dialog_id = pending_notification.settings_dialog_id;
|
||||
is_silent = pending_notification.is_silent;
|
||||
}
|
||||
grouped_notifications.push_back(std::move(pending_notification));
|
||||
}
|
||||
do_flush_pending_notifications(group_key, group, grouped_notifications);
|
||||
if (do_flush_pending_notifications(group_key, group, grouped_notifications)) {
|
||||
force_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
group.pending_notifications_flush_time = 0;
|
||||
@ -1447,6 +1496,12 @@ void NotificationManager::flush_pending_notifications(NotificationGroupId group_
|
||||
}
|
||||
|
||||
add_group(std::move(final_group_key), std::move(group));
|
||||
|
||||
if (force_update) {
|
||||
auto id = group_key.group_id.get();
|
||||
flush_pending_updates_timeout_.cancel_timeout(id);
|
||||
flush_pending_updates(id, "on_notifications_removed");
|
||||
}
|
||||
}
|
||||
|
||||
void NotificationManager::flush_all_pending_notifications() {
|
||||
@ -1693,6 +1748,7 @@ void NotificationManager::remove_notification(NotificationGroupId group_id, Noti
|
||||
|
||||
vector<td_api::object_ptr<td_api::notification>> added_notifications;
|
||||
vector<int32> removed_notification_ids;
|
||||
CHECK(max_notification_group_size_ > 0);
|
||||
if (is_found && notification_pos + max_notification_group_size_ >= old_group_size) {
|
||||
removed_notification_ids.push_back(notification_id.get());
|
||||
if (old_group_size >= max_notification_group_size_ + 1) {
|
||||
@ -1702,7 +1758,8 @@ void NotificationManager::remove_notification(NotificationGroupId group_id, Noti
|
||||
if (added_notifications.back()->type_ == nullptr) {
|
||||
added_notifications.pop_back();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if (added_notifications.empty()) {
|
||||
load_message_notifications_from_database(group_it->first, group_it->second, keep_notification_group_size_);
|
||||
}
|
||||
}
|
||||
@ -1769,6 +1826,7 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id
|
||||
}
|
||||
}
|
||||
if (new_total_count != -1) {
|
||||
new_total_count += get_temporary_notification_total_count(group_it->second);
|
||||
new_total_count -= static_cast<int32>(group_it->second.pending_notifications.size());
|
||||
if (new_total_count < 0) {
|
||||
LOG(ERROR) << "Have wrong new_total_count " << new_total_count << " + "
|
||||
@ -1837,6 +1895,101 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
|
||||
void NotificationManager::remove_temporary_notifications(NotificationGroupId group_id) {
|
||||
CHECK(group_id.is_valid());
|
||||
|
||||
if (is_disabled() || max_notification_group_count_ == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto group_it = get_group_force(group_id);
|
||||
if (group_it == groups_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto &group = group_it->second;
|
||||
while (!group.pending_notifications.empty() && group.pending_notifications.back().type->is_temporary()) {
|
||||
VLOG(notifications) << "Remove temporary " << group.pending_notifications.back() << " from " << group_id;
|
||||
// notification is still pending, just delete it
|
||||
group.pending_notifications.pop_back();
|
||||
if (group.pending_notifications.empty()) {
|
||||
group.pending_notifications_flush_time = 0;
|
||||
flush_pending_notifications_timeout_.cancel_timeout(group_id.get());
|
||||
on_pending_notification_update_count_changed(-1, group_id.get(), "remove_temporary_notifications");
|
||||
}
|
||||
}
|
||||
|
||||
auto old_group_size = group.notifications.size();
|
||||
size_t notification_pos = old_group_size;
|
||||
for (size_t pos = 0; pos < notification_pos; pos++) {
|
||||
if (group.notifications[pos].type->is_temporary()) {
|
||||
notification_pos = pos;
|
||||
}
|
||||
}
|
||||
if (notification_pos == old_group_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool is_total_count_changed = false;
|
||||
if (group.total_count == 0) {
|
||||
LOG(ERROR) << "Total notification count became negative in " << group_id << " after removing "
|
||||
<< old_group_size - notification_pos << " temporary notificaitons";
|
||||
} else {
|
||||
group.total_count -= narrow_cast<int32>(old_group_size - notification_pos);
|
||||
is_total_count_changed = true;
|
||||
}
|
||||
|
||||
vector<int32> removed_notification_ids;
|
||||
for (auto i = notification_pos; i < old_group_size; i++) {
|
||||
CHECK(group.notifications[i].type->is_temporary());
|
||||
VLOG(notifications) << "Remove temporary " << group.notifications[i] << " from " << group_id;
|
||||
if (i + max_notification_group_size_ >= old_group_size) {
|
||||
removed_notification_ids.push_back(group.notifications[i].notification_id.get());
|
||||
}
|
||||
}
|
||||
group.notifications.erase(group.notifications.begin() + notification_pos, group.notifications.end());
|
||||
CHECK(!removed_notification_ids.empty());
|
||||
|
||||
vector<td_api::object_ptr<td_api::notification>> added_notifications;
|
||||
if (old_group_size >= max_notification_group_size_) {
|
||||
for (size_t i = old_group_size - max_notification_group_size_;
|
||||
i-- > 0 && added_notifications.size() < removed_notification_ids.size();) {
|
||||
added_notifications.push_back(get_notification_object(group_it->first.dialog_id, group.notifications[i]));
|
||||
if (added_notifications.back()->type_ == nullptr) {
|
||||
added_notifications.pop_back();
|
||||
}
|
||||
}
|
||||
if (added_notifications.size() < removed_notification_ids.size()) {
|
||||
load_message_notifications_from_database(group_it->first, group, keep_notification_group_size_);
|
||||
}
|
||||
}
|
||||
|
||||
on_notifications_removed(std::move(group_it), std::move(added_notifications), std::move(removed_notification_ids),
|
||||
false);
|
||||
|
||||
remove_added_notifications_from_pending_updates(
|
||||
group_id, [](const td_api::object_ptr<td_api::notification> ¬ification) {
|
||||
return notification->get_id() == td_api::notificationTypeNewPushMessage::ID;
|
||||
});
|
||||
}
|
||||
|
||||
int32 NotificationManager::get_temporary_notification_total_count(const NotificationGroup &group) {
|
||||
int32 result = 0;
|
||||
for (auto ¬ification : reversed(group.notifications)) {
|
||||
if (!notification.type->is_temporary()) {
|
||||
break;
|
||||
}
|
||||
result++;
|
||||
}
|
||||
for (auto &pending_notification : reversed(group.pending_notifications)) {
|
||||
if (!pending_notification.type->is_temporary()) {
|
||||
break;
|
||||
}
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void NotificationManager::set_notification_total_count(NotificationGroupId group_id, int32 new_total_count) {
|
||||
if (!group_id.is_valid()) {
|
||||
return;
|
||||
@ -1851,6 +2004,7 @@ void NotificationManager::set_notification_total_count(NotificationGroupId group
|
||||
return;
|
||||
}
|
||||
|
||||
new_total_count += get_temporary_notification_total_count(group_it->second);
|
||||
new_total_count -= static_cast<int32>(group_it->second.pending_notifications.size());
|
||||
if (new_total_count < 0) {
|
||||
LOG(ERROR) << "Have wrong new_total_count " << new_total_count << " after removing "
|
||||
@ -2803,6 +2957,10 @@ Status NotificationManager::process_message_push_notification(DialogId dialog_id
|
||||
}
|
||||
CHECK(random_id == 0);
|
||||
|
||||
if (is_disabled() || max_notification_group_count_ == 0) {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
auto notification_id = get_next_notification_id();
|
||||
if (!notification_id.is_valid()) {
|
||||
return Status::OK();
|
||||
|
@ -205,8 +205,16 @@ class NotificationManager : public Actor {
|
||||
|
||||
static NotificationId get_first_notification_id(const NotificationGroup &group);
|
||||
|
||||
static NotificationId get_last_notification_id(const NotificationGroup &group);
|
||||
|
||||
static MessageId get_first_message_id(const NotificationGroup &group);
|
||||
|
||||
static MessageId get_last_message_id(const NotificationGroup &group);
|
||||
|
||||
static int32 get_temporary_notification_total_count(const NotificationGroup &group);
|
||||
|
||||
void remove_temporary_notifications(NotificationGroupId group_id);
|
||||
|
||||
int32 load_message_notification_groups_from_database(int32 limit, bool send_update);
|
||||
|
||||
void load_message_notifications_from_database(const NotificationGroupKey &group_key, NotificationGroup &group,
|
||||
@ -233,8 +241,8 @@ class NotificationManager : public Actor {
|
||||
int32 get_notification_delay_ms(DialogId dialog_id, const PendingNotification ¬ification,
|
||||
int32 min_delay_ms) const;
|
||||
|
||||
void do_flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group,
|
||||
vector<PendingNotification> &pending_notifications);
|
||||
bool do_flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group,
|
||||
vector<PendingNotification> &pending_notifications) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
void flush_pending_notifications(NotificationGroupId group_id);
|
||||
|
||||
|
@ -18,6 +18,10 @@ class NotificationTypeMessage : public NotificationType {
|
||||
return message_id_.is_valid() && message_id_.is_server();
|
||||
}
|
||||
|
||||
bool is_temporary() const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
MessageId get_message_id() const override {
|
||||
return message_id_;
|
||||
}
|
||||
@ -50,6 +54,10 @@ class NotificationTypeSecretChat : public NotificationType {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_temporary() const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
MessageId get_message_id() const override {
|
||||
return MessageId();
|
||||
}
|
||||
@ -76,6 +84,10 @@ class NotificationTypeCall : public NotificationType {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_temporary() const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
MessageId get_message_id() const override {
|
||||
return MessageId::max();
|
||||
}
|
||||
@ -104,15 +116,18 @@ class NotificationTypePushMessage : public NotificationType {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_temporary() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
MessageId get_message_id() const override {
|
||||
return message_id_;
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::NotificationType> get_notification_type_object(DialogId dialog_id) const override {
|
||||
// auto sender_user_id = G()->td().get_actor_unsafe()->contacts_manager_->get_user_id_object(
|
||||
// sender_user_id_, "get_notification_type_object");
|
||||
// return td_api::make_object<td_api::notificationTypeNewPushMessage>(sender_user_id, message_id_.get(), key_, arg_);
|
||||
return nullptr;
|
||||
auto sender_user_id = G()->td().get_actor_unsafe()->contacts_manager_->get_user_id_object(
|
||||
sender_user_id_, "get_notification_type_object");
|
||||
return td_api::make_object<td_api::notificationTypeNewPushMessage>(message_id_.get(), sender_user_id, key_, arg_);
|
||||
}
|
||||
|
||||
StringBuilder &to_string_builder(StringBuilder &string_builder) const override {
|
||||
|
@ -30,6 +30,8 @@ class NotificationType {
|
||||
|
||||
virtual bool can_be_delayed() const = 0;
|
||||
|
||||
virtual bool is_temporary() const = 0;
|
||||
|
||||
virtual MessageId get_message_id() const = 0;
|
||||
|
||||
virtual td_api::object_ptr<td_api::NotificationType> get_notification_type_object(DialogId dialog_id) const = 0;
|
||||
|
Reference in New Issue
Block a user