diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 728a80d3..fd60762b 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -3801,6 +3801,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const { bool has_last_clear_history_message_id = last_clear_history_message_id.is_valid(); bool has_last_database_message_id = !has_last_database_message && last_database_message_id.is_valid(); bool has_message_notification_group_id = message_notification_group_id.is_valid(); + bool has_last_notification_date = last_notification_date > 0; BEGIN_STORE_FLAGS(); STORE_FLAG(has_draft_message); STORE_FLAG(has_last_database_message); @@ -3825,7 +3826,8 @@ void MessagesManager::Dialog::store(StorerT &storer) const { STORE_FLAG(has_last_database_message_id); STORE_FLAG(need_repair_server_unread_count); STORE_FLAG(is_marked_as_unread); - STORE_FLAG(has_message_notification_group_id); // 23 + STORE_FLAG(has_message_notification_group_id); + STORE_FLAG(has_last_notification_date); // 24 END_STORE_FLAGS(); store(dialog_id, storer); // must be stored at offset 4 @@ -3887,6 +3889,9 @@ void MessagesManager::Dialog::store(StorerT &storer) const { if (has_message_notification_group_id) { store(message_notification_group_id, storer); } + if (has_last_notification_date) { + store(last_notification_date, storer); + } } // do not forget to resolve dialog dependencies including dependencies of last_message @@ -3907,6 +3912,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { bool has_last_clear_history_message_id; bool has_last_database_message_id; bool has_message_notification_group_id; + bool has_last_notification_date; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_draft_message); PARSE_FLAG(has_last_database_message); @@ -3932,6 +3938,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { PARSE_FLAG(need_repair_server_unread_count); PARSE_FLAG(is_marked_as_unread); PARSE_FLAG(has_message_notification_group_id); + PARSE_FLAG(has_last_notification_date); END_PARSE_FLAGS(); parse(dialog_id, parser); // must be stored at offset 4 @@ -4017,6 +4024,9 @@ void MessagesManager::Dialog::parse(ParserT &parser) { if (has_message_notification_group_id) { parse(message_notification_group_id, parser); } + if (has_last_notification_date) { + parse(last_notification_date, parser); + } } template @@ -4255,7 +4265,7 @@ void MessagesManager::save_dialog_to_database(DialogId dialog_id) { CHECK(d != nullptr); LOG(INFO) << "Save " << dialog_id << " to database"; G()->td_db()->get_dialog_db_async()->add_dialog( - dialog_id, d->order, 0 /*TODO: last_notification_date*/, get_dialog_database_value(d), + dialog_id, d->order, d->last_notification_date, get_dialog_database_value(d), PromiseCreator::lambda([dialog_id](Result<> result) { send_closure(G()->messages_manager(), &MessagesManager::on_save_dialog_to_database, dialog_id, result.is_ok()); })); @@ -9788,6 +9798,13 @@ void MessagesManager::try_restore_dialog_reply_markup(Dialog *d, const Message * } } +void MessagesManager::set_dialog_last_notification_date(Dialog *d, int32 last_notification_date) { + if (last_notification_date != d->last_notification_date) { + d->last_notification_date = last_notification_date; + on_dialog_updated(d->dialog_id, "set_dialog_last_notification_date"); + } +} + void MessagesManager::on_update_sent_text_message(int64 random_id, tl_object_ptr message_media, vector> &&entities) { @@ -17442,6 +17459,7 @@ void MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f << ", but forced to send notification about " << m->message_id << " in " << d->dialog_id; m->notification_id = td_->notification_manager_->get_next_notification_id(); + set_dialog_last_notification_date(d, m->date); VLOG(notifications) << "Assign " << m->notification_id << " to " << m->message_id << " in " << d->dialog_id; send_closure_later(G()->notification_manager(), &NotificationManager::add_notification, get_dialog_message_notification_group_id(d), d->dialog_id, settings_dialog_id, @@ -20715,6 +20733,16 @@ void MessagesManager::update_message(Dialog *d, unique_ptr &old_message is_changed = true; } } + if (old_message->notification_id != new_message->notification_id) { + if (old_message->notification_id.is_valid()) { + if (new_message->notification_id.is_valid()) { + LOG(ERROR) << "Notification id for " << message_id << " in " << dialog_id << " has tried to change from " + << old_message->notification_id << " to " << new_message->notification_id; + } + } else { + old_message->notification_id = new_message->notification_id; + } + } if (old_message->reply_to_message_id != new_message->reply_to_message_id) { // Can't check "&& get_message_force(d, old_message->reply_to_message_id) == nullptr", because it diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 86781202..8715a975 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -867,6 +867,7 @@ class MessagesManager : public Actor { MessageId max_added_message_id; NotificationGroupId message_notification_group_id; + int32 last_notification_date = 0; bool has_contact_registered_message = false; @@ -1543,6 +1544,8 @@ class MessagesManager : public Actor { void try_restore_dialog_reply_markup(Dialog *d, const Message *m); + void set_dialog_last_notification_date(Dialog *d, int32 last_notification_date); + static string get_notification_settings_scope_database_key(NotificationSettingsScope scope); void save_scope_notification_settings(NotificationSettingsScope scope, const ScopeNotificationSettings &new_settings); diff --git a/td/telegram/NotificationGroupId.h b/td/telegram/NotificationGroupId.h index 2b091a03..3ef6ed8a 100644 --- a/td/telegram/NotificationGroupId.h +++ b/td/telegram/NotificationGroupId.h @@ -36,6 +36,10 @@ class NotificationGroupId { return id == other.id; } + bool operator!=(const NotificationGroupId &other) const { + return id != other.id; + } + template void store(StorerT &storer) const { storer.store_int(id); diff --git a/td/telegram/NotificationId.h b/td/telegram/NotificationId.h index a2712daf..3b78b2f9 100644 --- a/td/telegram/NotificationId.h +++ b/td/telegram/NotificationId.h @@ -36,6 +36,10 @@ class NotificationId { return id == other.id; } + bool operator!=(const NotificationId &other) const { + return id != other.id; + } + template void store(StorerT &storer) const { storer.store_int(id); diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index 4dd72da6..e7dd38b7 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -6,6 +6,8 @@ // #include "td/telegram/NotificationManager.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/ConfigShared.h" #include "td/telegram/Global.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" @@ -17,11 +19,27 @@ int VERBOSITY_NAME(notifications) = VERBOSITY_NAME(WARNING); NotificationManager::NotificationManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { } +bool NotificationManager::is_disabled() const { + LOG(ERROR) << "IS DISABLED"; + return td_->auth_manager_->is_bot(); +} + void NotificationManager::start_up() { + if (is_disabled()) { + return; + } + current_notification_id_ = NotificationId(to_integer(G()->td_db()->get_binlog_pmc()->get("notification_id_current"))); current_notification_group_id_ = NotificationGroupId(to_integer(G()->td_db()->get_binlog_pmc()->get("notification_group_id_current"))); + + max_notification_group_count_ = + G()->shared_config().get_option_integer("notification_group_count_max", DEFAULT_NOTIFICATION_GROUP_COUNT_MAX); + max_notification_group_size_ = + G()->shared_config().get_option_integer("notification_group_size_max", DEFAULT_NOTIFICATION_GROUP_SIZE_MAX); + + // TODO load groups } void NotificationManager::tear_down() { @@ -29,12 +47,20 @@ void NotificationManager::tear_down() { } NotificationId NotificationManager::get_next_notification_id() { + if (is_disabled()) { + return NotificationId(); + } + current_notification_id_ = NotificationId(current_notification_id_.get() % 0x7FFFFFFF + 1); G()->td_db()->get_binlog_pmc()->set("notification_id_current", to_string(current_notification_id_.get())); return current_notification_id_; } NotificationGroupId NotificationManager::get_next_notification_group_id() { + if (is_disabled()) { + return NotificationGroupId(); + } + current_notification_group_id_ = NotificationGroupId(current_notification_group_id_.get() % 0x7FFFFFFF + 1); G()->td_db()->get_binlog_pmc()->set("notification_group_id_current", to_string(current_notification_group_id_.get())); return current_notification_group_id_; @@ -43,6 +69,10 @@ NotificationGroupId NotificationManager::get_next_notification_group_id() { void NotificationManager::add_notification(NotificationGroupId group_id, DialogId dialog_id, DialogId notification_settings_dialog_id, bool silent, NotificationId notification_id, unique_ptr type) { + if (is_disabled()) { + return; + } + CHECK(type != nullptr); VLOG(notifications) << "Add " << notification_id << " to " << group_id << " in " << dialog_id << " with settings from " << notification_settings_dialog_id @@ -51,10 +81,17 @@ void NotificationManager::add_notification(NotificationGroupId group_id, DialogI } void NotificationManager::edit_notification(NotificationId notification_id, unique_ptr type) { + if (is_disabled()) { + return; + } + VLOG(notifications) << "Edit " << notification_id << ": " << *type; } void NotificationManager::delete_notification(NotificationId notification_id) { + if (is_disabled()) { + return; + } } void NotificationManager::remove_notification(NotificationId notification_id, Promise &&promise) { @@ -62,6 +99,10 @@ void NotificationManager::remove_notification(NotificationId notification_id, Pr return promise.set_error(Status::Error(400, "Notification identifier is invalid")); } + if (is_disabled()) { + return promise.set_value(Unit()); + } + // TODO update total_count promise.set_value(Unit()); } @@ -75,6 +116,10 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id return promise.set_error(Status::Error(400, "Notification identifier is invalid")); } + if (is_disabled()) { + return promise.set_value(Unit()); + } + // TODO update total_count promise.set_value(Unit()); } diff --git a/td/telegram/NotificationManager.h b/td/telegram/NotificationManager.h index fe6f5f95..5eb02656 100644 --- a/td/telegram/NotificationManager.h +++ b/td/telegram/NotificationManager.h @@ -43,12 +43,40 @@ class NotificationManager : public Actor { Promise &&promise); private: + struct Notification { + NotificationId notification_id; + unique_ptr type; + }; + + struct PendingNotification { + DialogId settings_dialog_id; + bool silent = false; + NotificationId notification_id; + unique_ptr type; + }; + + struct NotificationGroup { + DialogId dialog_id; + int32 total_count = 0; + + vector notifications; + vector pending_notifications; + }; + + bool is_disabled() const; + void start_up() override; void tear_down() override; NotificationId current_notification_id_; NotificationGroupId current_notification_group_id_; + static constexpr int32 DEFAULT_NOTIFICATION_GROUP_COUNT_MAX = 10; + static constexpr int32 DEFAULT_NOTIFICATION_GROUP_SIZE_MAX = 10; + + int32 max_notification_group_count_; + int32 max_notification_group_size_; + Td *td_; ActorShared<> parent_; };