summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h')
-rw-r--r--protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h805
1 files changed, 336 insertions, 469 deletions
diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h b/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h
index e67e50cdb7..77730ac86b 100644
--- a/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h
+++ b/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2022
+// 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)
@@ -8,11 +8,13 @@
#include "td/telegram/AccessRights.h"
#include "td/telegram/AffectedHistory.h"
+#include "td/telegram/BackgroundInfo.h"
#include "td/telegram/ChannelId.h"
#include "td/telegram/ChatReactions.h"
#include "td/telegram/DialogAction.h"
#include "td/telegram/DialogDate.h"
#include "td/telegram/DialogDb.h"
+#include "td/telegram/DialogFilterDialogInfo.h"
#include "td/telegram/DialogFilterId.h"
#include "td/telegram/DialogId.h"
#include "td/telegram/DialogListId.h"
@@ -25,7 +27,6 @@
#include "td/telegram/files/FileSourceId.h"
#include "td/telegram/FolderId.h"
#include "td/telegram/FullMessageId.h"
-#include "td/telegram/Global.h"
#include "td/telegram/InputDialogId.h"
#include "td/telegram/InputGroupCallId.h"
#include "td/telegram/logevent/LogEventHelper.h"
@@ -37,8 +38,11 @@
#include "td/telegram/MessageReplyHeader.h"
#include "td/telegram/MessageReplyInfo.h"
#include "td/telegram/MessageSearchFilter.h"
+#include "td/telegram/MessagesInfo.h"
+#include "td/telegram/MessageSource.h"
#include "td/telegram/MessageThreadInfo.h"
#include "td/telegram/MessageTtl.h"
+#include "td/telegram/MessageViewer.h"
#include "td/telegram/net/DcId.h"
#include "td/telegram/net/NetQuery.h"
#include "td/telegram/Notification.h"
@@ -47,6 +51,7 @@
#include "td/telegram/NotificationGroupType.h"
#include "td/telegram/NotificationId.h"
#include "td/telegram/NotificationSettingsScope.h"
+#include "td/telegram/OrderedMessage.h"
#include "td/telegram/Photo.h"
#include "td/telegram/RecentDialogList.h"
#include "td/telegram/ReplyMarkup.h"
@@ -66,7 +71,6 @@
#include "td/actor/MultiPromise.h"
#include "td/actor/MultiTimeout.h"
#include "td/actor/SignalSlot.h"
-#include "td/actor/Timeout.h"
#include "td/utils/buffer.h"
#include "td/utils/ChangesProcessor.h"
@@ -76,7 +80,7 @@
#include "td/utils/HashTableUtils.h"
#include "td/utils/Heap.h"
#include "td/utils/Hints.h"
-#include "td/utils/logging.h"
+#include "td/utils/List.h"
#include "td/utils/Promise.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
@@ -88,6 +92,7 @@
#include <functional>
#include <map>
#include <memory>
+#include <queue>
#include <set>
#include <unordered_map>
#include <unordered_set>
@@ -159,18 +164,6 @@ class MessagesManager final : public Actor {
MessagesManager &operator=(MessagesManager &&) = delete;
~MessagesManager() final;
- static vector<MessageId> get_message_ids(const vector<int64> &input_message_ids);
-
- static vector<int32> get_server_message_ids(const vector<MessageId> &message_ids);
-
- static vector<int32> get_scheduled_server_message_ids(const vector<MessageId> &message_ids);
-
- static MessageId get_message_id(const tl_object_ptr<telegram_api::Message> &message_ptr, bool is_scheduled);
-
- static DialogId get_message_dialog_id(const tl_object_ptr<telegram_api::Message> &message_ptr);
-
- static FullMessageId get_full_message_id(const tl_object_ptr<telegram_api::Message> &message_ptr, bool is_scheduled);
-
tl_object_ptr<telegram_api::InputPeer> get_input_peer(DialogId dialog_id, AccessRights access_rights) const;
static tl_object_ptr<telegram_api::InputPeer> get_input_peer_force(DialogId dialog_id);
@@ -189,14 +182,10 @@ class MessagesManager final : public Actor {
bool have_input_peer(DialogId dialog_id, AccessRights access_rights) const;
- void on_get_empty_messages(DialogId dialog_id, const vector<MessageId> &empty_message_ids);
+ vector<DialogId> get_peers_dialog_ids(vector<tl_object_ptr<telegram_api::Peer>> &&peers,
+ bool expect_no_access = false);
- struct MessagesInfo {
- vector<tl_object_ptr<telegram_api::Message>> messages;
- int32 total_count = 0;
- bool is_channel_messages = false;
- };
- MessagesInfo get_messages_info(tl_object_ptr<telegram_api::messages_Messages> &&messages_ptr, const char *source);
+ void on_get_empty_messages(DialogId dialog_id, const vector<MessageId> &empty_message_ids);
void get_channel_difference_if_needed(DialogId dialog_id, MessagesInfo &&messages_info,
Promise<MessagesInfo> &&promise);
@@ -235,7 +224,8 @@ class MessagesManager final : public Actor {
void on_get_messages_search_result(const string &query, int32 offset_date, DialogId offset_dialog_id,
MessageId offset_message_id, int32 limit, MessageSearchFilter filter,
int32 min_date, int32 max_date, int64 random_id, int32 total_count,
- vector<tl_object_ptr<telegram_api::Message>> &&messages, Promise<Unit> &&promise);
+ vector<tl_object_ptr<telegram_api::Message>> &&messages, int32 next_rate,
+ Promise<Unit> &&promise);
void on_failed_messages_search(int64 random_id);
void on_get_outgoing_document_messages(vector<tl_object_ptr<telegram_api::Message>> &&messages,
@@ -249,12 +239,11 @@ class MessagesManager final : public Actor {
Promise<td_api::object_ptr<td_api::messages>> &&promise);
void on_get_message_public_forwards(int32 total_count, vector<tl_object_ptr<telegram_api::Message>> &&messages,
- Promise<td_api::object_ptr<td_api::foundMessages>> &&promise);
+ int32 next_rate, Promise<td_api::object_ptr<td_api::foundMessages>> &&promise);
// if message is from_update, flags have_previous and have_next are ignored and must be both true
FullMessageId on_get_message(tl_object_ptr<telegram_api::Message> message_ptr, bool from_update,
- bool is_channel_message, bool is_scheduled, bool have_previous, bool have_next,
- const char *source);
+ bool is_channel_message, bool is_scheduled, const char *source);
void open_secret_message(SecretChatId secret_chat_id, int64 random_id, Promise<Unit>);
@@ -304,10 +293,16 @@ class MessagesManager final : public Actor {
void on_update_dialog_is_marked_as_unread(DialogId dialog_id, bool is_marked_as_unread);
+ void on_update_dialog_is_translatable(DialogId dialog_id, bool is_translatable);
+
+ void update_is_translatable(bool new_is_premium);
+
void on_update_dialog_is_blocked(DialogId dialog_id, bool is_blocked);
void on_update_dialog_last_pinned_message_id(DialogId dialog_id, MessageId last_pinned_message_id);
+ void on_update_dialog_background(DialogId dialog_id, telegram_api::object_ptr<telegram_api::WallPaper> &&wallpaper);
+
void on_update_dialog_theme_name(DialogId dialog_id, string theme_name);
void on_update_dialog_pending_join_requests(DialogId dialog_id, int32 pending_join_request_count,
@@ -330,8 +325,6 @@ class MessagesManager final : public Actor {
void on_update_dialog_message_ttl(DialogId dialog_id, MessageTtl message_ttl);
- void on_update_dialog_filters();
-
void on_update_service_notification(tl_object_ptr<telegram_api::updateServiceNotification> &&update,
bool skip_new_entities, Promise<Unit> &&promise);
@@ -343,7 +336,8 @@ class MessagesManager final : public Actor {
tl_object_ptr<telegram_api::updateChannelReadMessagesContents> &&update);
void on_update_read_message_comments(DialogId dialog_id, MessageId message_id, MessageId max_message_id,
- MessageId last_read_inbox_message_id, MessageId last_read_outbox_message_id);
+ MessageId last_read_inbox_message_id, MessageId last_read_outbox_message_id,
+ int32 unread_count);
void on_update_channel_too_long(tl_object_ptr<telegram_api::updateChannelTooLong> &&update, bool force_apply);
@@ -443,8 +437,13 @@ class MessagesManager final : public Actor {
bool get_dialog_silent_send_message(DialogId dialog_id) const;
+ bool get_dialog_has_last_message(DialogId dialog_id) const;
+
DialogId get_dialog_default_send_message_as_dialog_id(DialogId dialog_id) const;
+ MessageId get_reply_to_message_id(DialogId dialog_id, MessageId top_thread_message_id, MessageId message_id,
+ bool for_draft);
+
Result<td_api::object_ptr<td_api::message>> send_message(
DialogId dialog_id, MessageId top_thread_message_id, MessageId reply_to_message_id,
tl_object_ptr<td_api::messageSendOptions> &&options, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup,
@@ -478,6 +477,9 @@ class MessagesManager final : public Actor {
Status send_screenshot_taken_notification_message(DialogId dialog_id);
+ void share_dialog_with_bot(FullMessageId full_message_id, int32 button_id, DialogId shared_dialog_id,
+ bool expect_user, bool only_check, Promise<Unit> &&promise);
+
Result<MessageId> add_local_message(DialogId dialog_id, td_api::object_ptr<td_api::MessageSender> &&sender,
MessageId reply_to_message_id, bool disable_notification,
tl_object_ptr<td_api::InputMessageContent> &&input_message_content)
@@ -538,6 +540,14 @@ class MessagesManager final : public Actor {
void after_set_typing_query(DialogId dialog_id, int32 generation);
+ void add_dialog_list_for_dialog_filter(DialogFilterId dialog_filter_id);
+
+ void edit_dialog_list_for_dialog_filter(unique_ptr<DialogFilter> &old_dialog_filter,
+ unique_ptr<DialogFilter> new_dialog_filter, bool &disable_get_dialog_filter,
+ const char *source);
+
+ void delete_dialog_list_for_dialog_filter(DialogFilterId dialog_filter_id, const char *source);
+
vector<DialogListId> get_dialog_lists_to_add_dialog(DialogId dialog_id);
void add_dialog_to_list(DialogId dialog_id, DialogListId dialog_list_id, Promise<Unit> &&promise);
@@ -585,10 +595,6 @@ class MessagesManager final : public Actor {
void load_dialogs(vector<DialogId> dialog_ids, Promise<vector<DialogId>> &&promise);
- void load_dialog_filter(DialogFilterId dialog_filter_id, bool force, Promise<Unit> &&promise);
-
- void get_recommended_dialog_filters(Promise<td_api::object_ptr<td_api::recommendedChatFilters>> &&promise);
-
Result<DialogDate> get_dialog_list_last_date(DialogListId dialog_list_id);
vector<DialogId> get_dialogs(DialogListId dialog_list_id, DialogDate offset, int32 limit, bool exact_limit,
@@ -597,6 +603,8 @@ class MessagesManager final : public Actor {
void get_dialogs_from_list(DialogListId dialog_list_id, int32 limit,
Promise<td_api::object_ptr<td_api::chats>> &&promise);
+ void read_all_dialogs_from_list(DialogListId dialog_list_id, Promise<Unit> &&promise, bool is_recursive = false);
+
vector<DialogId> search_public_dialogs(const string &query, Promise<Unit> &&promise);
std::pair<int32, vector<DialogId>> search_dialogs(const string &query, int32 limit, Promise<Unit> &&promise);
@@ -611,6 +619,8 @@ class MessagesManager final : public Actor {
void block_message_sender_from_replies(MessageId message_id, bool need_delete_message, bool need_delete_all_messages,
bool report_spam, Promise<Unit> &&promise);
+ bool is_dialog_blocked(DialogId dialog_id) const;
+
void get_blocked_dialogs(int32 offset, int32 limit, Promise<td_api::object_ptr<td_api::messageSenders>> &&promise);
void on_get_blocked_dialogs(int32 offset, int32 limit, int32 total_count,
@@ -648,10 +658,11 @@ class MessagesManager final : public Actor {
DialogId dialog_id, MessageId message_id, DialogId expected_dialog_id,
MessageId expected_message_id, Promise<MessageThreadInfo> promise);
- void get_message_viewers(FullMessageId full_message_id, Promise<td_api::object_ptr<td_api::users>> &&promise);
+ void get_message_viewers(FullMessageId full_message_id,
+ Promise<td_api::object_ptr<td_api::messageViewers>> &&promise);
- void translate_text(const string &text, const string &from_language_code, const string &to_language_code,
- Promise<td_api::object_ptr<td_api::text>> &&promise);
+ void translate_message_text(FullMessageId full_message_id, const string &to_language_code,
+ Promise<td_api::object_ptr<td_api::formattedText>> &&promise);
void recognize_speech(FullMessageId full_message_id, Promise<Unit> &&promise);
@@ -672,16 +683,11 @@ class MessagesManager final : public Actor {
td_api::object_ptr<td_api::messageLinkInfo> get_message_link_info_object(const MessageLinkInfo &info) const;
- void create_dialog_filter(td_api::object_ptr<td_api::chatFilter> filter,
- Promise<td_api::object_ptr<td_api::chatFilterInfo>> &&promise);
-
- void edit_dialog_filter(DialogFilterId dialog_filter_id, td_api::object_ptr<td_api::chatFilter> filter,
- Promise<td_api::object_ptr<td_api::chatFilterInfo>> &&promise);
+ InputDialogId get_input_dialog_id(DialogId dialog_id) const;
- void delete_dialog_filter(DialogFilterId dialog_filter_id, Promise<Unit> &&promise);
+ bool is_dialog_in_dialog_list(DialogId dialog_id) const;
- void reorder_dialog_filters(vector<DialogFilterId> dialog_filter_ids, int32 main_dialog_list_position,
- Promise<Unit> &&promise);
+ Status can_add_dialog_to_filter(DialogId dialog_id);
Status delete_dialog_reply_markup(DialogId dialog_id, MessageId message_id) TD_WARN_UNUSED_RESULT;
@@ -694,6 +700,8 @@ class MessagesManager final : public Actor {
Status toggle_dialog_is_marked_as_unread(DialogId dialog_id, bool is_marked_as_unread) TD_WARN_UNUSED_RESULT;
+ Status toggle_dialog_is_translatable(DialogId dialog_id, bool is_translatable) TD_WARN_UNUSED_RESULT;
+
Status toggle_message_sender_is_blocked(const td_api::object_ptr<td_api::MessageSender> &sender,
bool is_blocked) TD_WARN_UNUSED_RESULT;
@@ -705,12 +713,12 @@ class MessagesManager final : public Actor {
void create_dialog(DialogId dialog_id, bool force, Promise<Unit> &&promise);
- DialogId create_new_group_chat(const vector<UserId> &user_ids, const string &title, int64 &random_id,
- Promise<Unit> &&promise);
+ DialogId create_new_group_chat(const vector<UserId> &user_ids, const string &title, MessageTtl message_ttl,
+ int64 &random_id, Promise<Unit> &&promise);
- DialogId create_new_channel_chat(const string &title, bool is_megagroup, const string &description,
- const DialogLocation &location, bool for_import, int64 &random_id,
- Promise<Unit> &&promise);
+ DialogId create_new_channel_chat(const string &title, bool is_forum, bool is_megagroup, const string &description,
+ const DialogLocation &location, bool for_import, MessageTtl message_ttl,
+ int64 &random_id, Promise<Unit> &&promise);
void create_new_secret_chat(UserId user_id, Promise<SecretChatId> &&promise);
@@ -722,7 +730,7 @@ class MessagesManager final : public Actor {
Status close_dialog(DialogId dialog_id) TD_WARN_UNUSED_RESULT;
- Status view_messages(DialogId dialog_id, MessageId top_thread_message_id, const vector<MessageId> &message_ids,
+ Status view_messages(DialogId dialog_id, vector<MessageId> message_ids, MessageSource source,
bool force_read) TD_WARN_UNUSED_RESULT;
void finish_get_message_views(DialogId dialog_id, const vector<MessageId> &message_ids);
@@ -743,13 +751,17 @@ class MessagesManager final : public Actor {
void reset_all_notification_settings();
- tl_object_ptr<td_api::chat> get_chat_object(DialogId dialog_id) const;
+ int64 get_chat_id_object(DialogId dialog_id, const char *source) const;
+
+ vector<int64> get_chat_ids_object(const vector<DialogId> &dialog_ids, const char *source) const;
- static tl_object_ptr<td_api::chats> get_chats_object(int32 total_count, const vector<DialogId> &dialog_ids);
+ td_api::object_ptr<td_api::chat> get_chat_object(DialogId dialog_id);
- static tl_object_ptr<td_api::chats> get_chats_object(const std::pair<int32, vector<DialogId>> &dialog_ids);
+ tl_object_ptr<td_api::chats> get_chats_object(int32 total_count, const vector<DialogId> &dialog_ids,
+ const char *source) const;
- tl_object_ptr<td_api::chatFilter> get_chat_filter_object(DialogFilterId dialog_filter_id) const;
+ tl_object_ptr<td_api::chats> get_chats_object(const std::pair<int32, vector<DialogId>> &dialog_ids,
+ const char *source) const;
tl_object_ptr<td_api::messages> get_dialog_history(DialogId dialog_id, MessageId from_message_id, int32 offset,
int32 limit, int left_tries, bool only_local,
@@ -764,12 +776,20 @@ class MessagesManager final : public Actor {
MessageSearchFilter filter, int64 &random_id,
bool use_db, Promise<Unit> &&promise);
- std::pair<int32, vector<MessageId>> search_dialog_messages(DialogId dialog_id, const string &query,
- const td_api::object_ptr<td_api::MessageSender> &sender,
- MessageId from_message_id, int32 offset, int32 limit,
- MessageSearchFilter filter,
- MessageId top_thread_message_id, int64 &random_id,
- bool use_db, Promise<Unit> &&promise);
+ struct FoundDialogMessages {
+ vector<MessageId> message_ids;
+ MessageId next_from_message_id;
+ int32 total_count = 0;
+ };
+
+ td_api::object_ptr<td_api::foundChatMessages> get_found_chat_messages_object(
+ DialogId dialog_id, const FoundDialogMessages &found_dialog_messages, const char *source);
+
+ FoundDialogMessages search_dialog_messages(DialogId dialog_id, const string &query,
+ const td_api::object_ptr<td_api::MessageSender> &sender,
+ MessageId from_message_id, int32 offset, int32 limit,
+ MessageSearchFilter filter, MessageId top_thread_message_id,
+ int64 &random_id, bool use_db, Promise<Unit> &&promise);
struct FoundMessages {
vector<FullMessageId> full_message_ids;
@@ -783,14 +803,12 @@ class MessagesManager final : public Actor {
FoundMessages offline_search_messages(DialogId dialog_id, const string &query, string offset, int32 limit,
MessageSearchFilter filter, int64 &random_id, Promise<Unit> &&promise);
- std::pair<int32, vector<FullMessageId>> search_messages(FolderId folder_id, bool ignore_folder_id,
- const string &query, int32 offset_date,
- DialogId offset_dialog_id, MessageId offset_message_id,
- int32 limit, MessageSearchFilter filter, int32 min_date,
- int32 max_date, int64 &random_id, Promise<Unit> &&promise);
+ FoundMessages search_messages(FolderId folder_id, bool ignore_folder_id, const string &query, const string &offset,
+ int32 limit, MessageSearchFilter filter, int32 min_date, int32 max_date,
+ int64 &random_id, Promise<Unit> &&promise);
- std::pair<int32, vector<FullMessageId>> search_call_messages(MessageId from_message_id, int32 limit, bool only_missed,
- int64 &random_id, bool use_db, Promise<Unit> &&promise);
+ FoundMessages search_call_messages(const string &offset, int32 limit, bool only_missed, int64 &random_id, bool use_db,
+ Promise<Unit> &&promise);
void search_outgoing_document_messages(const string &query, int32 limit,
Promise<td_api::object_ptr<td_api::foundMessages>> &&promise);
@@ -943,6 +961,8 @@ class MessagesManager final : public Actor {
void on_get_channel_difference(DialogId dialog_id, int32 request_pts, int32 request_limit,
tl_object_ptr<telegram_api::updates_ChannelDifference> &&difference_ptr);
+ void try_update_dialog_pos(DialogId dialog_id);
+
void force_create_dialog(DialogId dialog_id, const char *source, bool expect_no_access = false,
bool force_update_dialog_pos = false);
@@ -1126,15 +1146,14 @@ class MessagesManager final : public Actor {
};
// Do not forget to update MessagesManager::update_message and all make_unique<Message> when this class is changed
- struct Message {
- int32 random_y = 0;
-
+ struct Message final : public ListNode {
MessageId message_id;
UserId sender_user_id;
DialogId sender_dialog_id;
int32 date = 0;
int32 edit_date = 0;
int32 send_date = 0;
+ int32 sending_id = 0;
int64 random_id = 0;
@@ -1180,10 +1199,6 @@ class MessagesManager final : public Actor {
bool hide_via_bot = false; // for resend_message
bool is_bot_start_message = false; // for resend_message
- bool have_previous = false;
- bool have_next = false;
- bool from_database = false;
-
bool has_get_message_views_query = false;
bool need_view_counter_increment = false;
@@ -1235,9 +1250,6 @@ class MessagesManager final : public Actor {
const char *debug_source = "null";
- unique_ptr<Message> left;
- unique_ptr<Message> right;
-
mutable int32 last_access_date = 0;
mutable bool is_update_sent = false; // whether the message is known to the app
@@ -1250,6 +1262,13 @@ class MessagesManager final : public Actor {
template <class ParserT>
void parse(ParserT &parser);
+
+ Message() = default;
+ Message(const Message &) = delete;
+ Message &operator=(const Message &) = delete;
+ Message(Message &&) = delete;
+ Message &operator=(Message &&) = delete;
+ ~Message() = default;
};
struct NotificationGroupInfo {
@@ -1268,6 +1287,29 @@ class MessagesManager final : public Actor {
void parse(ParserT &parser);
};
+ struct DialogScheduledMessages {
+ FlatHashMap<ScheduledServerMessageId, int32, ScheduledServerMessageIdHash> scheduled_message_date_;
+
+ FlatHashMap<int32, MessageId> last_assigned_scheduled_message_id_; // date -> message_id
+
+ FlatHashSet<ScheduledServerMessageId, ScheduledServerMessageIdHash> deleted_scheduled_server_message_ids_;
+
+ FlatHashMap<MessageId, unique_ptr<Message>, MessageIdHash> scheduled_messages_;
+ };
+
+ struct NotificationInfo {
+ NotificationGroupInfo message_notification_group_;
+ NotificationGroupInfo mention_notification_group_;
+ NotificationId new_secret_chat_notification_id_; // secret chats only
+ MessageId pinned_message_notification_message_id_;
+ MessageId max_notification_message_id_;
+
+ vector<std::pair<DialogId, MessageId>> pending_new_message_notifications_;
+ vector<std::pair<DialogId, MessageId>> pending_new_mention_notifications_;
+
+ FlatHashMap<NotificationId, MessageId, NotificationIdHash> notification_id_to_message_id_;
+ };
+
struct Dialog {
DialogId dialog_id;
MessageId last_new_message_id; // identifier of the last known server message received from update, there should be
@@ -1301,13 +1343,12 @@ class MessagesManager final : public Actor {
unique_ptr<DialogActionBar> action_bar;
LogEventIdWithGeneration save_draft_message_log_event_id;
LogEventIdWithGeneration save_notification_settings_log_event_id;
- std::unordered_map<int64, LogEventIdWithGeneration, Hash<int64>> read_history_log_event_ids;
- std::unordered_set<MessageId, MessageIdHash> updated_read_history_message_ids;
LogEventIdWithGeneration set_folder_id_log_event_id;
InputGroupCallId active_group_call_id;
InputGroupCallId expected_active_group_call_id;
DialogId default_join_group_call_as_dialog_id;
DialogId default_send_message_as_dialog_id;
+ BackgroundInfo background_info;
string theme_name;
int32 pending_join_request_count = 0;
vector<UserId> pending_join_request_user_ids;
@@ -1315,6 +1356,9 @@ class MessagesManager final : public Actor {
int32 unload_dialog_delay_seed = 0;
int64 last_media_album_id = 0;
uint32 history_generation = 0;
+ uint32 open_count = 0;
+
+ unique_ptr<NotificationInfo> notification_info;
FolderId folder_id;
vector<DialogListId> dialog_list_ids; // TODO replace with mask
@@ -1331,7 +1375,6 @@ class MessagesManager final : public Actor {
int32 delete_last_message_date = 0;
int32 pending_last_message_date = 0;
MessageId pending_last_message_id;
- MessageId max_notification_message_id;
MessageId last_edited_message_id;
uint32 scheduled_messages_sync_generation = 0;
uint32 last_repair_scheduled_messages_generation = 0;
@@ -1342,11 +1385,6 @@ class MessagesManager final : public Actor {
MessageId being_updated_last_database_message_id;
MessageId being_deleted_message_id;
- NotificationGroupInfo message_notification_group;
- NotificationGroupInfo mention_notification_group;
- NotificationId new_secret_chat_notification_id; // secret chats only
- MessageId pinned_message_notification_message_id;
-
bool has_contact_registered_message = false;
bool is_last_message_deleted_locally = false;
@@ -1355,7 +1393,6 @@ class MessagesManager final : public Actor {
bool know_action_bar = false;
bool has_outgoing_messages = false;
- bool is_opened = false;
bool was_opened = false;
bool need_restore_reply_markup = true;
@@ -1386,20 +1423,19 @@ class MessagesManager final : public Actor {
bool has_expected_active_group_call_id = false;
bool has_bots = false;
bool is_has_bots_inited = false;
+ bool is_background_inited = false;
bool is_theme_name_inited = false;
bool is_available_reactions_inited = false;
bool had_yet_unsent_message_id_overflow = false;
-
- bool increment_view_counter = false;
+ bool need_repair_unread_reaction_count = false;
+ bool need_repair_unread_mention_count = false;
+ bool is_translatable = false;
bool is_update_new_chat_sent = false;
bool is_update_new_chat_being_sent = false;
bool has_unload_timeout = false;
bool is_channel_difference_finished = false;
- bool suffix_load_done_ = false;
- bool suffix_load_has_query_ = false;
-
int32 pts = 0; // for channels only
int32 pending_read_channel_inbox_pts = 0; // for channels only
int32 pending_read_channel_inbox_server_unread_count = 0; // for channels only
@@ -1411,67 +1447,19 @@ class MessagesManager final : public Actor {
// application start, used to guarantee that all assigned message identifiers
// are different
- FlatHashMap<MessageId, std::set<MessageId>, MessageIdHash>
- yet_unsent_thread_message_ids; // top_thread_message_id -> yet unsent message IDs
-
- FlatHashMap<ScheduledServerMessageId, int32, ScheduledServerMessageIdHash> scheduled_message_date;
-
- FlatHashMap<MessageId, MessageId, MessageIdHash> yet_unsent_message_id_to_persistent_message_id;
-
- FlatHashMap<int32, MessageId> last_assigned_scheduled_message_id; // date -> message_id
-
WaitFreeHashSet<MessageId, MessageIdHash> deleted_message_ids;
- FlatHashSet<ScheduledServerMessageId, ScheduledServerMessageIdHash> deleted_scheduled_server_message_ids;
- vector<std::pair<DialogId, MessageId>> pending_new_message_notifications;
- vector<std::pair<DialogId, MessageId>> pending_new_mention_notifications;
+ string client_data;
- FlatHashMap<NotificationId, MessageId, NotificationIdHash> notification_id_to_message_id;
+ WaitFreeHashMap<MessageId, unique_ptr<Message>, MessageIdHash> messages;
- string client_data;
+ mutable ListNode message_lru_list;
- // Load from newest to oldest message
- MessageId suffix_load_first_message_id_; // identifier of some message such all suffix messages in range
- // [suffix_load_first_message_id_, last_message_id] are loaded
- MessageId suffix_load_query_message_id_;
- std::vector<std::pair<Promise<Unit>, std::function<bool(const Message *)>>> suffix_load_queries_;
-
- FlatHashMap<MessageId, int64, MessageIdHash> pending_viewed_live_locations; // message_id -> task_id
- FlatHashSet<MessageId, MessageIdHash> pending_viewed_message_ids;
-
- unique_ptr<Message> messages;
- unique_ptr<Message> scheduled_messages;
-
- struct MessageOp {
- enum : int8 { Add, SetPts, Delete, DeleteAll } type;
- bool from_update = false;
- bool have_previous = false;
- bool have_next = false;
- MessageContentType content_type = MessageContentType::None;
- int32 pts = 0;
- MessageId message_id;
- const char *source = nullptr;
- double date = 0;
-
- MessageOp(decltype(type) type, MessageId message_id, MessageContentType content_type, bool from_update,
- bool have_previous, bool have_next, const char *source)
- : type(type)
- , from_update(from_update)
- , have_previous(have_previous)
- , have_next(have_next)
- , content_type(content_type)
- , message_id(message_id)
- , source(source)
- , date(G()->server_time()) {
- }
+ OrderedMessages ordered_messages;
- MessageOp(decltype(type) type, int32 pts, const char *source)
- : type(type), pts(pts), source(source), date(G()->server_time()) {
- }
- };
+ unique_ptr<DialogScheduledMessages> scheduled_messages;
const char *debug_set_dialog_last_database_message_id = "Unknown"; // to be removed soon
- vector<MessageOp> debug_message_op;
// message identifiers loaded from database
MessageId debug_last_new_message_id;
@@ -1481,8 +1469,8 @@ class MessagesManager final : public Actor {
Dialog() = default;
Dialog(const Dialog &) = delete;
Dialog &operator=(const Dialog &) = delete;
- Dialog(Dialog &&other) = delete;
- Dialog &operator=(Dialog &&other) = delete;
+ Dialog(Dialog &&) = delete;
+ Dialog &operator=(Dialog &&) = delete;
~Dialog() = default;
template <class StorerT>
@@ -1492,11 +1480,6 @@ class MessagesManager final : public Actor {
void parse(ParserT &parser);
};
- struct RecommendedDialogFilter {
- unique_ptr<DialogFilter> dialog_filter;
- string description;
- };
-
struct DialogList {
DialogListId dialog_list_id;
bool is_message_unread_count_inited_ = false;
@@ -1603,133 +1586,6 @@ class MessagesManager final : public Actor {
}
};
- class MessagesIteratorBase {
- vector<const Message *> stack_;
-
- protected:
- MessagesIteratorBase() = default;
-
- // points iterator to message with greatest id which is less or equal than message_id
- MessagesIteratorBase(const Message *root, MessageId message_id) {
- size_t last_right_pos = 0;
- while (root != nullptr) {
- // LOG(DEBUG) << "Have root->message_id = " << root->message_id;
- stack_.push_back(root);
- if (root->message_id <= message_id) {
- // LOG(DEBUG) << "Go right";
- last_right_pos = stack_.size();
- root = root->right.get();
- } else {
- // LOG(DEBUG) << "Go left";
- root = root->left.get();
- }
- }
- stack_.resize(last_right_pos);
- }
-
- const Message *operator*() const {
- return stack_.empty() ? nullptr : stack_.back();
- }
-
- ~MessagesIteratorBase() = default;
-
- public:
- MessagesIteratorBase(const MessagesIteratorBase &) = delete;
- MessagesIteratorBase &operator=(const MessagesIteratorBase &) = delete;
- MessagesIteratorBase(MessagesIteratorBase &&other) = default;
- MessagesIteratorBase &operator=(MessagesIteratorBase &&other) = default;
-
- void operator++() {
- if (stack_.empty()) {
- return;
- }
-
- const Message *cur = stack_.back();
- if (!cur->have_next) {
- stack_.clear();
- return;
- }
- if (cur->right == nullptr) {
- while (true) {
- stack_.pop_back();
- if (stack_.empty()) {
- return;
- }
- const Message *new_cur = stack_.back();
- if (new_cur->left.get() == cur) {
- return;
- }
- cur = new_cur;
- }
- }
-
- cur = cur->right.get();
- while (cur != nullptr) {
- stack_.push_back(cur);
- cur = cur->left.get();
- }
- }
-
- void operator--() {
- if (stack_.empty()) {
- return;
- }
-
- const Message *cur = stack_.back();
- if (!cur->have_previous) {
- stack_.clear();
- return;
- }
- if (cur->left == nullptr) {
- while (true) {
- stack_.pop_back();
- if (stack_.empty()) {
- return;
- }
- const Message *new_cur = stack_.back();
- if (new_cur->right.get() == cur) {
- return;
- }
- cur = new_cur;
- }
- }
-
- cur = cur->left.get();
- while (cur != nullptr) {
- stack_.push_back(cur);
- cur = cur->right.get();
- }
- }
- };
-
- class MessagesIterator final : public MessagesIteratorBase {
- public:
- MessagesIterator() = default;
-
- MessagesIterator(Dialog *d, MessageId message_id)
- : MessagesIteratorBase(message_id.is_scheduled() ? d->scheduled_messages.get() : d->messages.get(),
- message_id) {
- }
-
- Message *operator*() const {
- return const_cast<Message *>(MessagesIteratorBase::operator*());
- }
- };
-
- class MessagesConstIterator final : public MessagesIteratorBase {
- public:
- MessagesConstIterator() = default;
-
- MessagesConstIterator(const Dialog *d, MessageId message_id)
- : MessagesIteratorBase(message_id.is_scheduled() ? d->scheduled_messages.get() : d->messages.get(),
- message_id) {
- }
-
- const Message *operator*() const {
- return MessagesIteratorBase::operator*();
- }
- };
-
struct PendingSecretMessage {
enum class Type : int32 { NewMessage, DeleteMessages, DeleteHistory };
Type type = Type::NewMessage;
@@ -1753,18 +1609,30 @@ class MessagesManager final : public Actor {
bool update_stickersets_order = false;
bool protect_content = false;
int32 schedule_date = 0;
+ int32 sending_id = 0;
MessageSendOptions() = default;
MessageSendOptions(bool disable_notification, bool from_background, bool update_stickersets_order,
- bool protect_content, int32 schedule_date)
+ bool protect_content, int32 schedule_date, int32 sending_id)
: disable_notification(disable_notification)
, from_background(from_background)
, update_stickersets_order(update_stickersets_order)
, protect_content(protect_content)
- , schedule_date(schedule_date) {
+ , schedule_date(schedule_date)
+ , sending_id(sending_id) {
}
};
+ struct SuffixLoadQueries {
+ bool suffix_load_done_ = false;
+ bool suffix_load_has_query_ = false;
+
+ MessageId suffix_load_first_message_id_; // identifier of some message such all suffix messages in range
+ // [suffix_load_first_message_id_, last_message_id] are loaded
+ MessageId suffix_load_query_message_id_;
+ vector<std::pair<Promise<Unit>, std::function<bool(const Message *)>>> suffix_load_queries_;
+ };
+
class BlockMessageSenderFromRepliesOnServerLogEvent;
class DeleteAllCallMessagesOnServerLogEvent;
class DeleteAllChannelMessagesFromSenderOnServerLogEvent;
@@ -1793,13 +1661,12 @@ class MessagesManager final : public Actor {
class SetDialogFolderIdOnServerLogEvent;
class ToggleDialogIsBlockedOnServerLogEvent;
class ToggleDialogIsMarkedAsUnreadOnServerLogEvent;
+ class ToggleDialogIsTranslatableOnServerLogEvent;
class ToggleDialogIsPinnedOnServerLogEvent;
class ToggleDialogReportSpamStateOnServerLogEvent;
class UnpinAllDialogMessagesOnServerLogEvent;
class UpdateDialogNotificationSettingsOnServerLogEvent;
- class DialogFiltersLogEvent;
-
static constexpr size_t MAX_GROUPED_MESSAGES = 10; // server side limit
static constexpr int32 MAX_GET_DIALOGS = 100; // server side limit
static constexpr int32 MAX_GET_HISTORY = 100; // server side limit
@@ -1807,13 +1674,11 @@ class MessagesManager final : public Actor {
static constexpr int32 MIN_SEARCH_PUBLIC_DIALOG_PREFIX_LEN = 4; // server side limit
static constexpr int32 MIN_CHANNEL_DIFFERENCE = 1;
static constexpr int32 MAX_CHANNEL_DIFFERENCE = 100;
- static constexpr int32 MAX_BOT_CHANNEL_DIFFERENCE = 100000; // server side limit
- static constexpr int32 MAX_RECENT_DIALOGS = 50; // some reasonable value
- static constexpr size_t MAX_TITLE_LENGTH = 128; // server side limit for chat title
- static constexpr size_t MAX_DESCRIPTION_LENGTH = 255; // server side limit for chat description
- static constexpr size_t MAX_DIALOG_FILTER_TITLE_LENGTH = 12; // server side limit for dialog filter title
- static constexpr int32 MAX_PRIVATE_MESSAGE_TTL = 60; // server side limit
- static constexpr int32 DIALOG_FILTERS_CACHE_TIME = 86400;
+ static constexpr int32 MAX_BOT_CHANNEL_DIFFERENCE = 100000; // server side limit
+ static constexpr int32 MAX_RECENT_DIALOGS = 50; // some reasonable value
+ static constexpr size_t MAX_TITLE_LENGTH = 128; // server side limit for chat title
+ static constexpr size_t MAX_DESCRIPTION_LENGTH = 255; // server side limit for chat description
+ static constexpr int32 MAX_PRIVATE_MESSAGE_TTL = 60; // server side limit
static constexpr size_t MIN_DELETED_ASYNCHRONOUSLY_MESSAGES = 10;
static constexpr size_t MAX_UNLOADED_MESSAGES = 5000;
@@ -1822,8 +1687,6 @@ class MessagesManager final : public Actor {
static constexpr int64 MAX_ORDINARY_DIALOG_ORDER =
9221294780217032704; // == get_dialog_order(MessageId(), MIN_PINNED_DIALOG_DATE - 1)
- static constexpr int32 UPDATE_CHANNEL_TO_LONG_FLAG_HAS_PTS = 1 << 0;
-
static constexpr int32 CHANNEL_DIFFERENCE_FLAG_IS_FINAL = 1 << 0;
static constexpr int32 CHANNEL_DIFFERENCE_FLAG_HAS_TIMEOUT = 1 << 1;
@@ -1837,6 +1700,8 @@ class MessagesManager final : public Actor {
static constexpr int32 MIN_READ_HISTORY_DELAY = 3; // seconds
static constexpr int32 MAX_SAVE_DIALOG_DELAY = 0; // seconds
+ static constexpr int32 DEFAULT_LOADED_EXPIRED_MESSAGES = 50;
+
static constexpr int32 LIVE_LOCATION_VIEW_PERIOD = 60; // seconds, server-side limit
static constexpr int32 UPDATE_VIEWED_MESSAGES_PERIOD = 15; // seconds
@@ -1858,6 +1723,10 @@ class MessagesManager final : public Actor {
static int32 get_message_date(const tl_object_ptr<telegram_api::Message> &message_ptr);
+ static vector<UserId> get_message_user_ids(const Message *m);
+
+ static vector<ChannelId> get_message_channel_ids(const Message *m);
+
static bool is_dialog_inited(const Dialog *d);
int32 get_dialog_mute_until(const Dialog *d) const;
@@ -1905,8 +1774,8 @@ class MessagesManager final : public Actor {
void get_dialog_message_count_from_server(DialogId dialog_id, MessageSearchFilter filter, Promise<int32> &&promise);
- FullMessageId on_get_message(MessageInfo &&message_info, bool from_update, bool is_channel_message,
- bool have_previous, bool have_next, const char *source);
+ FullMessageId on_get_message(MessageInfo &&message_info, const bool from_update, const bool is_channel_message,
+ const char *source);
Result<InputMessageContent> process_input_message_content(
DialogId dialog_id, tl_object_ptr<td_api::InputMessageContent> &&input_message_content);
@@ -1920,6 +1789,7 @@ class MessagesManager final : public Actor {
static Status can_use_message_send_options(const MessageSendOptions &options,
const unique_ptr<MessageContent> &content, int32 ttl);
+
static Status can_use_message_send_options(const MessageSendOptions &options, const InputMessageContent &content);
Status can_use_top_thread_message_id(Dialog *d, MessageId top_thread_message_id, MessageId reply_to_message_id);
@@ -1967,7 +1837,7 @@ class MessagesManager final : public Actor {
bool was_uploaded, bool was_thumbnail_uploaded, string file_reference,
int32 schedule_date, uint64 generation, Result<int32> &&result);
- static MessageId get_persistent_message_id(const Dialog *d, MessageId message_id);
+ MessageId get_persistent_message_id(const Dialog *d, MessageId message_id) const;
static FullMessageId get_replied_message_id(DialogId dialog_id, const Message *m);
@@ -2009,7 +1879,7 @@ class MessagesManager final : public Actor {
Result<td_api::object_ptr<td_api::message>> forward_message(DialogId to_dialog_id, MessageId top_thread_message_id,
DialogId from_dialog_id, MessageId message_id,
- tl_object_ptr<td_api::messageSendOptions> &&options,
+ td_api::object_ptr<td_api::messageSendOptions> &&options,
bool in_game_share,
MessageCopyOptions &&copy_options) TD_WARN_UNUSED_RESULT;
@@ -2049,7 +1919,7 @@ class MessagesManager final : public Actor {
Result<ForwardedMessages> get_forwarded_messages(DialogId to_dialog_id, MessageId top_thread_message_id,
DialogId from_dialog_id, const vector<MessageId> &message_ids,
- tl_object_ptr<td_api::messageSendOptions> &&options,
+ td_api::object_ptr<td_api::messageSendOptions> &&options,
bool in_game_share, vector<MessageCopyOptions> &&copy_options);
void do_send_media(DialogId dialog_id, Message *m, FileId file_id, FileId thumbnail_file_id,
@@ -2098,7 +1968,8 @@ class MessagesManager final : public Actor {
void restore_message_reply_to_message_id(Dialog *d, Message *m);
- Message *continue_send_message(DialogId dialog_id, unique_ptr<Message> &&m, uint64 log_event_id);
+ Message *continue_send_message(DialogId dialog_id, unique_ptr<Message> &&message, bool *need_update_dialog_pos,
+ uint64 log_event_id);
bool is_message_unload_enabled() const;
@@ -2138,6 +2009,8 @@ class MessagesManager final : public Actor {
unique_ptr<Message> do_delete_scheduled_message(Dialog *d, MessageId message_id, bool is_permanently_deleted,
const char *source);
+ void on_message_deleted_from_database(Dialog *d, const Message *m, const char *source);
+
void on_message_deleted(Dialog *d, Message *m, bool is_permanently_deleted, const char *source);
static bool is_deleted_message(const Dialog *d, MessageId message_id);
@@ -2148,10 +2021,9 @@ class MessagesManager final : public Actor {
void unload_dialog(DialogId dialog_id);
- void delete_all_dialog_messages(Dialog *d, bool remove_from_dialog_list, bool is_permanently_deleted);
+ void clear_dialog_message_list(Dialog *d, bool remove_from_dialog_list, int32 last_message_date);
- void do_delete_all_dialog_messages(Dialog *d, unique_ptr<Message> &message, bool is_permanently_deleted,
- vector<int64> &deleted_message_ids);
+ void delete_all_dialog_messages(Dialog *d, bool remove_from_dialog_list, bool is_permanently_deleted);
void erase_delete_messages_log_event(uint64 log_event_id);
@@ -2195,19 +2067,12 @@ class MessagesManager final : public Actor {
void on_get_affected_history(DialogId dialog_id, AffectedHistoryQuery query, bool get_affected_messages,
AffectedHistory affected_history, Promise<Unit> &&promise);
- static MessageId find_message_by_date(const Message *m, int32 date);
-
- static void find_messages_by_date(const Message *m, int32 min_date, int32 max_date, vector<MessageId> &message_ids);
-
- static void find_messages(const Message *m, vector<MessageId> &message_ids,
- const std::function<bool(const Message *)> &condition);
+ static vector<MessageId> find_dialog_messages(const Dialog *d, const std::function<bool(const Message *)> &condition);
- static void find_old_messages(const Message *m, MessageId max_message_id, vector<MessageId> &message_ids);
+ std::function<int32(MessageId)> get_get_message_date(const Dialog *d) const;
- static void find_newer_messages(const Message *m, MessageId min_message_id, vector<MessageId> &message_ids);
-
- void find_unloadable_messages(const Dialog *d, int32 unload_before_date, const Message *m,
- vector<MessageId> &message_ids, bool &has_left_to_unload_messages) const;
+ vector<MessageId> find_unloadable_messages(const Dialog *d, int32 unload_before_date,
+ bool &has_left_to_unload_messages) const;
void on_pending_message_views_timeout(DialogId dialog_id);
@@ -2230,7 +2095,7 @@ class MessagesManager final : public Actor {
void on_message_reply_info_changed(DialogId dialog_id, const Message *m) const;
- Result<FullMessageId> get_top_thread_full_message_id(DialogId dialog_id, const Message *m) const;
+ Result<FullMessageId> get_top_thread_full_message_id(DialogId dialog_id, const Message *m, bool allow_non_root) const;
td_api::object_ptr<td_api::messageInteractionInfo> get_message_interaction_info_object(DialogId dialog_id,
const Message *m) const;
@@ -2257,6 +2122,14 @@ class MessagesManager final : public Actor {
bool has_incoming_notification(DialogId dialog_id, const Message *m) const;
+ void read_history_outbox(Dialog *d, MessageId max_message_id, int32 read_date = -1);
+
+ void read_history_inbox(Dialog *d, MessageId max_message_id, int32 unread_count, const char *source);
+
+ void read_dialog_inbox(Dialog *d, MessageId max_message_id);
+
+ void mark_dialog_as_read(Dialog *d);
+
int32 calc_new_unread_count_from_last_unread(Dialog *d, MessageId max_message_id, MessageType type) const;
int32 calc_new_unread_count_from_the_end(Dialog *d, MessageId max_message_id, MessageType type,
@@ -2268,6 +2141,10 @@ class MessagesManager final : public Actor {
void repair_channel_server_unread_count(Dialog *d);
+ void repair_dialog_unread_reaction_count(Dialog *d, Promise<Unit> &&promise, const char *source);
+
+ void repair_dialog_unread_mention_count(Dialog *d, const char *source);
+
void read_history_outbox(DialogId dialog_id, MessageId max_message_id, int32 read_date = -1);
void read_history_on_server(Dialog *d, MessageId max_message_id);
@@ -2295,6 +2172,8 @@ class MessagesManager final : public Actor {
void on_update_viewed_messages_timeout(DialogId dialog_id);
+ void on_send_update_chat_read_inbox_timeout(DialogId dialog_id);
+
bool delete_newer_server_messages_at_the_end(Dialog *d, MessageId max_message_id);
template <class T, class It>
@@ -2331,9 +2210,7 @@ class MessagesManager final : public Actor {
void on_get_scheduled_messages_from_database(DialogId dialog_id, vector<MessageDbDialogMessage> &&messages);
- static int32 get_random_y(MessageId message_id);
-
- static void set_message_id(unique_ptr<Message> &message, MessageId message_id);
+ static bool have_dialog_scheduled_messages_in_memory(const Dialog *d);
static bool is_allowed_useless_update(const tl_object_ptr<telegram_api::Update> &update);
@@ -2382,14 +2259,19 @@ class MessagesManager final : public Actor {
void update_message_reply_count(Dialog *d, MessageId message_id, DialogId replier_dialog_id,
MessageId reply_message_id, int32 update_date, int diff, bool is_recursive = false);
- Message *add_message_to_dialog(DialogId dialog_id, unique_ptr<Message> message, bool from_update, bool *need_update,
- bool *need_update_dialog_pos, const char *source);
+ void fix_new_message(const Dialog *d, Message *m, bool from_database) const;
- Message *add_message_to_dialog(Dialog *d, unique_ptr<Message> message, bool from_update, bool *need_update,
- bool *need_update_dialog_pos, const char *source);
+ void remove_message_remove_keyboard_reply_markup(Message *m) const;
- Message *add_scheduled_message_to_dialog(Dialog *d, unique_ptr<Message> message, bool from_update, bool *need_update,
- const char *source);
+ void add_message_to_dialog_message_list(const Message *m, Dialog *d, const bool from_database, const bool from_update,
+ const bool need_update, bool *need_update_dialog_pos, const char *source);
+
+ Message *add_message_to_dialog(Dialog *d, unique_ptr<Message> message, const bool from_database,
+ const bool from_update, bool *need_update, bool *need_update_dialog_pos,
+ const char *source);
+
+ Message *add_scheduled_message_to_dialog(Dialog *d, unique_ptr<Message> message, bool from_database, bool from_update,
+ bool *need_update, const char *source);
void register_new_local_message_id(Dialog *d, const Message *m);
@@ -2405,7 +2287,8 @@ class MessagesManager final : public Actor {
void delete_all_dialog_messages_from_database(Dialog *d, MessageId max_message_id, const char *source);
- void delete_message_from_database(Dialog *d, MessageId message_id, const Message *m, bool is_permanently_deleted);
+ void delete_message_from_database(Dialog *d, MessageId message_id, const Message *m, bool is_permanently_deleted,
+ const char *source);
void update_reply_to_message_id(DialogId dialog_id, MessageId old_message_id, MessageId new_message_id,
bool have_new_message, const char *source);
@@ -2416,11 +2299,11 @@ class MessagesManager final : public Actor {
static void delete_random_id_to_message_id_correspondence(Dialog *d, int64 random_id, MessageId message_id);
- static void add_notification_id_to_message_id_correspondence(Dialog *d, NotificationId notification_id,
- MessageId message_id);
+ static void add_notification_id_to_message_id_correspondence(NotificationInfo *notification_info,
+ NotificationId notification_id, MessageId message_id);
- static void delete_notification_id_to_message_id_correspondence(Dialog *d, NotificationId notification_id,
- MessageId message_id);
+ static void delete_notification_id_to_message_id_correspondence(NotificationInfo *notification_info,
+ NotificationId notification_id, MessageId message_id);
void remove_message_notification_id(Dialog *d, Message *m, bool is_permanent, bool force_update,
bool ignore_pinned_message_notification_removal = false);
@@ -2435,12 +2318,7 @@ class MessagesManager final : public Actor {
void do_delete_message_log_event(const DeleteMessageLogEvent &log_event) const;
- static void attach_message_to_previous(Dialog *d, MessageId message_id, const char *source);
-
- static void attach_message_to_next(Dialog *d, MessageId message_id, const char *source);
-
- bool update_message(Dialog *d, Message *old_message, unique_ptr<Message> new_message, bool *need_update_dialog_pos,
- bool is_message_in_dialog);
+ bool update_message(Dialog *d, Message *old_message, unique_ptr<Message> new_message, bool is_message_in_dialog);
static bool need_message_changed_warning(const Message *old_message);
@@ -2469,11 +2347,14 @@ class MessagesManager final : public Actor {
static bool is_message_notification_active(const Dialog *d, const Message *m);
+ static NotificationGroupInfo &get_notification_group_info(Dialog *d, bool from_mentions);
+
static NotificationGroupInfo &get_notification_group_info(Dialog *d, const Message *m);
NotificationGroupId get_dialog_notification_group_id(DialogId dialog_id, NotificationGroupInfo &group_info);
- NotificationId get_next_notification_id(Dialog *d, NotificationGroupId notification_group_id, MessageId message_id);
+ NotificationId get_next_notification_id(NotificationInfo *notification_info,
+ NotificationGroupId notification_group_id, MessageId message_id);
void try_add_pinned_message_notification(Dialog *d, vector<Notification> &res, NotificationId max_notification_id,
int32 limit);
@@ -2516,7 +2397,7 @@ class MessagesManager final : public Actor {
bool need_skip_bot_commands(DialogId dialog_id, const Message *m) const;
- void send_update_message_send_succeeded(Dialog *d, MessageId old_message_id, const Message *m) const;
+ void send_update_message_send_succeeded(const Dialog *d, MessageId old_message_id, const Message *m);
void send_update_message_content(const Dialog *d, Message *m, bool is_message_in_dialog, const char *source);
@@ -2534,14 +2415,14 @@ class MessagesManager final : public Actor {
void send_update_new_chat(Dialog *d);
+ bool need_hide_dialog_draft_message(DialogId dialog_id) const;
+
void send_update_chat_draft_message(const Dialog *d);
void send_update_chat_last_message(Dialog *d, const char *source);
void send_update_chat_last_message_impl(const Dialog *d, const char *source) const;
- void send_update_chat_filters();
-
void send_update_unread_message_count(DialogList &list, DialogId dialog_id, bool force, const char *source,
bool from_database = false);
@@ -2566,6 +2447,10 @@ class MessagesManager final : public Actor {
void send_update_chat_available_reactions(const Dialog *d);
+ void send_update_secret_chats_with_user_background(const Dialog *d) const;
+
+ void send_update_chat_background(const Dialog *d);
+
void send_update_secret_chats_with_user_theme(const Dialog *d) const;
void send_update_chat_theme(const Dialog *d);
@@ -2576,7 +2461,7 @@ class MessagesManager final : public Actor {
void send_update_chat_message_sender(const Dialog *d);
- void send_update_chat_message_ttl(const Dialog *d);
+ void send_update_chat_message_auto_delete_time(const Dialog *d);
void send_update_chat_has_scheduled_messages(Dialog *d, bool from_deletion);
@@ -2597,8 +2482,7 @@ class MessagesManager final : public Actor {
static tl_object_ptr<td_api::MessageSchedulingState> get_message_scheduling_state_object(int32 send_date);
- tl_object_ptr<td_api::message> get_message_object(DialogId dialog_id, const Message *m, const char *source,
- bool for_event_log = false) const;
+ tl_object_ptr<td_api::message> get_message_object(DialogId dialog_id, const Message *m, const char *source) const;
static tl_object_ptr<td_api::messages> get_messages_object(int32 total_count,
vector<tl_object_ptr<td_api::message>> &&messages,
@@ -2606,8 +2490,6 @@ class MessagesManager final : public Actor {
vector<DialogId> sort_dialogs_by_order(const vector<DialogId> &dialog_ids, int32 limit) const;
- vector<DialogId> get_peers_dialog_ids(vector<tl_object_ptr<telegram_api::Peer>> &&peers);
-
static bool need_unread_counter(int64 dialog_order);
int32 get_dialog_total_count(const DialogList &list) const;
@@ -2620,8 +2502,6 @@ class MessagesManager final : public Actor {
void recalc_unread_count(DialogListId dialog_list_id, int32 old_dialog_total_count, bool force);
- td_api::object_ptr<td_api::updateChatFilters> get_update_chat_filters_object() const;
-
td_api::object_ptr<td_api::updateUnreadMessageCount> get_update_unread_message_count_object(
const DialogList &list) const;
@@ -2667,6 +2547,8 @@ class MessagesManager final : public Actor {
void set_dialog_is_marked_as_unread(Dialog *d, bool is_marked_as_unread);
+ void set_dialog_is_translatable(Dialog *d, bool is_translatable);
+
void set_dialog_is_blocked(Dialog *d, bool is_blocked);
void set_dialog_has_bots(Dialog *d, bool has_bots);
@@ -2675,6 +2557,8 @@ class MessagesManager final : public Actor {
void drop_dialog_last_pinned_message_id(Dialog *d);
+ void set_dialog_background(Dialog *d, BackgroundInfo &&background_info);
+
void set_dialog_theme_name(Dialog *d, string theme_name);
void fix_pending_join_requests(DialogId dialog_id, int32 &pending_join_request_count,
@@ -2699,6 +2583,8 @@ class MessagesManager final : public Actor {
void toggle_dialog_is_marked_as_unread_on_server(DialogId dialog_id, bool is_marked_as_unread, uint64 log_event_id);
+ void toggle_dialog_is_translatable_on_server(DialogId dialog_id, bool is_translatable, uint64 log_event_id);
+
void toggle_dialog_is_blocked_on_server(DialogId dialog_id, bool is_blocked, uint64 log_event_id);
void reorder_pinned_dialogs_on_server(FolderId folder_id, const vector<DialogId> &dialog_ids, uint64 log_event_id);
@@ -2728,6 +2614,8 @@ class MessagesManager final : public Actor {
bool update_dialog_silent_send_message(Dialog *d, bool silent_send_message);
+ void set_dialog_message_ttl(Dialog *d, MessageTtl message_ttl);
+
ChatReactions get_message_available_reactions(const Dialog *d, const Message *m,
bool dissalow_custom_for_non_premium);
@@ -2735,6 +2623,8 @@ class MessagesManager final : public Actor {
void on_set_message_reactions(FullMessageId full_message_id, Result<Unit> result, Promise<Unit> promise);
+ void on_read_message_reactions(DialogId dialog_id, vector<MessageId> &&message_ids, Result<Unit> &&result);
+
void set_dialog_available_reactions(Dialog *d, ChatReactions &&available_reactions);
void set_dialog_next_available_reactions_generation(Dialog *d, uint32 generation);
@@ -2769,6 +2659,9 @@ class MessagesManager final : public Actor {
MessageId get_message_id_by_random_id(Dialog *d, int64 random_id, const char *source);
+ Dialog *add_dialog_for_new_message(DialogId dialog_id, bool have_last_message, bool *need_update_dialog_pos,
+ const char *source);
+
Dialog *add_dialog(DialogId dialog_id, const char *source);
Dialog *add_new_dialog(unique_ptr<Dialog> &&dialog, bool is_loaded_from_database, const char *source);
@@ -2787,6 +2680,8 @@ class MessagesManager final : public Actor {
td_api::object_ptr<td_api::ChatActionBar> get_chat_action_bar_object(const Dialog *d) const;
+ td_api::object_ptr<td_api::chatBackground> get_chat_background_object(const Dialog *d) const;
+
string get_dialog_theme_name(const Dialog *d) const;
td_api::object_ptr<td_api::chatJoinRequestsInfo> get_chat_join_requests_info_object(const Dialog *d) const;
@@ -2815,82 +2710,9 @@ class MessagesManager final : public Actor {
void reload_pinned_dialogs(DialogListId dialog_list_id, Promise<Unit> &&promise);
- static double get_dialog_filters_cache_time();
-
- void schedule_dialog_filters_reload(double timeout);
-
- static void on_reload_dialog_filters_timeout(void *messages_manager_ptr);
-
- void reload_dialog_filters();
-
- void on_get_dialog_filters(Result<vector<tl_object_ptr<telegram_api::DialogFilter>>> r_filters, bool dummy);
-
- bool need_synchronize_dialog_filters() const;
-
- void synchronize_dialog_filters();
-
void update_dialogs_hints(const Dialog *d);
void update_dialogs_hints_rating(const Dialog *d);
- td_api::object_ptr<td_api::chatFilter> get_chat_filter_object(const DialogFilter *filter) const;
-
- void load_dialog_filter_dialogs(DialogFilterId dialog_filter_id, vector<InputDialogId> &&input_dialog_ids,
- Promise<Unit> &&promise);
-
- void on_load_dialog_filter_dialogs(DialogFilterId dialog_filter_id, vector<DialogId> &&dialog_ids,
- Promise<Unit> &&promise);
-
- void load_dialog_filter(const DialogFilter *filter, bool force, Promise<Unit> &&promise);
-
- void on_get_recommended_dialog_filters(Result<vector<tl_object_ptr<telegram_api::dialogFilterSuggested>>> result,
- Promise<td_api::object_ptr<td_api::recommendedChatFilters>> &&promise);
-
- void on_load_recommended_dialog_filters(Result<Unit> &&result, vector<RecommendedDialogFilter> &&filters,
- Promise<td_api::object_ptr<td_api::recommendedChatFilters>> &&promise);
-
- InputDialogId get_input_dialog_id(DialogId dialog_id) const;
-
- void sort_dialog_filter_input_dialog_ids(DialogFilter *dialog_filter, const char *source) const;
-
- Result<unique_ptr<DialogFilter>> create_dialog_filter(DialogFilterId dialog_filter_id,
- td_api::object_ptr<td_api::chatFilter> filter);
-
- void update_dialog_filter_on_server(unique_ptr<DialogFilter> &&dialog_filter);
-
- void on_update_dialog_filter(unique_ptr<DialogFilter> dialog_filter, Status result);
-
- void delete_dialog_filter_on_server(DialogFilterId dialog_filter_id);
-
- void on_delete_dialog_filter(DialogFilterId dialog_filter_id, Status result);
-
- void reorder_dialog_filters_on_server(vector<DialogFilterId> dialog_filter_ids, int32 main_dialog_list_position);
-
- void on_reorder_dialog_filters(vector<DialogFilterId> dialog_filter_ids, int32 main_dialog_list_position,
- Status result);
-
- void save_dialog_filters();
-
- void add_dialog_filter(unique_ptr<DialogFilter> dialog_filter, bool at_beginning, const char *source);
-
- void edit_dialog_filter(unique_ptr<DialogFilter> new_dialog_filter, const char *source);
-
- int32 delete_dialog_filter(DialogFilterId dialog_filter_id, const char *source);
-
- static bool set_dialog_filters_order(vector<unique_ptr<DialogFilter>> &dialog_filters,
- vector<DialogFilterId> dialog_filter_ids);
-
- const DialogFilter *get_server_dialog_filter(DialogFilterId dialog_filter_id) const;
-
- DialogFilter *get_dialog_filter(DialogFilterId dialog_filter_id);
- const DialogFilter *get_dialog_filter(DialogFilterId dialog_filter_id) const;
-
- int32 get_server_main_dialog_list_position() const;
-
- static vector<DialogFilterId> get_dialog_filter_ids(const vector<unique_ptr<DialogFilter>> &dialog_filters,
- int32 main_dialog_list_position);
-
- static vector<FolderId> get_dialog_filter_folder_ids(const DialogFilter *filter);
-
vector<FolderId> get_dialog_list_folder_ids(const DialogList &list) const;
bool has_dialogs_from_folder(const DialogList &list, const DialogFolder &folder) const;
@@ -2901,7 +2723,7 @@ class MessagesManager final : public Actor {
static void remove_dialog_from_list(Dialog *d, DialogListId dialog_list_id);
- bool need_dialog_in_filter(const Dialog *d, const DialogFilter *filter) const;
+ DialogFilterDialogInfo get_dialog_info_for_dialog_filter(const Dialog *d) const;
bool need_dialog_in_list(const Dialog *d, const DialogList &list) const;
@@ -2924,12 +2746,6 @@ class MessagesManager final : public Actor {
DialogFolder *get_dialog_folder(FolderId folder_id);
const DialogFolder *get_dialog_folder(FolderId folder_id) const;
- static unique_ptr<Message> *treap_find_message(unique_ptr<Message> *v, MessageId message_id);
- static const unique_ptr<Message> *treap_find_message(const unique_ptr<Message> *v, MessageId message_id);
-
- static Message *treap_insert_message(unique_ptr<Message> *v, unique_ptr<Message> message);
- static unique_ptr<Message> treap_delete_message(unique_ptr<Message> *v);
-
static Message *get_message(Dialog *d, MessageId message_id);
static const Message *get_message(const Dialog *d, MessageId message_id);
@@ -2953,6 +2769,9 @@ class MessagesManager final : public Actor {
Message *on_get_message_from_database(Dialog *d, MessageId message_id, const BufferSlice &value, bool is_scheduled,
const char *source);
+ vector<MessageId> on_get_messages_from_database(Dialog *d, vector<MessageDbDialogMessage> &&messages,
+ MessageId first_message_id, bool &have_error, const char *source);
+
void get_dialog_message_by_date_from_server(const Dialog *d, int32 date, int64 random_id, bool after_database_search,
Promise<Unit> &&promise);
@@ -3024,11 +2843,12 @@ class MessagesManager final : public Actor {
void hangup() final;
void create_folders();
+
void init();
- void ttl_db_loop_start(double server_now);
- void ttl_db_loop(double server_now);
- void ttl_db_on_result(Result<std::pair<std::vector<MessageDbMessage>, int32>> r_result, bool dummy);
+ void ttl_db_loop();
+
+ void ttl_db_on_result(Result<std::vector<MessageDbMessage>> r_result, bool dummy);
void on_restore_missing_message_after_get_difference(FullMessageId full_message_id, MessageId old_message_id,
Result<Unit> result);
@@ -3047,8 +2867,8 @@ class MessagesManager final : public Actor {
void on_get_discussion_message(DialogId dialog_id, MessageId message_id, MessageThreadInfo &&message_thread_info,
Promise<MessageThreadInfo> &&promise);
- void on_get_message_viewers(DialogId dialog_id, vector<UserId> user_ids, bool is_recursive,
- Promise<td_api::object_ptr<td_api::users>> &&promise);
+ void on_get_message_viewers(DialogId dialog_id, MessageViewers message_viewers, bool is_recursive,
+ Promise<td_api::object_ptr<td_api::messageViewers>> &&promise);
static MessageId get_first_database_message_id_by_index(const Dialog *d, MessageSearchFilter filter);
@@ -3108,6 +2928,10 @@ class MessagesManager final : public Actor {
bool get_dialog_has_scheduled_messages(const Dialog *d) const;
+ static DialogScheduledMessages *add_dialog_scheduled_messages(Dialog *d);
+
+ static NotificationInfo *add_dialog_notification_info(Dialog *d);
+
static int64 get_dialog_order(MessageId message_id, int32 message_date);
bool is_dialog_sponsored(const Dialog *d) const;
@@ -3175,18 +2999,28 @@ class MessagesManager final : public Actor {
bool need_channel_difference_to_add_message(DialogId dialog_id,
const tl_object_ptr<telegram_api::Message> &message_ptr);
- void run_after_channel_difference(DialogId dialog_id, Promise<Unit> &&promise);
+ void run_after_channel_difference(DialogId dialog_id, MessageId expected_max_message_id, Promise<Unit> &&promise);
bool running_get_channel_difference(DialogId dialog_id) const;
void on_channel_get_difference_timeout(DialogId dialog_id);
- void get_channel_difference(DialogId dialog_id, int32 pts, bool force, const char *source, bool is_old = false);
+ void update_expected_channel_pts(DialogId dialog_id, int32 expected_pts);
+
+ void update_expected_channel_max_message_id(DialogId dialog_id, MessageId expected_max_message_id);
+
+ void schedule_get_channel_difference(DialogId dialog_id, int32 expected_pts, MessageId expected_max_message_id,
+ double delay);
+
+ void get_channel_difference(DialogId dialog_id, int32 pts, int32 expected_pts, MessageId expected_max_message_id,
+ bool force, const char *source, bool is_old = false);
void do_get_channel_difference(DialogId dialog_id, int32 pts, bool force,
tl_object_ptr<telegram_api::InputChannel> &&input_channel, bool is_old,
const char *source);
+ void process_pending_get_channel_differences();
+
void process_get_channel_difference_updates(DialogId dialog_id, int32 new_pts,
vector<tl_object_ptr<telegram_api::Message>> &&new_messages,
vector<tl_object_ptr<telegram_api::Update>> &&other_updates);
@@ -3224,6 +3058,8 @@ class MessagesManager final : public Actor {
static void on_update_viewed_messages_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int);
+ static void on_send_update_chat_read_inbox_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int);
+
void load_secret_thumbnail(FileId thumbnail_file_id);
void on_upload_media(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file,
@@ -3269,11 +3105,11 @@ class MessagesManager final : public Actor {
void save_auth_notification_ids();
- static MessageId get_next_message_id(Dialog *d, MessageType type);
+ MessageId get_next_message_id(Dialog *d, MessageType type) const;
- static MessageId get_next_local_message_id(Dialog *d);
+ MessageId get_next_local_message_id(Dialog *d) const;
- static MessageId get_next_yet_unsent_message_id(Dialog *d);
+ MessageId get_next_yet_unsent_message_id(Dialog *d) const;
static MessageId get_next_yet_unsent_scheduled_message_id(Dialog *d, int32 date);
@@ -3305,14 +3141,8 @@ class MessagesManager final : public Actor {
void load_calls_db_state();
void save_calls_db_state();
- static constexpr bool is_debug_message_op_enabled() {
- return !LOG_IS_STRIPPED(ERROR) && false;
- }
-
void add_message_dependencies(Dependencies &dependencies, const Message *m);
- static void dump_debug_message_op(const Dialog *d, int priority = 0);
-
static void save_send_message_log_event(DialogId dialog_id, const Message *m);
static uint64 save_toggle_dialog_report_spam_state_on_server_log_event(DialogId dialog_id, bool is_spam_dialog);
@@ -3352,6 +3182,8 @@ class MessagesManager final : public Actor {
static uint64 save_toggle_dialog_is_marked_as_unread_on_server_log_event(DialogId dialog_id,
bool is_marked_as_unread);
+ static uint64 save_toggle_dialog_is_translatable_on_server_log_event(DialogId dialog_id, bool is_translatable);
+
static uint64 save_toggle_dialog_is_blocked_on_server_log_event(DialogId dialog_id, bool is_blocked);
static uint64 save_read_message_contents_on_server_log_event(DialogId dialog_id,
@@ -3367,8 +3199,8 @@ class MessagesManager final : public Actor {
static uint64 save_unpin_all_dialog_messages_on_server_log_event(DialogId dialog_id);
- void suffix_load_loop(Dialog *d);
- static void suffix_load_update_first_message_id(Dialog *d);
+ void suffix_load_loop(const Dialog *d, SuffixLoadQueries *queries);
+ void suffix_load_update_first_message_id(const Dialog *d, SuffixLoadQueries *queries);
void suffix_load_query_ready(DialogId dialog_id);
void suffix_load_add_query(Dialog *d, std::pair<Promise<Unit>, std::function<bool(const Message *)>> query);
void suffix_load_till_date(Dialog *d, int32 date, Promise<Unit> promise);
@@ -3376,6 +3208,8 @@ class MessagesManager final : public Actor {
bool is_group_dialog(DialogId dialog_id) const;
+ bool is_forum_channel(DialogId dialog_id) const;
+
bool is_broadcast_channel(DialogId dialog_id) const;
bool is_deleted_secret_chat(const Dialog *d) const;
@@ -3450,9 +3284,9 @@ class MessagesManager final : public Actor {
Slot ttl_slot_;
enum YieldType : int32 { None, TtlDb }; // None must be first
- int32 ttl_db_expires_from_;
- int32 ttl_db_expires_till_;
- bool ttl_db_has_query_;
+ double ttl_db_next_request_time_ = 0;
+ int32 ttl_db_next_limit_ = DEFAULT_LOADED_EXPIRED_MESSAGES;
+ bool ttl_db_has_query_ = false;
Slot ttl_db_slot_;
FlatHashMap<int64, FullMessageId> being_sent_messages_; // message_random_id -> message
@@ -3544,6 +3378,7 @@ class MessagesManager final : public Actor {
int64 added_message_count_ = 0;
FlatHashSet<DialogId, DialogIdHash> loaded_dialogs_; // dialogs loaded from database, but not added to dialogs_
+ FlatHashSet<DialogId, DialogIdHash> failed_to_load_dialogs_;
FlatHashSet<DialogId, DialogIdHash> postponed_chat_read_inbox_updates_;
@@ -3562,13 +3397,10 @@ class MessagesManager final : public Actor {
FlatHashMap<int64, FullMessageId> get_dialog_message_by_date_results_;
FlatHashMap<int64, td_api::object_ptr<td_api::messageCalendar>> found_dialog_message_calendars_;
- FlatHashMap<int64, std::pair<int32, vector<MessageId>>>
- found_dialog_messages_; // random_id -> [total_count, [message_id]...]
- FlatHashMap<int64, DialogId> found_dialog_messages_dialog_id_; // random_id -> dialog_id
- FlatHashMap<int64, std::pair<int32, vector<FullMessageId>>>
- found_messages_; // random_id -> [total_count, [full_message_id]...]
- FlatHashMap<int64, std::pair<int32, vector<FullMessageId>>>
- found_call_messages_; // random_id -> [total_count, [full_message_id]...]
+ FlatHashMap<int64, FoundDialogMessages> found_dialog_messages_; // random_id -> FoundDialogMessages
+ FlatHashMap<int64, DialogId> found_dialog_messages_dialog_id_; // random_id -> dialog_id
+ FlatHashMap<int64, FoundMessages> found_messages_; // random_id -> FoundMessages
+ FlatHashMap<int64, FoundMessages> found_call_messages_; // random_id -> FoundMessages
FlatHashMap<int64, FoundMessages> found_fts_messages_; // random_id -> FoundMessages
@@ -3616,24 +3448,35 @@ class MessagesManager final : public Actor {
std::unordered_map<DialogListId, DialogList, DialogListIdHash> dialog_lists_;
std::unordered_map<FolderId, DialogFolder, FolderIdHash> dialog_folders_;
- bool are_dialog_filters_being_synchronized_ = false;
- bool are_dialog_filters_being_reloaded_ = false;
- bool need_dialog_filters_reload_ = false;
- bool disable_get_dialog_filter_ = false;
- bool is_update_chat_filters_sent_ = false;
- int32 dialog_filters_updated_date_ = 0;
- vector<unique_ptr<DialogFilter>> server_dialog_filters_;
- vector<unique_ptr<DialogFilter>> dialog_filters_;
- vector<RecommendedDialogFilter> recommended_dialog_filters_;
- vector<Promise<Unit>> dialog_filter_reload_queries_;
- int32 server_main_dialog_list_position_ = 0; // position of the main dialog list stored on the server
- int32 main_dialog_list_position_ = 0; // local position of the main dialog list stored on the server
-
- FlatHashMap<DialogId, string, DialogIdHash> active_get_channel_differencies_;
+ struct PendingGetChannelDifference {
+ DialogId dialog_id_;
+ int32 pts_ = 0;
+ int32 limit_ = 0;
+ bool force_ = false;
+ telegram_api::object_ptr<telegram_api::InputChannel> input_channel_;
+ const char *source_ = nullptr;
+
+ PendingGetChannelDifference(DialogId dialog_id, int32 pts, int32 limit, bool force,
+ telegram_api::object_ptr<telegram_api::InputChannel> &&input_channel,
+ const char *source)
+ : dialog_id_(dialog_id)
+ , pts_(pts)
+ , limit_(limit)
+ , force_(force)
+ , input_channel_(std::move(input_channel))
+ , source_(source) {
+ }
+ };
+ std::queue<unique_ptr<PendingGetChannelDifference>> pending_get_channel_differences_;
+ int32 get_channel_difference_count_ = 0;
+
+ FlatHashMap<DialogId, string, DialogIdHash> active_get_channel_differences_;
FlatHashMap<DialogId, uint64, DialogIdHash> get_channel_difference_to_log_event_id_;
FlatHashMap<DialogId, int32, DialogIdHash> channel_get_difference_retry_timeouts_;
FlatHashMap<DialogId, std::multimap<int32, PendingPtsUpdate>, DialogIdHash> postponed_channel_updates_;
FlatHashSet<DialogId, DialogIdHash> is_channel_difference_finished_;
+ FlatHashMap<DialogId, int32, DialogIdHash> expected_channel_pts_;
+ FlatHashMap<DialogId, MessageId, DialogIdHash> expected_channel_max_message_id_;
MultiTimeout channel_get_difference_timeout_{"ChannelGetDifferenceTimeout"};
MultiTimeout channel_get_difference_retry_timeout_{"ChannelGetDifferenceRetryTimeout"};
@@ -3649,8 +3492,7 @@ class MessagesManager final : public Actor {
MultiTimeout update_dialog_online_member_count_timeout_{"UpdateDialogOnlineMemberCountTimeout"};
MultiTimeout preload_folder_dialog_list_timeout_{"PreloadFolderDialogListTimeout"};
MultiTimeout update_viewed_messages_timeout_{"UpdateViewedMessagesTimeout"};
-
- Timeout reload_dialog_filters_timeout_;
+ MultiTimeout send_update_chat_read_inbox_timeout_{"SendUpdateChatReadInboxTimeout"};
Hints dialogs_hints_; // search dialogs by title and usernames
@@ -3732,8 +3574,14 @@ class MessagesManager final : public Actor {
int64 viewed_live_location_task_id_ = 0;
FlatHashMap<int64, FullMessageId> viewed_live_location_tasks_; // task_id -> task
+ FlatHashMap<DialogId, FlatHashMap<MessageId, int64, MessageIdHash>, DialogIdHash>
+ pending_viewed_live_locations_; // ... -> task_id
- FlatHashMap<uint64, std::map<MessageId, Promise<Message *>>> yet_unsent_media_queues_;
+ struct UnsentMediaQueue {
+ DialogId dialog_id_;
+ std::map<MessageId, Promise<Message *>> queue_;
+ };
+ FlatHashMap<uint64, UnsentMediaQueue> yet_unsent_media_queues_;
FlatHashMap<DialogId, NetQueryRef, DialogIdHash> set_typing_query_;
@@ -3767,12 +3615,31 @@ class MessagesManager final : public Actor {
FlatHashMap<DialogId, MessageId, DialogIdHash> previous_repaired_read_inbox_max_message_id_;
+ FlatHashMap<FullMessageId, MessageId, FullMessageIdHash> yet_unsent_full_message_id_to_persistent_message_id_;
+ FlatHashMap<FullMessageId, std::set<MessageId>, FullMessageIdHash>
+ yet_unsent_thread_message_ids_; // {dialog_id, top_thread_message_id} -> yet unsent message IDs
+
+ FlatHashMap<DialogId, unique_ptr<SuffixLoadQueries>, DialogIdHash> dialog_suffix_load_queries_;
+
+ struct PendingMessageView {
+ FlatHashSet<MessageId, MessageIdHash> message_ids_;
+ bool increment_view_counter_ = false;
+ };
+ FlatHashMap<DialogId, PendingMessageView, DialogIdHash> pending_message_views_;
+
+ FlatHashMap<DialogId, std::unordered_map<int64, LogEventIdWithGeneration, Hash<int64>>, DialogIdHash>
+ read_history_log_event_ids_;
+
+ FlatHashMap<DialogId, std::unordered_set<MessageId, MessageIdHash>, DialogIdHash> updated_read_history_message_ids_;
+
struct PendingReaction {
int32 query_count = 0;
bool was_updated = false;
};
FlatHashMap<FullMessageId, PendingReaction, FullMessageIdHash> pending_reactions_;
+ FlatHashMap<FullMessageId, int32, FullMessageIdHash> pending_read_reactions_;
+
vector<string> active_reactions_;
FlatHashMap<string, size_t> active_reaction_pos_;