diff options
author | George Hazan <george.hazan@gmail.com> | 2024-09-29 19:03:55 +0300 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2024-09-29 19:04:03 +0300 |
commit | cebfc5c8facbf6ae335499f7f4b3dc57a60af999 (patch) | |
tree | 4c39e613c87f6164df1fe80601e611987aaaec84 /protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h | |
parent | 189164bebda4bca9bb3d672500d844bfe7f26517 (diff) |
TDLIB update up to the current state
Diffstat (limited to 'protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h')
-rw-r--r-- | protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h | 1485 |
1 files changed, 695 insertions, 790 deletions
diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h b/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h index 77730ac86b..973d0a8f50 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-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // 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) @@ -9,16 +9,15 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/AffectedHistory.h" #include "td/telegram/BackgroundInfo.h" +#include "td/telegram/BusinessConnectionId.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" -#include "td/telegram/DialogLocation.h" #include "td/telegram/DialogNotificationSettings.h" #include "td/telegram/DialogParticipant.h" #include "td/telegram/DialogSource.h" @@ -26,51 +25,60 @@ #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileSourceId.h" #include "td/telegram/FolderId.h" -#include "td/telegram/FullMessageId.h" -#include "td/telegram/InputDialogId.h" #include "td/telegram/InputGroupCallId.h" #include "td/telegram/logevent/LogEventHelper.h" #include "td/telegram/MessageContentType.h" #include "td/telegram/MessageCopyOptions.h" #include "td/telegram/MessageDb.h" +#include "td/telegram/MessageEffectId.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/MessageId.h" +#include "td/telegram/MessageInputReplyTo.h" #include "td/telegram/MessageLinkInfo.h" +#include "td/telegram/MessageOrigin.h" #include "td/telegram/MessageReplyHeader.h" #include "td/telegram/MessageReplyInfo.h" #include "td/telegram/MessageSearchFilter.h" +#include "td/telegram/MessageSelfDestructType.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" +#include "td/telegram/NotificationGroupFromDatabase.h" #include "td/telegram/NotificationGroupId.h" +#include "td/telegram/NotificationGroupInfo.h" #include "td/telegram/NotificationGroupKey.h" #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/QuickReplyShortcutId.h" +#include "td/telegram/ReactionType.h" +#include "td/telegram/ReactionUnavailabilityReason.h" #include "td/telegram/RecentDialogList.h" +#include "td/telegram/RepliedMessageInfo.h" #include "td/telegram/ReplyMarkup.h" -#include "td/telegram/ReportReason.h" #include "td/telegram/RestrictionReason.h" +#include "td/telegram/SavedMessagesTopicId.h" #include "td/telegram/ScheduledServerMessageId.h" #include "td/telegram/secret_api.h" #include "td/telegram/SecretChatId.h" #include "td/telegram/SecretInputMedia.h" #include "td/telegram/ServerMessageId.h" +#include "td/telegram/StoryFullId.h" +#include "td/telegram/StoryNotificationSettings.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" -#include "td/telegram/Usernames.h" #include "td/actor/actor.h" #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" @@ -101,45 +109,23 @@ namespace td { struct BinlogEvent; +class BusinessBotManageBar; class Dependencies; class DialogActionBar; class DialogFilter; class DraftMessage; +class FactCheck; struct InputMessageContent; class MessageContent; +class MessageForwardInfo; struct MessageReactions; +struct MessageSearchOffset; +class MissingInvitees; class Td; +class Usernames; class MessagesManager final : public Actor { public: - // static constexpr int32 MESSAGE_FLAG_IS_UNREAD = 1 << 0; - static constexpr int32 MESSAGE_FLAG_IS_OUT = 1 << 1; - static constexpr int32 MESSAGE_FLAG_IS_FORWARDED = 1 << 2; - static constexpr int32 MESSAGE_FLAG_IS_REPLY = 1 << 3; - static constexpr int32 MESSAGE_FLAG_HAS_MENTION = 1 << 4; - static constexpr int32 MESSAGE_FLAG_HAS_UNREAD_CONTENT = 1 << 5; - static constexpr int32 MESSAGE_FLAG_HAS_REPLY_MARKUP = 1 << 6; - static constexpr int32 MESSAGE_FLAG_HAS_ENTITIES = 1 << 7; - static constexpr int32 MESSAGE_FLAG_HAS_FROM_ID = 1 << 8; - static constexpr int32 MESSAGE_FLAG_HAS_MEDIA = 1 << 9; - static constexpr int32 MESSAGE_FLAG_HAS_INTERACTION_INFO = 1 << 10; - static constexpr int32 MESSAGE_FLAG_IS_SENT_VIA_BOT = 1 << 11; - static constexpr int32 MESSAGE_FLAG_IS_SILENT = 1 << 13; - static constexpr int32 MESSAGE_FLAG_IS_POST = 1 << 14; - static constexpr int32 MESSAGE_FLAG_HAS_EDIT_DATE = 1 << 15; - static constexpr int32 MESSAGE_FLAG_HAS_AUTHOR_SIGNATURE = 1 << 16; - static constexpr int32 MESSAGE_FLAG_HAS_MEDIA_ALBUM_ID = 1 << 17; - static constexpr int32 MESSAGE_FLAG_IS_FROM_SCHEDULED = 1 << 18; - static constexpr int32 MESSAGE_FLAG_IS_LEGACY = 1 << 19; - static constexpr int32 MESSAGE_FLAG_HAS_REACTIONS = 1 << 20; - static constexpr int32 MESSAGE_FLAG_HIDE_EDIT_DATE = 1 << 21; - static constexpr int32 MESSAGE_FLAG_IS_RESTRICTED = 1 << 22; - static constexpr int32 MESSAGE_FLAG_HAS_REPLY_INFO = 1 << 23; - static constexpr int32 MESSAGE_FLAG_IS_PINNED = 1 << 24; - static constexpr int32 MESSAGE_FLAG_HAS_TTL_PERIOD = 1 << 25; - static constexpr int32 MESSAGE_FLAG_NOFORWARDS = 1 << 26; - - static constexpr int32 SEND_MESSAGE_FLAG_IS_REPLY = 1 << 0; static constexpr int32 SEND_MESSAGE_FLAG_DISABLE_WEB_PAGE_PREVIEW = 1 << 1; static constexpr int32 SEND_MESSAGE_FLAG_HAS_REPLY_MARKUP = 1 << 2; static constexpr int32 SEND_MESSAGE_FLAG_HAS_ENTITIES = 1 << 3; @@ -154,8 +140,8 @@ class MessagesManager final : public Actor { static constexpr int32 SEND_MESSAGE_FLAG_HAS_SEND_AS = 1 << 13; static constexpr int32 SEND_MESSAGE_FLAG_NOFORWARDS = 1 << 14; static constexpr int32 SEND_MESSAGE_FLAG_UPDATE_STICKER_SETS_ORDER = 1 << 15; - - static constexpr int32 ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME = 30 * 60; + static constexpr int32 SEND_MESSAGE_FLAG_INVERT_MEDIA = 1 << 16; + static constexpr int32 SEND_MESSAGE_FLAG_EFFECT = 1 << 18; MessagesManager(Td *td, ActorShared<> parent); MessagesManager(const MessagesManager &) = delete; @@ -164,33 +150,23 @@ class MessagesManager final : public Actor { MessagesManager &operator=(MessagesManager &&) = delete; ~MessagesManager() final; - 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); - - vector<tl_object_ptr<telegram_api::InputPeer>> get_input_peers(const vector<DialogId> &dialog_ids, - AccessRights access_rights) const; - - tl_object_ptr<telegram_api::InputDialogPeer> get_input_dialog_peer(DialogId dialog_id, - AccessRights access_rights) const; - - vector<tl_object_ptr<telegram_api::InputDialogPeer>> get_input_dialog_peers(const vector<DialogId> &dialog_ids, - AccessRights access_rights) const; + static bool is_invalid_poll_message(const telegram_api::Message *message); - tl_object_ptr<telegram_api::inputEncryptedChat> get_input_encrypted_chat(DialogId dialog_id, - AccessRights access_rights) const; - - bool have_input_peer(DialogId dialog_id, AccessRights access_rights) const; - - vector<DialogId> get_peers_dialog_ids(vector<tl_object_ptr<telegram_api::Peer>> &&peers, - bool expect_no_access = false); + static int32 get_message_date(const tl_object_ptr<telegram_api::Message> &message_ptr); void on_get_empty_messages(DialogId dialog_id, const vector<MessageId> &empty_message_ids); + void get_channel_difference_if_needed(DialogId dialog_id, MessageId message_id, const char *source); + void get_channel_difference_if_needed(DialogId dialog_id, MessagesInfo &&messages_info, - Promise<MessagesInfo> &&promise); + Promise<MessagesInfo> &&promise, const char *source); + + void get_channel_differences_if_needed(MessagesInfo &&messages_info, Promise<MessagesInfo> &&promise, + const char *source); - void get_channel_differences_if_needed(MessagesInfo &&messages_info, Promise<MessagesInfo> &&promise); + void get_channel_differences_if_needed( + const vector<const telegram_api::object_ptr<telegram_api::Message> *> &messages, Promise<Unit> &&promise, + const char *source); void on_get_messages(vector<tl_object_ptr<telegram_api::Message>> &&messages, bool is_channel_message, bool is_scheduled, Promise<Unit> &&promise, const char *source); @@ -203,30 +179,36 @@ class MessagesManager final : public Actor { vector<tl_object_ptr<telegram_api::Peer>> &&peers); void on_failed_public_dialogs_search(const string &query, Status &&error); - void on_get_message_search_result_calendar(DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, - int64 random_id, int32 total_count, + void on_get_message_search_result_calendar(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, int32 total_count, vector<tl_object_ptr<telegram_api::Message>> &&messages, vector<tl_object_ptr<telegram_api::searchResultsCalendarPeriod>> &&periods, - Promise<Unit> &&promise); - void on_failed_get_message_search_result_calendar(DialogId dialog_id, int64 random_id); - - void on_get_dialog_messages_search_result(DialogId dialog_id, const string &query, DialogId sender_dialog_id, - MessageId from_message_id, int32 offset, int32 limit, - MessageSearchFilter filter, MessageId top_thread_message_id, - int64 random_id, int32 total_count, - vector<tl_object_ptr<telegram_api::Message>> &&messages, + Promise<td_api::object_ptr<td_api::messageCalendar>> &&promise); + + void on_get_call_messages(MessageId from_message_id, int32 limit, MessageSearchFilter filter, int32 total_count, + vector<telegram_api::object_ptr<telegram_api::Message>> &&messages, + Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); + + void on_get_dialog_messages_search_result(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + const string &query, DialogId sender_dialog_id, MessageId from_message_id, + int32 offset, int32 limit, MessageSearchFilter filter, + MessageId top_thread_message_id, const ReactionType &tag, int64 random_id, + int32 total_count, vector<tl_object_ptr<telegram_api::Message>> &&messages, Promise<Unit> &&promise); void on_failed_dialog_messages_search(DialogId dialog_id, int64 random_id); - void on_get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, int32 total_count, - Promise<int32> &&promise); + void on_get_dialog_message_count(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, int32 total_count, Promise<int32> &&promise); 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, + int32 min_date, int32 max_date, int32 total_count, vector<tl_object_ptr<telegram_api::Message>> &&messages, int32 next_rate, - Promise<Unit> &&promise); - void on_failed_messages_search(int64 random_id); + Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); + + void on_get_hashtag_search_result(const string &hashtag, const MessageSearchOffset &old_offset, int32 limit, + int32 total_count, vector<tl_object_ptr<telegram_api::Message>> &&messages, + int32 next_rate, Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); void on_get_outgoing_document_messages(vector<tl_object_ptr<telegram_api::Message>> &&messages, Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); @@ -238,11 +220,7 @@ class MessagesManager final : public Actor { vector<tl_object_ptr<telegram_api::Message>> &&messages, 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, - 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, + MessageFullId on_get_message(tl_object_ptr<telegram_api::Message> message_ptr, bool from_update, bool is_channel_message, bool is_scheduled, const char *source); void open_secret_message(SecretChatId secret_chat_id, int64 random_id, Promise<Unit>); @@ -273,31 +251,36 @@ class MessagesManager final : public Actor { void on_update_sent_text_message(int64 random_id, tl_object_ptr<telegram_api::MessageMedia> message_media, vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities); - void delete_pending_message_web_page(FullMessageId full_message_id); + void delete_pending_message_web_page(MessageFullId message_full_id); void on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<telegram_api::Dialog>> &&dialog_folders, int32 total_count, vector<tl_object_ptr<telegram_api::Message>> &&messages, Promise<Unit> &&promise); - void on_get_common_dialogs(UserId user_id, int64 offset_chat_id, vector<tl_object_ptr<telegram_api::Chat>> &&chats, - int32 total_count); - - bool on_update_message_id(int64 random_id, MessageId new_message_id, const string &source); + bool on_update_message_id(int64 random_id, MessageId new_message_id, const char *source); void on_update_dialog_draft_message(DialogId dialog_id, MessageId top_thread_message_id, - tl_object_ptr<telegram_api::DraftMessage> &&draft_message); + tl_object_ptr<telegram_api::DraftMessage> &&draft_message, bool force = false); void on_update_dialog_is_pinned(FolderId folder_id, DialogId dialog_id, bool is_pinned); void on_update_pinned_dialogs(FolderId folder_id); + void on_update_dialog_is_forum(DialogId dialog_id, bool is_forum); + + void on_update_dialog_view_as_messages(DialogId dialog_id, bool view_as_messages); + 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_is_blocked(DialogId dialog_id, bool is_blocked, bool is_blocked_for_stories); + + void on_update_dialog_business_bot_is_paused(DialogId dialog_id, bool is_paused); + + void on_update_dialog_business_bot_removed(DialogId dialog_id); void on_update_dialog_last_pinned_message_id(DialogId dialog_id, MessageId last_pinned_message_id); @@ -341,51 +324,51 @@ class MessagesManager final : public Actor { void on_update_channel_too_long(tl_object_ptr<telegram_api::updateChannelTooLong> &&update, bool force_apply); - void on_update_message_view_count(FullMessageId full_message_id, int32 view_count); + void on_update_message_view_count(MessageFullId message_full_id, int32 view_count); - void on_update_message_forward_count(FullMessageId full_message_id, int32 forward_count); + void on_update_message_forward_count(MessageFullId message_full_id, int32 forward_count); - void on_update_message_reactions(FullMessageId full_message_id, + void on_update_message_reactions(MessageFullId message_full_id, tl_object_ptr<telegram_api::messageReactions> &&reactions, Promise<Unit> &&promise); - void update_message_reactions(FullMessageId full_message_id, unique_ptr<MessageReactions> &&reactions); + void update_message_reactions(MessageFullId message_full_id, unique_ptr<MessageReactions> &&reactions); void try_reload_message_reactions(DialogId dialog_id, bool is_finished); - void on_get_message_reaction_list(FullMessageId full_message_id, const string &reaction, - FlatHashMap<string, vector<DialogId>> reactions, int32 total_count); + void on_get_message_reaction_list(MessageFullId message_full_id, const ReactionType &reaction_type, + FlatHashMap<ReactionType, vector<DialogId>, ReactionTypeHash> reaction_types, + int32 total_count); - void on_update_message_interaction_info(FullMessageId full_message_id, int32 view_count, int32 forward_count, + void on_update_message_interaction_info(MessageFullId message_full_id, int32 view_count, int32 forward_count, bool has_reply_info, tl_object_ptr<telegram_api::messageReplies> &&reply_info); - void on_update_live_location_viewed(FullMessageId full_message_id); + void on_update_live_location_viewed(MessageFullId message_full_id); void on_update_some_live_location_viewed(Promise<Unit> &&promise); - void on_update_message_extended_media(FullMessageId full_message_id, - telegram_api::object_ptr<telegram_api::MessageExtendedMedia> extended_media); + void on_update_message_extended_media( + MessageFullId message_full_id, + vector<telegram_api::object_ptr<telegram_api::MessageExtendedMedia>> extended_media); - void on_external_update_message_content(FullMessageId full_message_id); + void on_external_update_message_content(MessageFullId message_full_id, const char *source, + bool expect_no_message = false); - void on_update_message_content(FullMessageId full_message_id); + void on_update_message_content(MessageFullId message_full_id); void on_read_channel_inbox(ChannelId channel_id, MessageId max_message_id, int32 server_unread_count, int32 pts, const char *source); void on_read_channel_outbox(ChannelId channel_id, MessageId max_message_id); - void on_update_channel_max_unavailable_message_id(ChannelId channel_id, MessageId max_unavailable_message_id); - - void on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server); + void on_update_channel_max_unavailable_message_id(ChannelId channel_id, MessageId max_unavailable_message_id, + const char *source); void on_update_delete_scheduled_messages(DialogId dialog_id, vector<ScheduledServerMessageId> &&server_message_ids); - void on_update_created_public_broadcasts(vector<ChannelId> channel_ids); + void on_dialog_speaking_action(DialogId dialog_id, DialogId speaking_dialog_id, int32 date); - void on_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id, - DialogAction action, int32 date, - MessageContentType message_content_type = MessageContentType::None); + void on_message_animated_emoji_clicked(MessageFullId message_full_id, string &&emoji, string &&data); void read_history_inbox(DialogId dialog_id, MessageId max_message_id, int32 unread_count, const char *source); @@ -403,6 +386,8 @@ class MessagesManager final : public Actor { void delete_dialog_messages_by_sender(DialogId dialog_id, DialogId sender_dialog_id, Promise<Unit> &&promise); + static Status fix_delete_message_min_max_dates(int32 &min_date, int32 &max_date); + void delete_dialog_messages_by_date(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke, Promise<Unit> &&promise); @@ -420,13 +405,10 @@ class MessagesManager final : public Actor { void clear_recently_found_dialogs(); - std::pair<int32, vector<DialogId>> get_recently_opened_dialogs(int32 limit, Promise<Unit> &&promise); + std::pair<int32, vector<DialogId>> search_recently_found_dialogs(const string &query, int32 limit, + Promise<Unit> &&promise); - DialogId resolve_dialog_username(const string &username) const; - - DialogId search_public_dialog(const string &username_to_search, bool force, Promise<Unit> &&promise); - - void reload_voice_chat_on_search(const string &username); + std::pair<int32, vector<DialogId>> get_recently_opened_dialogs(int32 limit, Promise<Unit> &&promise); void get_dialog_send_message_as_dialog_ids(DialogId dialog_id, Promise<td_api::object_ptr<td_api::chatMessageSenders>> &&promise, @@ -441,104 +423,82 @@ class MessagesManager final : public Actor { 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); + struct ForwardedMessageInfo { + int32 origin_date_ = 0; + MessageOrigin origin_; + unique_ptr<MessageContent> content_; + }; + ForwardedMessageInfo get_forwarded_message_info(MessageFullId message_full_id); + + MessageInputReplyTo create_message_input_reply_to(DialogId dialog_id, MessageId top_thread_message_id, + td_api::object_ptr<td_api::InputMessageReplyTo> &&reply_to, + 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, + DialogId dialog_id, const MessageId top_thread_message_id, + td_api::object_ptr<td_api::InputMessageReplyTo> &&reply_to, tl_object_ptr<td_api::messageSendOptions> &&options, + tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, tl_object_ptr<td_api::InputMessageContent> &&input_message_content) TD_WARN_UNUSED_RESULT; Result<td_api::object_ptr<td_api::messages>> send_message_group( - DialogId dialog_id, MessageId top_thread_message_id, MessageId reply_to_message_id, - tl_object_ptr<td_api::messageSendOptions> &&options, - vector<tl_object_ptr<td_api::InputMessageContent>> &&input_message_contents, - bool only_preview) TD_WARN_UNUSED_RESULT; + DialogId dialog_id, const MessageId top_thread_message_id, + td_api::object_ptr<td_api::InputMessageReplyTo> &&reply_to, tl_object_ptr<td_api::messageSendOptions> &&options, + vector<tl_object_ptr<td_api::InputMessageContent>> &&input_message_contents) TD_WARN_UNUSED_RESULT; Result<MessageId> send_bot_start_message(UserId bot_user_id, DialogId dialog_id, const string ¶meter) TD_WARN_UNUSED_RESULT; - Result<MessageId> send_inline_query_result_message(DialogId dialog_id, MessageId top_thread_message_id, - MessageId reply_to_message_id, - tl_object_ptr<td_api::messageSendOptions> &&options, - int64 query_id, const string &result_id, - bool hide_via_bot) TD_WARN_UNUSED_RESULT; - - Result<td_api::object_ptr<td_api::messages>> forward_messages(DialogId to_dialog_id, MessageId top_thread_message_id, - DialogId from_dialog_id, vector<MessageId> message_ids, - tl_object_ptr<td_api::messageSendOptions> &&options, - bool in_game_share, - vector<MessageCopyOptions> &©_options, - bool only_preview) TD_WARN_UNUSED_RESULT; + Result<td_api::object_ptr<td_api::message>> send_inline_query_result_message( + DialogId dialog_id, const MessageId top_thread_message_id, + td_api::object_ptr<td_api::InputMessageReplyTo> &&reply_to, tl_object_ptr<td_api::messageSendOptions> &&options, + int64 query_id, const string &result_id, bool hide_via_bot) TD_WARN_UNUSED_RESULT; - Result<vector<MessageId>> resend_messages(DialogId dialog_id, vector<MessageId> message_ids) TD_WARN_UNUSED_RESULT; + Result<td_api::object_ptr<td_api::messages>> forward_messages( + DialogId to_dialog_id, MessageId top_thread_message_id, DialogId from_dialog_id, vector<MessageId> message_ids, + tl_object_ptr<td_api::messageSendOptions> &&options, bool in_game_share, + vector<MessageCopyOptions> &©_options) TD_WARN_UNUSED_RESULT; - void set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Promise<Unit> &&promise); + Result<td_api::object_ptr<td_api::messages>> send_quick_reply_shortcut_messages( + DialogId dialog_id, QuickReplyShortcutId shortcut_id, int32 sending_id) TD_WARN_UNUSED_RESULT; - Status send_screenshot_taken_notification_message(DialogId dialog_id); + Result<vector<MessageId>> resend_messages(DialogId dialog_id, vector<MessageId> message_ids, + td_api::object_ptr<td_api::inputTextQuote> &"e) TD_WARN_UNUSED_RESULT; - 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) - TD_WARN_UNUSED_RESULT; - - void get_message_file_type(const string &message_file_head, - Promise<td_api::object_ptr<td_api::MessageFileType>> &&promise); - - void get_message_import_confirmation_text(DialogId dialog_id, Promise<string> &&promise); + void set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Promise<Unit> &&promise); - void import_messages(DialogId dialog_id, const td_api::object_ptr<td_api::InputFile> &message_file, - const vector<td_api::object_ptr<td_api::InputFile>> &attached_files, Promise<Unit> &&promise); + void share_dialogs_with_bot(MessageFullId message_full_id, int32 button_id, vector<DialogId> shared_dialog_ids, + bool expect_user, bool only_check, Promise<Unit> &&promise); - void start_import_messages(DialogId dialog_id, int64 import_id, vector<FileId> &&attached_file_ids, - Promise<Unit> &&promise); + Result<MessageId> add_local_message( + DialogId dialog_id, td_api::object_ptr<td_api::MessageSender> &&sender, + td_api::object_ptr<td_api::InputMessageReplyTo> &&reply_to, bool disable_notification, + tl_object_ptr<td_api::InputMessageContent> &&input_message_content) TD_WARN_UNUSED_RESULT; - void edit_message_text(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, + void edit_message_text(MessageFullId message_full_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, tl_object_ptr<td_api::InputMessageContent> &&input_message_content, Promise<Unit> &&promise); - void edit_message_live_location(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, - tl_object_ptr<td_api::location> &&input_location, int32 heading, + void edit_message_live_location(MessageFullId message_full_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, + tl_object_ptr<td_api::location> &&input_location, int32 live_period, int32 heading, int32 proximity_alert_radius, Promise<Unit> &&promise); - void edit_message_media(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, + void edit_message_media(MessageFullId message_full_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, tl_object_ptr<td_api::InputMessageContent> &&input_message_content, Promise<Unit> &&promise); - void edit_message_caption(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, - tl_object_ptr<td_api::formattedText> &&input_caption, Promise<Unit> &&promise); - - void edit_message_reply_markup(FullMessageId full_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, - Promise<Unit> &&promise); - - void edit_inline_message_text(const string &inline_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, - tl_object_ptr<td_api::InputMessageContent> &&input_message_content, - Promise<Unit> &&promise); - - void edit_inline_message_live_location(const string &inline_message_id, - tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, - tl_object_ptr<td_api::location> &&input_location, int32 heading, - int32 proximity_alert_radius, Promise<Unit> &&promise); + void edit_message_caption(MessageFullId message_full_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, + tl_object_ptr<td_api::formattedText> &&input_caption, bool invert_media, + Promise<Unit> &&promise); - void edit_inline_message_media(const string &inline_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, - tl_object_ptr<td_api::InputMessageContent> &&input_message_content, + void edit_message_reply_markup(MessageFullId message_full_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, Promise<Unit> &&promise); - void edit_inline_message_caption(const string &inline_message_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, - tl_object_ptr<td_api::formattedText> &&input_caption, Promise<Unit> &&promise); - - void edit_inline_message_reply_markup(const string &inline_message_id, - tl_object_ptr<td_api::ReplyMarkup> &&reply_markup, Promise<Unit> &&promise); - - void edit_message_scheduling_state(FullMessageId full_message_id, + void edit_message_scheduling_state(MessageFullId message_full_id, td_api::object_ptr<td_api::MessageSchedulingState> &&scheduling_state, Promise<Unit> &&promise); - void send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogAction action, - Promise<Unit> &&promise); + void set_message_fact_check(MessageFullId message_full_id, td_api::object_ptr<td_api::formattedText> &&text, + Promise<Unit> &&promise); - void after_set_typing_query(DialogId dialog_id, int32 generation); + void get_dialog_filter_dialog_count(td_api::object_ptr<td_api::chatFolder> filter, Promise<int32> &&promise); void add_dialog_list_for_dialog_filter(DialogFilterId dialog_filter_id); @@ -552,44 +512,23 @@ class MessagesManager final : public Actor { void add_dialog_to_list(DialogId dialog_id, DialogListId dialog_list_id, Promise<Unit> &&promise); - void set_dialog_photo(DialogId dialog_id, const tl_object_ptr<td_api::InputChatPhoto> &input_photo, - Promise<Unit> &&promise); - - void set_dialog_title(DialogId dialog_id, const string &title, Promise<Unit> &&promise); - - void set_dialog_description(DialogId dialog_id, const string &description, Promise<Unit> &&promise); - - void set_active_reactions(vector<string> active_reactions); + void set_active_reactions(vector<ReactionType> active_reaction_types); void set_dialog_available_reactions(DialogId dialog_id, td_api::object_ptr<td_api::ChatAvailableReactions> &&available_reactions_ptr, Promise<Unit> &&promise); - void set_dialog_permissions(DialogId dialog_id, const td_api::object_ptr<td_api::chatPermissions> &permissions, - Promise<Unit> &&promise); - - void toggle_dialog_has_protected_content(DialogId dialog_id, bool has_protected_content, Promise<Unit> &&promise); - void set_dialog_theme(DialogId dialog_id, const string &theme_name, Promise<Unit> &&promise); - void pin_dialog_message(DialogId dialog_id, MessageId message_id, bool disable_notification, bool only_for_self, - bool is_unpin, Promise<Unit> &&promise); + void pin_dialog_message(BusinessConnectionId business_connection_id, DialogId dialog_id, MessageId message_id, + bool disable_notification, bool only_for_self, bool is_unpin, Promise<Unit> &&promise); void unpin_all_dialog_messages(DialogId dialog_id, MessageId top_thread_message_id, Promise<Unit> &&promise); - void get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise, const char *source); - - string get_dialog_title(DialogId dialog_id) const; - bool have_dialog(DialogId dialog_id) const; bool have_dialog_force(DialogId dialog_id, const char *source); - bool have_dialog_info(DialogId dialog_id) const; - bool have_dialog_info_force(DialogId dialog_id) const; - - void reload_dialog_info_full(DialogId dialog_id, const char *source); - - void on_dialog_info_full_invalidated(DialogId dialog_id); + void reload_dialog_notification_settings(DialogId dialog_id, Promise<Unit> &&promise, const char *source); bool load_dialog(DialogId dialog_id, int left_tries, Promise<Unit> &&promise); @@ -611,31 +550,31 @@ class MessagesManager final : public Actor { vector<DialogId> search_dialogs_on_server(const string &query, int32 limit, Promise<Unit> &&promise); - void drop_common_dialogs_cache(UserId user_id); - - std::pair<int32, vector<DialogId>> get_common_dialogs(UserId user_id, DialogId offset_dialog_id, int32 limit, - bool force, Promise<Unit> &&promise); - 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 get_blocked_dialogs(const td_api::object_ptr<td_api::BlockList> &block_list, 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, vector<tl_object_ptr<telegram_api::peerBlocked>> &&blocked_peers, Promise<td_api::object_ptr<td_api::messageSenders>> &&promise); - bool can_get_message_statistics(FullMessageId full_message_id); + static Status can_report_message(MessageId message_id); + + bool can_share_message_in_story(MessageFullId message_full_id); + + bool can_get_message_statistics(MessageFullId message_full_id); - DialogId get_dialog_message_sender(FullMessageId full_message_id); + DialogId get_dialog_message_sender(MessageFullId message_full_id); - bool have_message_force(FullMessageId full_message_id, const char *source); + bool have_message_force(MessageFullId message_full_id, const char *source); - void get_message(FullMessageId full_message_id, Promise<Unit> &&promise); + void get_message(MessageFullId message_full_id, Promise<Unit> &&promise); - FullMessageId get_replied_message(DialogId dialog_id, MessageId message_id, bool force, Promise<Unit> &&promise); + MessageFullId get_replied_message(DialogId dialog_id, MessageId message_id, bool force, Promise<Unit> &&promise); MessageId get_dialog_pinned_message(DialogId dialog_id, Promise<Unit> &&promise); @@ -644,12 +583,15 @@ class MessagesManager final : public Actor { bool get_messages(DialogId dialog_id, const vector<MessageId> &message_ids, Promise<Unit> &&promise); - void get_message_from_server(FullMessageId full_message_id, Promise<Unit> &&promise, const char *source, + void get_message_from_server(MessageFullId message_full_id, Promise<Unit> &&promise, const char *source, tl_object_ptr<telegram_api::InputMessage> input_message = nullptr); - void get_messages_from_server(vector<FullMessageId> &&message_ids, Promise<Unit> &&promise, const char *source, + void get_messages_from_server(vector<MessageFullId> &&message_ids, Promise<Unit> &&promise, const char *source, tl_object_ptr<telegram_api::InputMessage> input_message = nullptr); + void get_message_properties(DialogId dialog_id, MessageId message_id, + Promise<td_api::object_ptr<td_api::messageProperties>> &&promise); + void get_message_thread(DialogId dialog_id, MessageId message_id, Promise<MessageThreadInfo> &&promise); td_api::object_ptr<td_api::messageThreadInfo> get_message_thread_info_object(const MessageThreadInfo &info); @@ -658,33 +600,36 @@ 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, + void get_message_read_date(MessageFullId message_full_id, + Promise<td_api::object_ptr<td_api::MessageReadDate>> &&promise); + + void get_message_viewers(MessageFullId message_full_id, Promise<td_api::object_ptr<td_api::messageViewers>> &&promise); - void translate_message_text(FullMessageId full_message_id, const string &to_language_code, + void translate_message_text(MessageFullId message_full_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); + bool is_message_edited_recently(MessageFullId message_full_id, int32 seconds); - void rate_speech_recognition(FullMessageId full_message_id, bool is_good, Promise<Unit> &&promise); - - bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds); + struct ReportDialogFromActionBar { + bool know_action_bar_ = false; + bool is_reported_ = false; + }; + ReportDialogFromActionBar report_dialog_from_action_bar(DialogId dialog_id, Promise<Unit> &promise); bool is_deleted_secret_chat(DialogId dialog_id) const; - Result<std::pair<string, bool>> get_message_link(FullMessageId full_message_id, int32 media_timestamp, bool for_group, + Result<std::pair<string, bool>> get_message_link(MessageFullId message_full_id, int32 media_timestamp, bool for_group, bool in_message_thread); - string get_message_embedding_code(FullMessageId full_message_id, bool for_group, Promise<Unit> &&promise); + string get_message_embedding_code(MessageFullId message_full_id, bool for_group, Promise<Unit> &&promise); - void on_get_public_message_link(FullMessageId full_message_id, bool for_group, string url, string html); + void on_get_public_message_link(MessageFullId message_full_id, bool for_group, string url, string html); void get_message_link_info(Slice url, Promise<MessageLinkInfo> &&promise); td_api::object_ptr<td_api::messageLinkInfo> get_message_link_info_object(const MessageLinkInfo &info) const; - InputDialogId get_input_dialog_id(DialogId dialog_id) const; - bool is_dialog_in_dialog_list(DialogId dialog_id) const; Status can_add_dialog_to_filter(DialogId dialog_id); @@ -698,12 +643,14 @@ class MessagesManager final : public Actor { Status toggle_dialog_is_pinned(DialogListId dialog_list_id, DialogId dialog_id, bool is_pinned) TD_WARN_UNUSED_RESULT; + Status toggle_dialog_view_as_messages(DialogId dialog_id, bool view_as_messages) TD_WARN_UNUSED_RESULT; + 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; + Status set_message_sender_block_list(const td_api::object_ptr<td_api::MessageSender> &sender, + const td_api::object_ptr<td_api::BlockList> &block_list) TD_WARN_UNUSED_RESULT; Status toggle_dialog_silent_send_message(DialogId dialog_id, bool silent_send_message) TD_WARN_UNUSED_RESULT; @@ -713,17 +660,6 @@ 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, MessageTtl message_ttl, - 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); - - DialogId migrate_dialog_to_megagroup(DialogId dialog_id, Promise<Unit> &&promise); - bool is_dialog_opened(DialogId dialog_id) const; Status open_dialog(DialogId dialog_id) TD_WARN_UNUSED_RESULT; @@ -737,11 +673,13 @@ class MessagesManager final : public Actor { void finish_get_message_extended_media(DialogId dialog_id, const vector<MessageId> &message_ids); - Status open_message_content(FullMessageId full_message_id) TD_WARN_UNUSED_RESULT; + Status open_message_content(MessageFullId message_full_id) TD_WARN_UNUSED_RESULT; - void click_animated_emoji_message(FullMessageId full_message_id, + void click_animated_emoji_message(MessageFullId message_full_id, Promise<td_api::object_ptr<td_api::sticker>> &&promise); + StoryNotificationSettings get_story_notification_settings(DialogId dialog_id); + vector<DialogId> get_dialog_notification_settings_exceptions(NotificationSettingsScope scope, bool filter_scope, bool compare_sound, bool force, Promise<Unit> &&promise); @@ -751,17 +689,13 @@ class MessagesManager final : public Actor { void reset_all_notification_settings(); - 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; + void update_story_max_reply_media_timestamp_in_replied_messages(StoryFullId story_full_id); - td_api::object_ptr<td_api::chat> get_chat_object(DialogId dialog_id); + int64 get_chat_id_object(DialogId dialog_id, const char *source) const; - tl_object_ptr<td_api::chats> get_chats_object(int32 total_count, const vector<DialogId> &dialog_ids, - const char *source) const; + td_api::object_ptr<td_api::chat> get_chat_object(DialogId dialog_id, const char *source); - tl_object_ptr<td_api::chats> get_chats_object(const std::pair<int32, vector<DialogId>> &dialog_ids, - const char *source) const; + td_api::object_ptr<td_api::draftMessage> get_my_dialog_draft_message_object() 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, @@ -772,9 +706,9 @@ class MessagesManager final : public Actor { int32 limit, int64 &random_id, Promise<Unit> &&promise); - td_api::object_ptr<td_api::messageCalendar> get_dialog_message_calendar(DialogId dialog_id, MessageId from_message_id, - MessageSearchFilter filter, int64 &random_id, - bool use_db, Promise<Unit> &&promise); + void get_dialog_message_calendar(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, + Promise<td_api::object_ptr<td_api::messageCalendar>> &&promise); struct FoundDialogMessages { vector<MessageId> message_ids; @@ -789,10 +723,11 @@ class MessagesManager final : public Actor { const td_api::object_ptr<td_api::MessageSender> &sender, MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, + SavedMessagesTopicId saved_messages_topic_id, const ReactionType &tag, int64 &random_id, bool use_db, Promise<Unit> &&promise); struct FoundMessages { - vector<FullMessageId> full_message_ids; + vector<MessageFullId> message_full_ids; string next_offset; int32 total_count = 0; }; @@ -800,74 +735,93 @@ class MessagesManager final : public Actor { td_api::object_ptr<td_api::foundMessages> get_found_messages_object(const FoundMessages &found_messages, const char *source); - FoundMessages offline_search_messages(DialogId dialog_id, const string &query, string offset, int32 limit, - MessageSearchFilter filter, int64 &random_id, Promise<Unit> &&promise); + void offline_search_messages(DialogId dialog_id, const string &query, string offset, int32 limit, + MessageSearchFilter filter, + Promise<td_api::object_ptr<td_api::foundMessages>> &&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); + void search_messages(DialogListId dialog_list_id, bool ignore_folder_id, bool broadcasts_only, const string &query, + const string &offset_str, int32 limit, MessageSearchFilter filter, int32 min_date, + int32 max_date, Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); - FoundMessages search_call_messages(const string &offset, int32 limit, bool only_missed, int64 &random_id, bool use_db, - Promise<Unit> &&promise); + void search_call_messages(const string &offset, int32 limit, bool only_missed, + Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); void search_outgoing_document_messages(const string &query, int32 limit, Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); + void search_hashtag_posts(string hashtag, string offset_str, int32 limit, + Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); + void search_dialog_recent_location_messages(DialogId dialog_id, int32 limit, Promise<td_api::object_ptr<td_api::messages>> &&promise); - vector<FullMessageId> get_active_live_location_messages(Promise<Unit> &&promise); - - int64 get_dialog_message_by_date(DialogId dialog_id, int32 date, Promise<Unit> &&promise); + void load_active_live_location_messages(Promise<Unit> &&promise); - void on_get_dialog_message_by_date_success(DialogId dialog_id, int32 date, int64 random_id, - vector<tl_object_ptr<telegram_api::Message>> &&messages, - Promise<Unit> &&promise); + void get_dialog_message_by_date(DialogId dialog_id, int32 date, + Promise<td_api::object_ptr<td_api::message>> &&promise); - void on_get_dialog_message_by_date_fail(int64 random_id); + void on_get_dialog_message_by_date(DialogId dialog_id, int32 date, + vector<telegram_api::object_ptr<telegram_api::Message>> &&messages, + Promise<td_api::object_ptr<td_api::message>> &&promise); - void get_dialog_sparse_message_positions(DialogId dialog_id, MessageSearchFilter filter, MessageId from_message_id, - int32 limit, + void get_dialog_sparse_message_positions(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, MessageId from_message_id, int32 limit, Promise<td_api::object_ptr<td_api::messagePositions>> &&promise); - void on_get_dialog_sparse_message_positions( - DialogId dialog_id, MessageSearchFilter filter, + static void on_get_dialog_sparse_message_positions( + DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageSearchFilter filter, telegram_api::object_ptr<telegram_api::messages_searchResultsPositions> positions, Promise<td_api::object_ptr<td_api::messagePositions>> &&promise); - void get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, bool return_local, - Promise<int32> &&promise); + void get_dialog_message_count(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, bool return_local, Promise<int32> &&promise); - void get_dialog_message_position(FullMessageId full_message_id, MessageSearchFilter filter, - MessageId top_thread_message_id, Promise<int32> &&promise); + void get_dialog_message_position(MessageFullId message_full_id, MessageSearchFilter filter, + MessageId top_thread_message_id, SavedMessagesTopicId saved_messages_topic_id, + Promise<int32> &&promise); vector<MessageId> get_dialog_scheduled_messages(DialogId dialog_id, bool force, bool ignore_result, Promise<Unit> &&promise); - Result<td_api::object_ptr<td_api::availableReactions>> get_message_available_reactions(FullMessageId full_message_id, + using AffectedHistoryQuery = std::function<void(DialogId, Promise<AffectedHistory>)>; + + void run_affected_history_query_until_complete(DialogId dialog_id, AffectedHistoryQuery query, + bool get_affected_messages, Promise<Unit> &&promise); + + Result<td_api::object_ptr<td_api::availableReactions>> get_message_available_reactions(MessageFullId message_full_id, int32 row_size); - void add_message_reaction(FullMessageId full_message_id, string reaction, bool is_big, bool add_to_recent, + void add_message_reaction(MessageFullId message_full_id, ReactionType reaction_type, bool is_big, bool add_to_recent, Promise<Unit> &&promise); - void remove_message_reaction(FullMessageId full_message_id, string reaction, Promise<Unit> &&promise); + void remove_message_reaction(MessageFullId message_full_id, ReactionType reaction_type, Promise<Unit> &&promise); + + void add_paid_message_reaction(MessageFullId message_full_id, int64 star_count, bool use_default_is_anonymous, + bool is_anonymous, Promise<Unit> &&promise); - void get_message_public_forwards(FullMessageId full_message_id, string offset, int32 limit, - Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); + void commit_paid_message_reactions(MessageFullId message_full_id, Promise<Unit> &&promise); - tl_object_ptr<td_api::message> get_dialog_message_by_date_object(int64 random_id); + void remove_paid_message_reactions(MessageFullId message_full_id, Promise<Unit> &&promise); + + void toggle_paid_message_reaction_is_anonymous(MessageFullId message_full_id, bool is_anonymous, + Promise<Unit> &&promise); td_api::object_ptr<td_api::message> get_dialog_event_log_message_object( DialogId dialog_id, tl_object_ptr<telegram_api::Message> &&message, DialogId &sender_dialog_id); - tl_object_ptr<td_api::message> get_message_object(FullMessageId full_message_id, const char *source); + td_api::object_ptr<td_api::businessMessage> get_business_message_object( + telegram_api::object_ptr<telegram_api::Message> &&message, + telegram_api::object_ptr<telegram_api::Message> &&reply_to_message); + + td_api::object_ptr<td_api::message> get_message_object(MessageFullId message_full_id, const char *source); - tl_object_ptr<td_api::messages> get_messages_object(int32 total_count, DialogId dialog_id, - const vector<MessageId> &message_ids, bool skip_not_found, - const char *source); + td_api::object_ptr<td_api::messages> get_messages_object(int32 total_count, DialogId dialog_id, + const vector<MessageId> &message_ids, bool skip_not_found, + const char *source); - tl_object_ptr<td_api::messages> get_messages_object(int32 total_count, const vector<FullMessageId> &full_message_ids, - bool skip_not_found, const char *source); + td_api::object_ptr<td_api::messages> get_messages_object(int32 total_count, + const vector<MessageFullId> &message_full_ids, + bool skip_not_found, const char *source); void process_pts_update(tl_object_ptr<telegram_api::Update> &&update_ptr); @@ -883,7 +837,9 @@ class MessagesManager final : public Actor { void on_dialog_bots_updated(DialogId dialog_id, vector<UserId> bot_user_ids, bool from_database); void on_dialog_photo_updated(DialogId dialog_id); + void on_dialog_accent_colors_updated(DialogId dialog_id); void on_dialog_title_updated(DialogId dialog_id); + void on_dialog_emoji_status_updated(DialogId dialog_id); void on_dialog_usernames_updated(DialogId dialog_id, const Usernames &old_usernames, const Usernames &new_usernames); void on_dialog_default_permissions_updated(DialogId dialog_id); void on_dialog_has_protected_content_updated(DialogId dialog_id); @@ -896,17 +852,15 @@ class MessagesManager final : public Actor { void drop_dialog_pending_join_requests(DialogId dialog_id); - void on_resolved_username(const string &username, DialogId dialog_id); - void drop_username(const string &username); - void on_update_notification_scope_is_muted(NotificationSettingsScope scope, bool is_muted); void on_update_dialog_notify_settings(DialogId dialog_id, tl_object_ptr<telegram_api::peerNotifySettings> &&peer_notify_settings, const char *source); - void on_update_dialog_available_reactions( - DialogId dialog_id, telegram_api::object_ptr<telegram_api::ChatReactions> &&available_reactions); + void on_update_dialog_available_reactions(DialogId dialog_id, + telegram_api::object_ptr<telegram_api::ChatReactions> &&available_reactions, + int32 reactions_limit, bool paid_reactions_available); void hide_dialog_action_bar(DialogId dialog_id); @@ -914,10 +868,7 @@ class MessagesManager final : public Actor { void reget_dialog_action_bar(DialogId dialog_id, const char *source, bool is_repair = true); - void report_dialog(DialogId dialog_id, const vector<MessageId> &message_ids, ReportReason &&reason, - Promise<Unit> &&promise); - - void report_dialog_photo(DialogId dialog_id, FileId file_id, ReportReason &&reason, Promise<Unit> &&promise); + void hide_all_business_bot_manager_bars(); void on_get_peer_settings(DialogId dialog_id, tl_object_ptr<telegram_api::peerSettings> &&peer_settings, bool ignore_privacy_exception = false); @@ -928,38 +879,40 @@ class MessagesManager final : public Actor { void after_get_difference(); - bool on_get_dialog_error(DialogId dialog_id, const Status &status, const char *source); + bool on_get_message_error(DialogId dialog_id, MessageId message_id, const Status &status, const char *source); void on_send_message_get_quick_ack(int64 random_id); void check_send_message_result(int64 random_id, DialogId dialog_id, const telegram_api::Updates *updates_ptr, const char *source); - FullMessageId on_send_message_success(int64 random_id, MessageId new_message_id, int32 date, int32 ttl_period, + MessageFullId on_send_message_success(int64 random_id, MessageId new_message_id, int32 date, int32 ttl_period, FileId new_file_id, const char *source); - void on_send_message_file_part_missing(int64 random_id, int bad_part); + void on_send_message_file_parts_missing(int64 random_id, vector<int> &&bad_parts); - void on_send_message_file_reference_error(int64 random_id); + void on_send_message_file_reference_error(int64 random_id, size_t pos); void on_send_media_group_file_reference_error(DialogId dialog_id, vector<int64> random_ids); void on_send_message_fail(int64 random_id, Status error); - void on_upload_message_media_success(DialogId dialog_id, MessageId message_id, - tl_object_ptr<telegram_api::MessageMedia> &&media); + void on_upload_message_media_success(DialogId dialog_id, MessageId message_id, int32 media_pos, + telegram_api::object_ptr<telegram_api::MessageMedia> &&media); - void on_upload_message_media_file_part_missing(DialogId dialog_id, MessageId message_id, int bad_part); + void on_upload_message_media_file_parts_missing(DialogId dialog_id, MessageId message_id, int32 media_pos, + vector<int> &&bad_parts); - void on_upload_message_media_fail(DialogId dialog_id, MessageId message_id, Status error); + void on_upload_message_media_fail(DialogId dialog_id, MessageId message_id, int32 media_pos, Status error); - void on_create_new_dialog_success(int64 random_id, tl_object_ptr<telegram_api::Updates> &&updates, - DialogType expected_type, Promise<Unit> &&promise); - - void on_create_new_dialog_fail(int64 random_id, Status error, Promise<Unit> &&promise); + void on_create_new_dialog(telegram_api::object_ptr<telegram_api::Updates> &&updates, + MissingInvitees &&missing_invitees, + Promise<td_api::object_ptr<td_api::createdBasicGroupChat>> &&chat_promise, + Promise<td_api::object_ptr<td_api::chat>> &&channel_promise); void on_get_channel_difference(DialogId dialog_id, int32 request_pts, int32 request_limit, - tl_object_ptr<telegram_api::updates_ChannelDifference> &&difference_ptr); + tl_object_ptr<telegram_api::updates_ChannelDifference> &&difference_ptr, + Status &&status); void try_update_dialog_pos(DialogId dialog_id); @@ -974,7 +927,7 @@ class MessagesManager final : public Actor { vector<tl_object_ptr<telegram_api::User>> users, vector<tl_object_ptr<telegram_api::Chat>> chats); - FileSourceId get_message_file_source_id(FullMessageId full_message_id, bool force = false); + FileSourceId get_message_file_source_id(MessageFullId message_full_id, bool force = false); struct MessagePushNotificationInfo { NotificationGroupId group_id; @@ -987,13 +940,7 @@ class MessagesManager final : public Actor { bool is_from_scheduled, bool contains_mention, bool is_pinned, bool is_from_binlog); - struct MessageNotificationGroup { - DialogId dialog_id; - NotificationGroupType type = NotificationGroupType::Calls; - int32 total_count = 0; - vector<Notification> notifications; - }; - MessageNotificationGroup get_message_notification_group_force(NotificationGroupId group_id); + NotificationGroupFromDatabase get_message_notification_group_force(NotificationGroupId group_id); vector<NotificationGroupKey> get_message_notification_group_keys_from_database(NotificationGroupKey from_group_key, int32 limit); @@ -1013,33 +960,36 @@ class MessagesManager final : public Actor { void on_update_scope_mention_notifications(NotificationSettingsScope scope, bool disable_mention_notifications); - void upload_dialog_photo(DialogId dialog_id, FileId file_id, bool is_animation, double main_frame_timestamp, - bool is_reupload, Promise<Unit> &&promise, vector<int> bad_parts = {}); - void on_binlog_events(vector<BinlogEvent> &&events); - void set_poll_answer(FullMessageId full_message_id, vector<int32> &&option_ids, Promise<Unit> &&promise); + void set_poll_answer(MessageFullId message_full_id, vector<int32> &&option_ids, Promise<Unit> &&promise); - void get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit, - Promise<std::pair<int32, vector<UserId>>> &&promise); + void get_poll_voters(MessageFullId message_full_id, int32 option_id, int32 offset, int32 limit, + Promise<td_api::object_ptr<td_api::messageSenders>> &&promise); - void stop_poll(FullMessageId full_message_id, td_api::object_ptr<td_api::ReplyMarkup> &&reply_markup, + void stop_poll(MessageFullId message_full_id, td_api::object_ptr<td_api::ReplyMarkup> &&reply_markup, Promise<Unit> &&promise); - Result<string> get_login_button_url(FullMessageId full_message_id, int64 button_id); + Result<string> get_login_button_url(MessageFullId message_full_id, int64 button_id); + + struct InvoiceMessageInfo { + ServerMessageId server_message_id_; + int64 star_count_ = 0; + }; + Result<InvoiceMessageInfo> get_invoice_message_info(MessageFullId message_full_id); - Result<ServerMessageId> get_invoice_message_id(FullMessageId full_message_id); + Result<ServerMessageId> get_payment_successful_message_id(MessageFullId message_full_id); - Result<ServerMessageId> get_payment_successful_message_id(FullMessageId full_message_id); + Result<ServerMessageId> get_giveaway_message_id(MessageFullId message_full_id); - bool can_set_game_score(FullMessageId full_message_id) const; + bool can_set_game_score(MessageFullId message_full_id) const; void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const; - void add_message_file_to_downloads(FullMessageId full_message_id, FileId file_id, int32 priority, + void add_message_file_to_downloads(MessageFullId message_full_id, FileId file_id, int32 priority, Promise<td_api::object_ptr<td_api::file>> promise); - void get_message_file_search_text(FullMessageId full_message_id, string unique_file_id, Promise<string> promise); + void get_message_file_search_text(MessageFullId message_full_id, string unique_file_id, Promise<string> promise); private: class PendingPtsUpdate { @@ -1059,114 +1009,75 @@ class MessagesManager final : public Actor { MessageId message_id; UserId sender_user_id; DialogId sender_dialog_id; + SavedMessagesTopicId saved_messages_topic_id; int32 date = 0; int32 ttl_period = 0; - int32 ttl = 0; + MessageSelfDestructType ttl; bool disable_web_page_preview = false; int64 random_id = 0; tl_object_ptr<telegram_api::messageFwdHeader> forward_header; MessageReplyHeader reply_header; UserId via_bot_user_id; + UserId via_business_bot_user_id; int32 view_count = 0; int32 forward_count = 0; tl_object_ptr<telegram_api::messageReplies> reply_info; tl_object_ptr<telegram_api::messageReactions> reactions; - int32 flags = 0; + tl_object_ptr<telegram_api::factCheck> fact_check; + int32 sender_boost_count = 0; int32 edit_date = 0; vector<RestrictionReason> restriction_reasons; string author_signature; int64 media_album_id = 0; + MessageEffectId effect_id; + bool is_outgoing = false; + bool is_silent = false; + bool is_channel_post = false; + bool is_legacy = false; + bool hide_edit_date = false; + bool is_from_scheduled = false; + bool is_from_offline = false; + bool is_pinned = false; + bool noforwards = false; + bool has_mention = false; + bool has_unread_content = false; + bool invert_media = false; unique_ptr<MessageContent> content; tl_object_ptr<telegram_api::ReplyMarkup> reply_markup; }; - struct MessageForwardInfo { - UserId sender_user_id; - int32 date = 0; - DialogId sender_dialog_id; - MessageId message_id; - string author_signature; - string sender_name; - DialogId from_dialog_id; - MessageId from_message_id; - string psa_type; - bool is_imported = false; - - MessageForwardInfo() = default; - - MessageForwardInfo(UserId sender_user_id, int32 date, DialogId sender_dialog_id, MessageId message_id, - string author_signature, string sender_name, DialogId from_dialog_id, MessageId from_message_id, - string psa_type, bool is_imported) - : sender_user_id(sender_user_id) - , date(date) - , sender_dialog_id(sender_dialog_id) - , message_id(message_id) - , author_signature(std::move(author_signature)) - , sender_name(std::move(sender_name)) - , from_dialog_id(from_dialog_id) - , from_message_id(from_message_id) - , psa_type(std::move(psa_type)) - , is_imported(is_imported) { - } - - bool operator==(const MessageForwardInfo &rhs) const { - return sender_user_id == rhs.sender_user_id && date == rhs.date && sender_dialog_id == rhs.sender_dialog_id && - message_id == rhs.message_id && author_signature == rhs.author_signature && - sender_name == rhs.sender_name && from_dialog_id == rhs.from_dialog_id && - from_message_id == rhs.from_message_id && psa_type == rhs.psa_type && is_imported == rhs.is_imported; - } - - bool operator!=(const MessageForwardInfo &rhs) const { - return !(*this == rhs); - } - - friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageForwardInfo &forward_info) { - string_builder << "MessageForwardInfo[" << (forward_info.is_imported ? "imported " : "") << "sender " - << forward_info.sender_user_id; - if (!forward_info.author_signature.empty() || !forward_info.sender_name.empty()) { - string_builder << '(' << forward_info.author_signature << '/' << forward_info.sender_name << ')'; - } - if (!forward_info.psa_type.empty()) { - string_builder << ", psa_type " << forward_info.psa_type; - } - if (forward_info.sender_dialog_id.is_valid()) { - string_builder << ", source "; - if (forward_info.message_id.is_valid()) { - string_builder << FullMessageId(forward_info.sender_dialog_id, forward_info.message_id); - } else { - string_builder << forward_info.sender_dialog_id; - } - } - if (forward_info.from_dialog_id.is_valid() || forward_info.from_message_id.is_valid()) { - string_builder << ", from " << FullMessageId(forward_info.from_dialog_id, forward_info.from_message_id); - } - return string_builder << " at " << forward_info.date << ']'; - } - }; - // Do not forget to update MessagesManager::update_message and all make_unique<Message> when this class is changed struct Message final : public ListNode { MessageId message_id; UserId sender_user_id; DialogId sender_dialog_id; + SavedMessagesTopicId saved_messages_topic_id; int32 date = 0; int32 edit_date = 0; int32 send_date = 0; - int32 sending_id = 0; + int32 sending_id = 0; // for yet unsent messages + int32 sender_boost_count = 0; int64 random_id = 0; unique_ptr<MessageForwardInfo> forward_info; - MessageId reply_to_message_id; - int64 reply_to_random_id = 0; // for send_message - DialogId reply_in_dialog_id; + RepliedMessageInfo replied_message_info; + StoryFullId reply_to_story_full_id; + MessageId top_thread_message_id; MessageId linked_top_thread_message_id; vector<MessageId> local_thread_message_ids; + DialogId initial_sender_dialog_id; // for send_message + MessageId initial_top_thread_message_id; // for send_message + MessageInputReplyTo input_reply_to; // for send_message + int64 reply_to_random_id = 0; // for send_message + string send_emoji; // for send_message + UserId via_bot_user_id; + UserId via_business_bot_user_id; vector<RestrictionReason> restriction_reasons; @@ -1185,15 +1096,17 @@ class MessagesManager final : public Actor { bool is_content_secret = false; // must be shown only while tapped bool is_mention_notification_disabled = false; bool is_from_scheduled = false; + bool is_from_offline = false; bool is_pinned = false; bool are_media_timestamp_entities_found = false; bool noforwards = false; + bool invert_media = false; + bool disable_web_page_preview = false; bool has_explicit_sender = false; // for send_message bool is_copy = false; // for send_message bool from_background = false; // for send_message bool update_stickersets_order = false; // for send_message - bool disable_web_page_preview = false; // for send_message bool clear_draft = false; // for send_message bool in_game_share = false; // for send_message bool hide_via_bot = false; // for resend_message @@ -1207,8 +1120,6 @@ class MessagesManager final : public Actor { DialogId real_forward_from_dialog_id; // for resend_message MessageId real_forward_from_message_id; // for resend_message - string send_emoji; // for send_message - NotificationId notification_id; NotificationId removed_notification_id; @@ -1219,6 +1130,7 @@ class MessagesManager final : public Actor { int32 forward_count = 0; MessageReplyInfo reply_info; unique_ptr<MessageReactions> reactions; + unique_ptr<FactCheck> fact_check; unique_ptr<DraftMessage> thread_draft_message; uint32 available_reactions_generation = 0; int32 interaction_info_update_date = 0; @@ -1230,17 +1142,19 @@ class MessagesManager final : public Actor { string send_error_message; double try_resend_at = 0; - int32 ttl_period = 0; // counted from message send date - int32 ttl = 0; // counted from message content view date - double ttl_expires_at = 0; // only for TTL + int32 ttl_period = 0; // counted from message send date + MessageSelfDestructType ttl; // counted from message content view date + double ttl_expires_at = 0; // only for TTL int64 media_album_id = 0; + MessageEffectId effect_id; unique_ptr<MessageContent> content; unique_ptr<ReplyMarkup> reply_markup; int32 edited_schedule_date = 0; + bool edited_invert_media = false; unique_ptr<MessageContent> edited_content; unique_ptr<ReplyMarkup> edited_reply_markup; uint64 edit_generation = 0; @@ -1271,22 +1185,6 @@ class MessagesManager final : public Actor { ~Message() = default; }; - struct NotificationGroupInfo { - NotificationGroupId group_id; - int32 last_notification_date = 0; // date of last notification in the group - NotificationId last_notification_id; // identifier of last notification in the group - NotificationId max_removed_notification_id; // notification identifier, up to which all notifications are removed - MessageId max_removed_message_id; // message identifier, up to which all notifications are removed - bool is_changed = false; // true, if the group needs to be saved to database - bool try_reuse = false; // true, if the group needs to be deleted from database and tried to be reused - - template <class StorerT> - void store(StorerT &storer) const; - - template <class ParserT> - void parse(ParserT &parser); - }; - struct DialogScheduledMessages { FlatHashMap<ScheduledServerMessageId, int32, ScheduledServerMessageIdHash> scheduled_message_date_; @@ -1302,7 +1200,7 @@ class MessagesManager final : public Actor { NotificationGroupInfo mention_notification_group_; NotificationId new_secret_chat_notification_id_; // secret chats only MessageId pinned_message_notification_message_id_; - MessageId max_notification_message_id_; + MessageId max_push_notification_message_id_; vector<std::pair<DialogId, MessageId>> pending_new_message_notifications_; vector<std::pair<DialogId, MessageId>> pending_new_mention_notifications_; @@ -1341,6 +1239,7 @@ class MessagesManager final : public Actor { MessageTtl message_ttl; unique_ptr<DraftMessage> draft_message; unique_ptr<DialogActionBar> action_bar; + unique_ptr<BusinessBotManageBar> business_bot_manage_bar; LogEventIdWithGeneration save_draft_message_log_event_id; LogEventIdWithGeneration save_notification_settings_log_event_id; LogEventIdWithGeneration set_folder_id_log_event_id; @@ -1368,13 +1267,12 @@ class MessagesManager final : public Actor { MessageId max_unavailable_message_id; // maximum unavailable message identifier for dialogs with cleared/unavailable history - int32 last_clear_history_date = 0; - MessageId last_clear_history_message_id; int64 order = DEFAULT_ORDER; + int64 pending_order = DEFAULT_ORDER; MessageId deleted_last_message_id; int32 delete_last_message_date = 0; - int32 pending_last_message_date = 0; - MessageId pending_last_message_id; + int32 last_clear_history_date = 0; + MessageId last_clear_history_message_id; MessageId last_edited_message_id; uint32 scheduled_messages_sync_generation = 0; uint32 last_repair_scheduled_messages_generation = 0; @@ -1394,6 +1292,7 @@ class MessagesManager final : public Actor { bool has_outgoing_messages = false; bool was_opened = false; + bool need_unload_on_close = false; bool need_restore_reply_markup = true; bool need_drop_default_send_message_as_dialog_id = false; @@ -1407,9 +1306,13 @@ class MessagesManager final : public Actor { bool is_folder_id_inited = false; bool need_repair_server_unread_count = false; bool need_repair_channel_server_unread_count = false; + bool is_forum = false; + bool view_as_messages = false; bool is_marked_as_unread = false; bool is_blocked = false; bool is_is_blocked_inited = false; + bool is_blocked_for_stories = false; + bool is_is_blocked_for_stories_inited = false; bool last_sent_has_scheduled_messages = false; bool has_scheduled_server_messages = false; bool has_scheduled_database_messages = false; @@ -1422,6 +1325,8 @@ class MessagesManager final : public Actor { bool is_message_ttl_inited = false; bool has_expected_active_group_call_id = false; bool has_bots = false; + bool is_view_as_messages_inited = false; + bool is_saved_messages_view_as_messages_inited = false; bool is_has_bots_inited = false; bool is_background_inited = false; bool is_theme_name_inited = false; @@ -1440,8 +1345,7 @@ class MessagesManager final : public Actor { int32 pending_read_channel_inbox_pts = 0; // for channels only int32 pending_read_channel_inbox_server_unread_count = 0; // for channels only MessageId pending_read_channel_inbox_max_message_id; // for channels only - std::unordered_map<int64, MessageId, Hash<int64>> - random_id_to_message_id; // for secret chats and yet unsent messages only + FlatHashMap<int64, MessageId> random_id_to_message_id; // for secret chats and yet unsent messages only MessageId last_assigned_message_id; // identifier of the last local or yet unsent message, assigned after // application start, used to guarantee that all assigned message identifiers @@ -1494,6 +1398,7 @@ class MessagesManager final : public Actor { int32 in_memory_dialog_total_count_ = 0; int32 server_dialog_total_count_ = -1; int32 secret_chat_total_count_ = -1; + int64 unique_id_ = 0; vector<Promise<Unit>> load_list_queries_; @@ -1608,18 +1513,23 @@ class MessagesManager final : public Actor { bool from_background = false; bool update_stickersets_order = false; bool protect_content = false; + bool only_preview = false; int32 schedule_date = 0; int32 sending_id = 0; + MessageEffectId effect_id; MessageSendOptions() = default; MessageSendOptions(bool disable_notification, bool from_background, bool update_stickersets_order, - bool protect_content, int32 schedule_date, int32 sending_id) + bool protect_content, bool only_preview, int32 schedule_date, int32 sending_id, + MessageEffectId effect_id) : disable_notification(disable_notification) , from_background(from_background) , update_stickersets_order(update_stickersets_order) , protect_content(protect_content) + , only_preview(only_preview) , schedule_date(schedule_date) - , sending_id(sending_id) { + , sending_id(sending_id) + , effect_id(effect_id) { } }; @@ -1633,6 +1543,34 @@ class MessagesManager final : public Actor { vector<std::pair<Promise<Unit>, std::function<bool(const Message *)>>> suffix_load_queries_; }; + struct PendingGetHistoryQuery { + DialogId dialog_id_; + MessageId from_message_id_; + MessageId old_last_message_id_; + int32 offset_ = 0; + int32 limit_ = 0; + bool from_database_ = false; + bool only_local_ = false; + + bool operator==(const PendingGetHistoryQuery &other) const { + return dialog_id_ == other.dialog_id_ && from_message_id_ == other.from_message_id_ && + old_last_message_id_ == other.old_last_message_id_ && offset_ == other.offset_ && limit_ == other.limit_ && + from_database_ == other.from_database_ && only_local_ == other.only_local_; + } + }; + struct PendingGetHistoryQueryHash { + uint32 operator()(const PendingGetHistoryQuery &query) const { + uint32 hash = DialogIdHash()(query.dialog_id_); + hash = combine_hashes(hash, MessageIdHash()(query.from_message_id_)); + hash = combine_hashes(hash, MessageIdHash()(query.old_last_message_id_)); + hash = combine_hashes(hash, Hash<int32>()(query.offset_)); + hash = combine_hashes(hash, Hash<int32>()(query.limit_)); + hash = combine_hashes(hash, static_cast<uint32>(query.from_database_)); + hash = combine_hashes(hash, static_cast<uint32>(query.only_local_)); + return hash; + } + }; + class BlockMessageSenderFromRepliesOnServerLogEvent; class DeleteAllCallMessagesOnServerLogEvent; class DeleteAllChannelMessagesFromSenderOnServerLogEvent; @@ -1657,9 +1595,11 @@ class MessagesManager final : public Actor { class SendBotStartMessageLogEvent; class SendInlineQueryResultMessageLogEvent; class SendMessageLogEvent; + class SendQuickReplyShortcutMessagesLogEvent; class SendScreenshotTakenNotificationMessageLogEvent; class SetDialogFolderIdOnServerLogEvent; class ToggleDialogIsBlockedOnServerLogEvent; + class ToggleDialogViewAsMessagesOnServerLogEvent; class ToggleDialogIsMarkedAsUnreadOnServerLogEvent; class ToggleDialogIsTranslatableOnServerLogEvent; class ToggleDialogIsPinnedOnServerLogEvent; @@ -1676,10 +1616,7 @@ class MessagesManager final : public Actor { 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 int32 MAX_PRIVATE_MESSAGE_TTL = 60; // server side limit - static constexpr size_t MIN_DELETED_ASYNCHRONOUSLY_MESSAGES = 10; + static constexpr size_t MIN_DELETED_ASYNCHRONOUSLY_MESSAGES = 2; static constexpr size_t MAX_UNLOADED_MESSAGES = 5000; static constexpr int64 SPONSORED_DIALOG_ORDER = static_cast<int64>(2147483647) << 32; @@ -1705,27 +1642,20 @@ class MessagesManager final : public Actor { static constexpr int32 LIVE_LOCATION_VIEW_PERIOD = 60; // seconds, server-side limit static constexpr int32 UPDATE_VIEWED_MESSAGES_PERIOD = 15; // seconds - static constexpr int32 USERNAME_CACHE_EXPIRE_TIME = 86400; static constexpr int32 AUTH_NOTIFICATION_ID_CACHE_TIME = 7 * 86400; static constexpr size_t MAX_SAVED_AUTH_NOTIFICATION_IDS = 100; - static constexpr int32 ONLINE_MEMBER_COUNT_UPDATE_TIME = 5 * 60; - static constexpr int32 MAX_RESEND_DELAY = 86400; // seconds, some resonable limit static constexpr int32 SCHEDULE_WHEN_ONLINE_DATE = 2147483646; - static constexpr double DIALOG_ACTION_TIMEOUT = 5.5; - static constexpr const char *DELETE_MESSAGE_USER_REQUEST_SOURCE = "user request"; static constexpr bool DROP_SEND_MESSAGE_UPDATES = false; - static int32 get_message_date(const tl_object_ptr<telegram_api::Message> &message_ptr); - - static vector<UserId> get_message_user_ids(const Message *m); + vector<UserId> get_message_user_ids(const Message *m) const; - static vector<ChannelId> get_message_channel_ids(const Message *m); + vector<ChannelId> get_message_channel_ids(const Message *m) const; static bool is_dialog_inited(const Dialog *d); @@ -1747,8 +1677,6 @@ class MessagesManager final : public Actor { void close_dialog(Dialog *d); - DialogId get_my_dialog_id() const; - void on_resolve_secret_chat_message_via_bot_username(const string &via_bot_username, MessageInfo *message_info_ptr, Promise<Unit> &&promise); @@ -1763,50 +1691,56 @@ class MessagesManager final : public Actor { void finish_delete_secret_chat_history(DialogId dialog_id, bool remove_from_dialog_list, MessageId last_message_id, Promise<Unit> promise); - MessageInfo parse_telegram_api_message(tl_object_ptr<telegram_api::Message> message_ptr, bool is_scheduled, - const char *source) const; + static MessageInfo parse_telegram_api_message(Td *td, tl_object_ptr<telegram_api::Message> message_ptr, + bool is_scheduled, bool is_business_message, const char *source); - std::pair<DialogId, unique_ptr<Message>> create_message(MessageInfo &&message_info, bool is_channel_message); + static std::pair<DialogId, unique_ptr<Message>> create_message(Td *td, MessageInfo &&message_info, + bool is_channel_message, bool is_business_message, + const char *source); MessageId find_old_message_id(DialogId dialog_id, MessageId message_id) const; void delete_update_message_id(DialogId dialog_id, MessageId message_id); - void get_dialog_message_count_from_server(DialogId dialog_id, MessageSearchFilter filter, Promise<int32> &&promise); + void get_dialog_message_count_from_server(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, Promise<int32> &&promise); - FullMessageId on_get_message(MessageInfo &&message_info, const bool from_update, const bool is_channel_message, + MessageFullId 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); + DialogId dialog_id, tl_object_ptr<td_api::InputMessageContent> &&input_message_content, + bool check_permissions = true); Result<MessageCopyOptions> process_message_copy_options(DialogId dialog_id, tl_object_ptr<td_api::messageCopyOptions> &&options) const; Result<MessageSendOptions> process_message_send_options(DialogId dialog_id, tl_object_ptr<td_api::messageSendOptions> &&options, - bool allow_update_stickersets_order) const; + bool allow_update_stickersets_order, bool allow_effect) const; static Status can_use_message_send_options(const MessageSendOptions &options, - const unique_ptr<MessageContent> &content, int32 ttl); + const unique_ptr<MessageContent> &content, MessageSelfDestructType 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); - - bool is_anonymous_administrator(DialogId dialog_id, string *author_signature) const; + Status can_use_top_thread_message_id(Dialog *d, MessageId top_thread_message_id, + const MessageInputReplyTo &input_reply_to); int64 generate_new_random_id(const Dialog *d); - unique_ptr<Message> create_message_to_send(Dialog *d, MessageId top_thread_message_id, MessageId reply_to_message_id, - const MessageSendOptions &options, unique_ptr<MessageContent> &&content, + unique_ptr<Message> create_message_to_send(Dialog *d, MessageId top_thread_message_id, + MessageInputReplyTo &&input_reply_to, const MessageSendOptions &options, + unique_ptr<MessageContent> &&content, bool invert_media, bool suppress_reply_info, unique_ptr<MessageForwardInfo> forward_info, - bool is_copy, DialogId send_as_dialog_id) const; + DialogId real_forward_from_dialog_id, bool is_copy, + DialogId send_as_dialog_id) const; - Message *get_message_to_send(Dialog *d, MessageId top_thread_message_id, MessageId reply_to_message_id, + Message *get_message_to_send(Dialog *d, MessageId top_thread_message_id, MessageInputReplyTo &&input_reply_to, const MessageSendOptions &options, unique_ptr<MessageContent> &&content, - bool *need_update_dialog_pos, bool suppress_reply_info = false, - unique_ptr<MessageForwardInfo> forward_info = nullptr, bool is_copy = false, + bool invert_media, bool *need_update_dialog_pos, bool suppress_reply_info = false, + unique_ptr<MessageForwardInfo> forward_info = nullptr, + DialogId real_forward_from_dialog_id = DialogId(), bool is_copy = false, DialogId sender_dialog_id = DialogId()); int64 begin_send_message(DialogId dialog_id, const Message *m); @@ -1817,17 +1751,19 @@ class MessagesManager final : public Actor { bool can_edit_message(DialogId dialog_id, const Message *m, bool is_editing, bool only_reply_markup = false) const; - bool has_qts_messages(DialogId dialog_id) const; - - bool can_report_dialog(DialogId dialog_id) const; - - Status can_pin_messages(DialogId dialog_id) const; + Status can_pin_message(DialogId dialog_id, const Message *m) const TD_WARN_UNUSED_RESULT; static Status can_get_media_timestamp_link(DialogId dialog_id, const Message *m); bool can_report_message_reactions(DialogId dialog_id, const Message *m) const; - Status can_get_message_viewers(FullMessageId full_message_id) TD_WARN_UNUSED_RESULT; + bool can_recognize_message_speech(DialogId dialog_id, const Message *m) const; + + bool can_set_message_fact_check(DialogId dialog_id, const Message *m) const; + + Status can_get_message_read_date(DialogId dialog_id, const Message *m) const TD_WARN_UNUSED_RESULT; + + Status can_get_message_viewers(MessageFullId message_full_id) TD_WARN_UNUSED_RESULT; Status can_get_message_viewers(DialogId dialog_id, const Message *m) const TD_WARN_UNUSED_RESULT; @@ -1839,12 +1775,13 @@ class MessagesManager final : public Actor { MessageId get_persistent_message_id(const Dialog *d, MessageId message_id) const; - static FullMessageId get_replied_message_id(DialogId dialog_id, const Message *m); + static MessageFullId get_replied_message_id(DialogId dialog_id, const Message *m); - MessageId get_reply_to_message_id(Dialog *d, MessageId top_thread_message_id, MessageId message_id, bool for_draft); + MessageInputReplyTo create_message_input_reply_to(Dialog *d, MessageId top_thread_message_id, + td_api::object_ptr<td_api::InputMessageReplyTo> &&reply_to, + bool for_draft); - void fix_server_reply_to_message_id(DialogId dialog_id, MessageId message_id, DialogId reply_in_dialog_id, - MessageId &reply_to_message_id) const; + static const MessageInputReplyTo *get_message_input_reply_to(const Message *m); bool can_set_game_score(DialogId dialog_id, const Message *m) const; @@ -1853,9 +1790,9 @@ class MessagesManager final : public Actor { bool process_channel_update(tl_object_ptr<telegram_api::Update> &&update_ptr); - void on_message_edited(FullMessageId full_message_id, int32 pts, bool had_message); + void on_message_edited(MessageFullId message_full_id, int32 pts, bool had_message); - void delete_messages_from_updates(const vector<MessageId> &message_ids); + void delete_messages_from_updates(const vector<MessageId> &message_ids, bool is_permanent); void delete_dialog_messages(DialogId dialog_id, const vector<MessageId> &message_ids, bool force_update_for_not_found_messages, const char *source); @@ -1872,7 +1809,19 @@ class MessagesManager final : public Actor { const vector<MessageId> &message_ids, bool drop_author, bool drop_media_captions, uint64 log_event_id); - void send_forward_message_query(int32 flags, DialogId to_dialog_id, MessageId top_thread_message_id, + uint64 save_send_quick_reply_shortcut_messages_log_event(DialogId dialog_id, QuickReplyShortcutId shortcut_id, + const vector<Message *> &messages, + const vector<MessageId> &message_ids); + + void do_send_quick_reply_shortcut_messages(DialogId dialog_id, QuickReplyShortcutId shortcut_id, + const vector<Message *> &messages, const vector<MessageId> &message_ids, + uint64 log_event_id); + + void send_send_quick_reply_messages_query(DialogId dialog_id, QuickReplyShortcutId shortcut_id, + vector<MessageId> message_ids, vector<int64> random_ids, + Promise<Unit> promise); + + void send_forward_message_query(int32 flags, DialogId to_dialog_id, const MessageId top_thread_message_id, DialogId from_dialog_id, tl_object_ptr<telegram_api::InputPeer> as_input_peer, vector<MessageId> message_ids, vector<int64> random_ids, int32 schedule_date, Promise<Unit> promise); @@ -1883,8 +1832,10 @@ class MessagesManager final : public Actor { bool in_game_share, MessageCopyOptions &©_options) TD_WARN_UNUSED_RESULT; + MessageOrigin get_forwarded_message_origin(DialogId dialog_id, const Message *m) const; + unique_ptr<MessageForwardInfo> create_message_forward_info(DialogId from_dialog_id, DialogId to_dialog_id, - const Message *forwarded_message) const; + const Message *m) const; void fix_forwarded_message(Message *m, DialogId to_dialog_id, const Message *forwarded_message, int64 media_album_id, bool drop_author) const; @@ -1892,18 +1843,20 @@ class MessagesManager final : public Actor { struct ForwardedMessages { struct CopiedMessage { unique_ptr<MessageContent> content; - MessageId reply_to_message_id; + MessageInputReplyTo input_reply_to; MessageId original_message_id; MessageId original_reply_to_message_id; unique_ptr<ReplyMarkup> reply_markup; int64 media_album_id; bool disable_web_page_preview; + bool invert_media; size_t index; }; vector<CopiedMessage> copied_messages; struct ForwardedMessageContent { unique_ptr<MessageContent> content; + bool invert_media; int64 media_album_id; size_t index; }; @@ -1922,27 +1875,30 @@ class MessagesManager final : public Actor { td_api::object_ptr<td_api::messageSendOptions> &&options, bool in_game_share, vector<MessageCopyOptions> &©_options); - void do_send_media(DialogId dialog_id, Message *m, FileId file_id, FileId thumbnail_file_id, + void do_send_media(DialogId dialog_id, const Message *m, int32 media_pos, FileId file_id, FileId thumbnail_file_id, tl_object_ptr<telegram_api::InputFile> input_file, tl_object_ptr<telegram_api::InputFile> input_thumbnail); - void do_send_secret_media(DialogId dialog_id, Message *m, FileId file_id, FileId thumbnail_file_id, + void do_send_secret_media(DialogId dialog_id, const Message *m, FileId file_id, FileId thumbnail_file_id, tl_object_ptr<telegram_api::InputEncryptedFile> input_encrypted_file, BufferSlice thumbnail); - void do_send_message(DialogId dialog_id, const Message *m, vector<int> bad_parts = {}); + void do_send_message(DialogId dialog_id, const Message *m, int32 media_pos = -1, vector<int> bad_parts = {}); - void on_message_media_uploaded(DialogId dialog_id, const Message *m, - tl_object_ptr<telegram_api::InputMedia> &&input_media, FileId file_id, - FileId thumbnail_file_id); + void on_message_media_uploaded(DialogId dialog_id, const Message *m, int32 media_pos, + telegram_api::object_ptr<telegram_api::InputMedia> &&input_media, + vector<FileId> file_ids, vector<FileId> thumbnail_file_ids); void on_secret_message_media_uploaded(DialogId dialog_id, const Message *m, SecretInputMedia &&secret_input_media, FileId file_id, FileId thumbnail_file_id); - void on_upload_message_media_finished(int64 media_album_id, DialogId dialog_id, MessageId message_id, Status result); + void on_upload_message_media_finished(int64 media_album_id, DialogId dialog_id, MessageId message_id, int32 media_pos, + Status result); void do_send_message_group(int64 media_album_id); + void do_send_paid_media_group(DialogId dialog_id, MessageId message_id); + void on_text_message_ready_to_send(DialogId dialog_id, MessageId message_id); void on_media_message_ready_to_send(DialogId dialog_id, MessageId message_id, Promise<Message *> &&promise); @@ -1962,10 +1918,17 @@ class MessagesManager final : public Actor { void do_send_inline_query_result_message(DialogId dialog_id, MessageId message_id, int64 query_id, const string &result_id); + void send_screenshot_taken_notification_message(Dialog *d); + static uint64 save_send_screenshot_taken_notification_message_log_event(DialogId dialog_id, const Message *m); void do_send_screenshot_taken_notification_message(DialogId dialog_id, const Message *m, uint64 log_event_id); + void set_message_reply(const Dialog *d, Message *m, MessageInputReplyTo input_reply_to, bool is_message_in_dialog); + + void update_message_reply_to_message_id(const Dialog *d, Message *m, MessageId reply_to_message_id, + bool is_message_in_dialog); + void restore_message_reply_to_message_id(Dialog *d, Message *m); Message *continue_send_message(DialogId dialog_id, unique_ptr<Message> &&message, bool *need_update_dialog_pos, @@ -1979,8 +1942,12 @@ class MessagesManager final : public Actor { bool can_save_message(DialogId dialog_id, const Message *m) const; + bool can_share_message_in_story(DialogId dialog_id, const Message *m) const; + bool can_get_message_statistics(DialogId dialog_id, const Message *m) const; + Status can_get_message_embedding_code(DialogId dialog_id, const Message *m) const; + struct CanDeleteDialog { bool for_self_; bool for_all_users_; @@ -2019,7 +1986,7 @@ class MessagesManager final : public Actor { double get_next_unload_dialog_delay(Dialog *d) const; - void unload_dialog(DialogId dialog_id); + void unload_dialog(DialogId dialog_id, int32 delay); void clear_dialog_message_list(Dialog *d, bool remove_from_dialog_list, int32 last_message_date); @@ -2059,11 +2026,6 @@ class MessagesManager final : public Actor { void unpin_all_dialog_messages_on_server(DialogId dialog_id, uint64 log_event_id, Promise<Unit> &&promise); - using AffectedHistoryQuery = std::function<void(DialogId, Promise<AffectedHistory>)>; - - void run_affected_history_query_until_complete(DialogId dialog_id, AffectedHistoryQuery query, - bool get_affected_messages, Promise<Unit> &&promise); - void on_get_affected_history(DialogId dialog_id, AffectedHistoryQuery query, bool get_affected_messages, AffectedHistory affected_history, Promise<Unit> &&promise); @@ -2076,7 +2038,7 @@ class MessagesManager final : public Actor { void on_pending_message_views_timeout(DialogId dialog_id); - void update_message_interaction_info(FullMessageId full_message_id, int32 view_count, int32 forward_count, + void update_message_interaction_info(MessageFullId message_full_id, int32 view_count, int32 forward_count, bool has_reply_info, tl_object_ptr<telegram_api::messageReplies> &&reply_info, bool has_reactions, unique_ptr<MessageReactions> &&reactions); @@ -2095,11 +2057,13 @@ 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, bool allow_non_root) const; + Result<MessageFullId> get_top_thread_message_full_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; + td_api::object_ptr<td_api::factCheck> get_message_fact_check_object(const Message *m) const; + vector<td_api::object_ptr<td_api::unreadReaction>> get_unread_reactions_object(DialogId dialog_id, const Message *m) const; @@ -2107,15 +2071,17 @@ class MessagesManager final : public Actor { bool has_reply_info, MessageReplyInfo &&reply_info, bool has_reactions, unique_ptr<MessageReactions> &&reactions, const char *source); + bool update_message_fact_check(const Dialog *d, Message *m, unique_ptr<FactCheck> &&fact_check, bool need_save); + bool update_message_contains_unread_mention(Dialog *d, Message *m, bool contains_unread_mention, const char *source); bool remove_message_unread_reactions(Dialog *d, Message *m, const char *source); - void read_message_content_from_updates(MessageId message_id); + void read_message_content_from_updates(MessageId message_id, int32 read_date); void read_channel_message_content_from_updates(Dialog *d, MessageId message_id); - bool read_message_content(Dialog *d, Message *m, bool is_local_read, const char *source); + bool read_message_content(Dialog *d, Message *m, bool is_local_read, int32 read_date, const char *source); void read_message_contents_on_server(DialogId dialog_id, vector<MessageId> message_ids, uint64 log_event_id, Promise<Unit> &&promise, bool skip_log_event = false); @@ -2165,11 +2131,6 @@ class MessagesManager final : public Actor { void set_dialog_max_unavailable_message_id(DialogId dialog_id, MessageId max_unavailable_message_id, bool from_update, const char *source); - void set_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server, - const char *source); - - void on_update_dialog_online_member_count_timeout(DialogId dialog_id); - void on_update_viewed_messages_timeout(DialogId dialog_id); void on_send_update_chat_read_inbox_timeout(DialogId dialog_id); @@ -2184,21 +2145,18 @@ class MessagesManager final : public Actor { void preload_older_messages(const Dialog *d, MessageId min_message_id); - void on_get_history_from_database(DialogId dialog_id, MessageId from_message_id, - MessageId old_last_database_message_id, int32 offset, int32 limit, - bool from_the_end, bool only_local, vector<MessageDbDialogMessage> &&messages, - Promise<Unit> &&promise); + void load_last_dialog_message_later(DialogId dialog_id); - void get_history_from_the_end(DialogId dialog_id, bool from_database, bool only_local, Promise<Unit> &&promise); - - void get_history_from_the_end_impl(const Dialog *d, bool from_database, bool only_local, Promise<Unit> &&promise, - const char *source); + void load_last_dialog_message(const Dialog *d, const char *source); - void get_history(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, bool from_database, - bool only_local, Promise<Unit> &&promise); + void on_get_history_from_database(DialogId dialog_id, MessageId from_message_id, + MessageId old_last_database_message_id, int32 offset, int32 limit, bool only_local, + vector<MessageDbDialogMessage> &&messages, Promise<Unit> &&promise); void get_history_impl(const Dialog *d, MessageId from_message_id, int32 offset, int32 limit, bool from_database, - bool only_local, Promise<Unit> &&promise); + bool only_local, Promise<Unit> &&promise, const char *source); + + void on_get_history_finished(const PendingGetHistoryQuery &query, Result<Unit> &&result); void load_messages(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, int left_tries, bool only_local, Promise<Unit> &&promise); @@ -2216,11 +2174,11 @@ class MessagesManager final : public Actor { bool is_message_auto_read(DialogId dialog_id, bool is_outgoing) const; - void fail_send_message(FullMessageId full_message_id, int error_code, const string &error_message); + void fail_send_message(MessageFullId message_full_id, int32 error_code, const string &error_message); - void fail_send_message(FullMessageId full_message_id, Status error); + void fail_send_message(MessageFullId message_full_id, Status error); - void fail_edit_message_media(FullMessageId full_message_id, Status &&error); + void fail_edit_message_media(MessageFullId message_full_id, Status &&error); void on_dialog_updated(DialogId dialog_id, const char *source); @@ -2263,6 +2221,8 @@ class MessagesManager final : public Actor { void remove_message_remove_keyboard_reply_markup(Message *m) const; + void update_replied_by_message_count(DialogId dialog_id, const Message *m, bool is_add); + 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); @@ -2279,12 +2239,14 @@ class MessagesManager final : public Actor { void on_message_notification_changed(Dialog *d, const Message *m, const char *source); - bool need_delete_file(FullMessageId full_message_id, FileId file_id) const; + bool need_delete_file(MessageFullId message_full_id, FileId file_id) const; bool need_delete_message_files(DialogId dialog_id, const Message *m) const; void add_message_to_database(const Dialog *d, const Message *m, const char *source); + void delete_all_dialog_notifications(Dialog *d, MessageId max_message_id, const char *source); + 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, @@ -2305,6 +2267,10 @@ class MessagesManager final : public Actor { static void delete_notification_id_to_message_id_correspondence(NotificationInfo *notification_info, NotificationId notification_id, MessageId message_id); + static bool is_notification_info_group_id(const NotificationInfo *notification_info, NotificationGroupId group_id); + + static bool is_dialog_notification_group_id(const Dialog *d, NotificationGroupId group_id); + void remove_message_notification_id(Dialog *d, Message *m, bool is_permanent, bool force_update, bool ignore_pinned_message_notification_removal = false); @@ -2318,6 +2284,8 @@ class MessagesManager final : public Actor { void do_delete_message_log_event(const DeleteMessageLogEvent &log_event) const; + int64 get_message_reply_to_random_id(const Dialog *d, const Message *m) const; + 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); @@ -2325,12 +2293,15 @@ class MessagesManager final : public Actor { bool update_message_content(DialogId dialog_id, Message *old_message, unique_ptr<MessageContent> new_content, bool need_merge_files, bool is_message_in_dialog, bool &is_content_changed); - void update_message_max_reply_media_timestamp(const Dialog *d, Message *m, bool need_send_update_message_content); + void update_message_max_reply_media_timestamp(const Dialog *d, Message *m, + bool need_send_update_message_content) const; void update_message_max_own_media_timestamp(const Dialog *d, Message *m); void update_message_max_reply_media_timestamp_in_replied_messages(DialogId dialog_id, MessageId reply_to_message_id); + bool can_register_message_reply(const Message *m) const; + void register_message_reply(DialogId dialog_id, const Message *m); void reregister_message_reply(DialogId dialog_id, const Message *m); @@ -2397,7 +2368,8 @@ class MessagesManager final : public Actor { bool need_skip_bot_commands(DialogId dialog_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_send_succeeded(Dialog *d, MessageId old_message_id, const Message *m, + bool *need_update_dialog_pos); void send_update_message_content(const Dialog *d, Message *m, bool is_message_in_dialog, const char *source); @@ -2407,18 +2379,24 @@ class MessagesManager final : public Actor { void send_update_message_interaction_info(DialogId dialog_id, const Message *m) const; + void send_update_message_fact_check(DialogId dialog_id, const Message *m) const; + void send_update_message_unread_reactions(DialogId dialog_id, const Message *m, int32 unread_reaction_count) const; - void send_update_message_live_location_viewed(FullMessageId full_message_id); + void send_update_message_live_location_viewed(MessageFullId message_full_id); + + void send_update_active_live_location_messages(); void send_update_delete_messages(DialogId dialog_id, vector<int64> &&message_ids, bool is_permanent) const; - void send_update_new_chat(Dialog *d); + void send_update_new_chat(Dialog *d, const char *source); - bool need_hide_dialog_draft_message(DialogId dialog_id) const; + bool need_hide_dialog_draft_message(const Dialog *d) const; void send_update_chat_draft_message(const Dialog *d); + void send_update_last_message_if_needed(const Dialog *d, const Message *m, const char *source) const; + 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; @@ -2439,12 +2417,12 @@ class MessagesManager final : public Actor { void send_update_chat_position(DialogListId dialog_list_id, const Dialog *d, const char *source) const; - void send_update_chat_online_member_count(DialogId dialog_id, int32 online_member_count) const; - void send_update_secret_chats_with_user_action_bar(const Dialog *d) const; void send_update_chat_action_bar(Dialog *d); + void send_update_chat_business_bot_manage_bar(Dialog *d); + void send_update_chat_available_reactions(const Dialog *d); void send_update_secret_chats_with_user_background(const Dialog *d) const; @@ -2465,9 +2443,6 @@ class MessagesManager final : public Actor { void send_update_chat_has_scheduled_messages(Dialog *d, bool from_deletion); - void send_update_chat_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id, - const DialogAction &action); - void repair_dialog_action_bar(Dialog *d, const char *source); void hide_dialog_action_bar(Dialog *d); @@ -2482,11 +2457,25 @@ 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) const; + td_api::object_ptr<td_api::MessageContent> get_message_message_content_object(DialogId dialog_id, + const Message *m) const; + + td_api::object_ptr<td_api::message> get_message_object(Dialog *d, MessageId message_id, const char *source); + + td_api::object_ptr<td_api::message> get_message_object(const Dialog *d, MessageId message_id, + const char *source) const; + + td_api::object_ptr<td_api::message> get_message_object(DialogId dialog_id, const Message *m, + const char *source) const; + + static td_api::object_ptr<td_api::messages> get_messages_object(int32 total_count, + vector<tl_object_ptr<td_api::message>> &&messages, + bool skip_not_found); + + td_api::object_ptr<td_api::message> get_business_message_message_object( + telegram_api::object_ptr<telegram_api::Message> &&message); - static tl_object_ptr<td_api::messages> get_messages_object(int32 total_count, - vector<tl_object_ptr<td_api::message>> &&messages, - bool skip_not_found); + td_api::object_ptr<td_api::updateActiveLiveLocationMessages> get_update_active_live_location_messages_object() const; vector<DialogId> sort_dialogs_by_order(const vector<DialogId> &dialog_ids, int32 limit) const; @@ -2536,8 +2525,6 @@ class MessagesManager final : public Actor { int32 get_pinned_dialogs_limit(DialogListId dialog_list_id) const; - static vector<DialogId> remove_secret_chat_dialog_ids(vector<DialogId> dialog_ids); - bool set_dialog_is_pinned(DialogId dialog_id, bool is_pinned); bool set_dialog_is_pinned(DialogListId dialog_list_id, Dialog *d, bool is_pinned, @@ -2545,11 +2532,17 @@ class MessagesManager final : public Actor { void save_pinned_folder_dialog_ids(const DialogList &list) const; + void on_update_dialog_view_as_topics(const Dialog *d, bool old_view_as_topics); + + void set_dialog_is_forum(Dialog *d, bool is_forum); + + void set_dialog_view_as_messages(Dialog *d, bool view_as_messages, const char *source); + 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_is_blocked(Dialog *d, bool is_blocked, bool is_blocked_for_stories); void set_dialog_has_bots(Dialog *d, bool has_bots); @@ -2581,11 +2574,14 @@ class MessagesManager final : public Actor { void toggle_dialog_is_pinned_on_server(DialogId dialog_id, bool is_pinned, uint64 log_event_id); + void toggle_dialog_view_as_messages_on_server(DialogId dialog_id, bool view_as_messages, uint64 log_event_id); + 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 toggle_dialog_is_blocked_on_server(DialogId dialog_id, bool is_blocked, bool is_blocked_for_stories, + uint64 log_event_id); void reorder_pinned_dialogs_on_server(FolderId folder_id, const vector<DialogId> &dialog_ids, uint64 log_event_id); @@ -2599,13 +2595,17 @@ class MessagesManager final : public Actor { void remove_dialog_mention_notifications(Dialog *d); - bool set_dialog_last_notification(DialogId dialog_id, NotificationGroupInfo &group_info, int32 last_notification_date, + void set_dialog_last_notification(DialogId dialog_id, NotificationGroupInfo &group_info, int32 last_notification_date, NotificationId last_notification_id, const char *source); + void set_dialog_last_notification_checked(DialogId dialog_id, NotificationGroupInfo &group_info, + int32 last_notification_date, NotificationId last_notification_id, + const char *source); + bool update_dialog_notification_settings(DialogId dialog_id, DialogNotificationSettings *current_settings, DialogNotificationSettings &&new_settings); - void schedule_dialog_unmute(DialogId dialog_id, bool use_default, int32 mute_until); + void schedule_dialog_unmute(DialogId dialog_id, bool use_default, int32 mute_until, int32 unix_time); void update_dialog_unmute_timeout(Dialog *d, bool &old_use_default, int32 &old_mute_until, bool new_use_default, int32 new_mute_until); @@ -2616,12 +2616,18 @@ class MessagesManager final : public Actor { 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); + bool can_add_message_tag(DialogId dialog_id, const MessageReactions *reactions) const; + + ChatReactions get_message_available_reactions(const Dialog *d, const Message *m, bool disallow_custom_for_non_premium, + ReactionUnavailabilityReason *unavailability_reason); + + DialogId get_my_reaction_dialog_id(const Dialog *d) const; + + void drop_message_pending_paid_reactions(const Dialog *d, Message *m); void set_message_reactions(Dialog *d, Message *m, bool is_big, bool add_to_recent, Promise<Unit> &&promise); - void on_set_message_reactions(FullMessageId full_message_id, Result<Unit> result, Promise<Unit> promise); + void on_set_message_reactions(MessageFullId message_full_id, Result<Unit> result, Promise<Unit> promise); void on_read_message_reactions(DialogId dialog_id, vector<MessageId> &&message_ids, Result<Unit> &&result); @@ -2641,18 +2647,15 @@ class MessagesManager final : public Actor { static bool need_poll_message_reactions(const Dialog *d, const Message *m); - void queue_message_reactions_reload(FullMessageId full_message_id); + void queue_message_reactions_reload(MessageFullId message_full_id); void queue_message_reactions_reload(DialogId dialog_id, const vector<MessageId> &message_ids); - bool is_dialog_action_unneeded(DialogId dialog_id) const; + void on_get_message_fact_checks(DialogId dialog_id, const vector<MessageId> &message_ids, + Result<vector<telegram_api::object_ptr<telegram_api::factCheck>>> r_fact_checks); void on_send_dialog_action_timeout(DialogId dialog_id); - void on_active_dialog_action_timeout(DialogId dialog_id); - - void clear_active_dialog_actions(DialogId dialog_id); - void cancel_dialog_action(DialogId dialog_id, const Message *m); Dialog *get_dialog_by_message_id(MessageId message_id); @@ -2666,20 +2669,23 @@ class MessagesManager final : public Actor { Dialog *add_new_dialog(unique_ptr<Dialog> &&dialog, bool is_loaded_from_database, const char *source); - void fix_new_dialog(Dialog *d, unique_ptr<Message> &&last_database_message, MessageId last_database_message_id, - int64 order, int32 last_clear_history_date, MessageId last_clear_history_message_id, - DialogId default_join_group_call_as_dialog_id, DialogId default_send_message_as_dialog_id, - bool need_drop_default_send_message_as_dialog_id, bool is_loaded_from_database, - const char *source); + void fix_new_dialog(Dialog *d, unique_ptr<DraftMessage> &&draft_message, unique_ptr<Message> &&last_database_message, + MessageId last_database_message_id, int64 order, int32 last_clear_history_date, + MessageId last_clear_history_message_id, DialogId default_join_group_call_as_dialog_id, + DialogId default_send_message_as_dialog_id, bool need_drop_default_send_message_as_dialog_id, + bool is_loaded_from_database, const char *source); - bool add_dialog_last_database_message(Dialog *d, unique_ptr<Message> &&last_database_message); + bool add_pending_dialog_data(Dialog *d, unique_ptr<Message> &&last_database_message, + unique_ptr<DraftMessage> &&draft_message); void fix_dialog_action_bar(const Dialog *d, DialogActionBar *action_bar); - td_api::object_ptr<td_api::ChatType> get_chat_type_object(DialogId dialog_id) const; + void fix_dialog_business_bot_manage_bar(DialogId dialog_id, BusinessBotManageBar *business_bot_manage_bar); td_api::object_ptr<td_api::ChatActionBar> get_chat_action_bar_object(const Dialog *d) const; + td_api::object_ptr<td_api::businessBotManageBar> get_business_bot_manage_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; @@ -2690,7 +2696,7 @@ class MessagesManager final : public Actor { td_api::object_ptr<td_api::MessageSender> get_default_message_sender_object(const Dialog *d) const; - td_api::object_ptr<td_api::chat> get_chat_object(const Dialog *d) const; + td_api::object_ptr<td_api::chat> get_chat_object(const Dialog *d, const char *source) const; Dialog *get_dialog(DialogId dialog_id); const Dialog *get_dialog(DialogId dialog_id) const; @@ -2702,12 +2708,17 @@ class MessagesManager final : public Actor { void on_get_dialogs_from_database(FolderId folder_id, int32 limit, DialogDbGetDialogsResult &&dialogs, Promise<Unit> &&promise); + Result<Dialog *> check_dialog_access(DialogId dialog_id, bool allow_secret_chats, AccessRights access_rights, + const char *source); + void send_get_dialog_query(DialogId dialog_id, Promise<Unit> &&promise, uint64 log_event_id, const char *source); void send_search_public_dialogs_query(const string &query, Promise<Unit> &&promise); vector<DialogId> get_pinned_dialog_ids(DialogListId dialog_list_id) const; + bool set_folder_pinned_dialogs(FolderId folder_id, vector<DialogId> old_dialog_ids, vector<DialogId> new_dialog_ids); + void reload_pinned_dialogs(DialogListId dialog_list_id, Promise<Unit> &&promise); void update_dialogs_hints(const Dialog *d); @@ -2719,9 +2730,9 @@ class MessagesManager final : public Actor { static bool is_dialog_in_list(const Dialog *d, DialogListId dialog_list_id); - static void add_dialog_to_list(Dialog *d, DialogListId dialog_list_id); + void add_dialog_to_list(Dialog *d, DialogListId dialog_list_id); - static void remove_dialog_from_list(Dialog *d, DialogListId dialog_list_id); + void remove_dialog_from_list(Dialog *d, DialogListId dialog_list_id); DialogFilterDialogInfo get_dialog_info_for_dialog_filter(const Dialog *d) const; @@ -2748,15 +2759,16 @@ class MessagesManager final : public Actor { static Message *get_message(Dialog *d, MessageId message_id); static const Message *get_message(const Dialog *d, MessageId message_id); + static const Message *get_message_static(const Dialog *d, MessageId message_id); - Message *get_message(FullMessageId full_message_id); - const Message *get_message(FullMessageId full_message_id) const; + Message *get_message(MessageFullId message_full_id); + const Message *get_message(MessageFullId message_full_id) const; bool have_message_force(Dialog *d, MessageId message_id, const char *source); Message *get_message_force(Dialog *d, MessageId message_id, const char *source); - Message *get_message_force(FullMessageId full_message_id, const char *source); + Message *get_message_force(MessageFullId message_full_id, const char *source); void get_message_force_from_server(Dialog *d, MessageId message_id, Promise<Unit> &&promise, tl_object_ptr<telegram_api::InputMessage> input_message = nullptr); @@ -2772,18 +2784,17 @@ class MessagesManager final : public Actor { 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); + void get_dialog_message_by_date_from_server(const Dialog *d, int32 date, bool after_database_search, + Promise<td_api::object_ptr<td_api::message>> &&promise); - void on_get_dialog_message_by_date_from_database(DialogId dialog_id, int32 date, int64 random_id, - Result<MessageDbDialogMessage> result, Promise<Unit> promise); + void on_get_dialog_message_by_date_from_database(DialogId dialog_id, int32 date, + Result<MessageDbDialogMessage> result, + Promise<td_api::object_ptr<td_api::message>> promise); std::pair<bool, int32> get_dialog_mute_until(DialogId dialog_id, const Dialog *d) const; int64 get_dialog_notification_ringtone_id(DialogId dialog_id, const Dialog *d) const; - NotificationSettingsScope get_dialog_notification_setting_scope(DialogId dialog_id) const; - DialogNotificationSettings *get_dialog_notification_settings(DialogId dialog_id, bool force); vector<FileId> get_message_file_ids(const Message *m) const; @@ -2810,20 +2821,12 @@ class MessagesManager final : public Actor { tl_object_ptr<telegram_api::InputPeer> get_send_message_as_input_peer(const Message *m) const; - static bool is_forward_info_sender_hidden(const MessageForwardInfo *forward_info); - - unique_ptr<MessageForwardInfo> get_message_forward_info( - tl_object_ptr<telegram_api::messageFwdHeader> &&forward_header, FullMessageId full_message_id); - - td_api::object_ptr<td_api::messageForwardInfo> get_message_forward_info_object( - const unique_ptr<MessageForwardInfo> &forward_info) const; - void ttl_read_history(Dialog *d, bool is_outgoing, MessageId from_message_id, MessageId till_message_id, double view_date); void ttl_read_history_impl(DialogId dialog_id, bool is_outgoing, MessageId from_message_id, MessageId till_message_id, double view_date); void ttl_on_view(const Dialog *d, Message *m, double view_date, double now); - bool ttl_on_open(Dialog *d, Message *m, double now, bool is_local_read); + bool ttl_on_open(Dialog *d, Message *m, double now, bool is_local_read, int32 read_date); void ttl_register_message(DialogId dialog_id, const Message *m, double now); void ttl_unregister_message(DialogId dialog_id, const Message *m, const char *source); void ttl_period_register_message(DialogId dialog_id, const Message *m, double server_time); @@ -2832,7 +2835,8 @@ class MessagesManager final : public Actor { void ttl_update_timeout(double now); void on_message_ttl_expired(Dialog *d, Message *m); - void on_message_ttl_expired_impl(Dialog *d, Message *m); + + void on_message_ttl_expired_impl(Dialog *d, Message *m, bool is_message_in_dialog); void start_up() final; @@ -2842,7 +2846,7 @@ class MessagesManager final : public Actor { void hangup() final; - void create_folders(); + void create_folders(int source); void init(); @@ -2850,10 +2854,10 @@ class MessagesManager final : public Actor { 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, + void on_restore_missing_message_after_get_difference(MessageFullId message_full_id, MessageId old_message_id, Result<Unit> result); - void on_get_message_link_dialog(MessageLinkInfo &&info, Promise<MessageLinkInfo> &&promise); + void on_get_message_link_dialog(MessageLinkInfo &&info, DialogId dialog_id, Promise<MessageLinkInfo> &&promise); void on_get_message_link_message(MessageLinkInfo &&info, DialogId dialog_id, Promise<MessageLinkInfo> &&promise); @@ -2872,30 +2876,38 @@ class MessagesManager final : public Actor { static MessageId get_first_database_message_id_by_index(const Dialog *d, MessageSearchFilter filter); - void on_get_message_calendar_from_database(int64 random_id, DialogId dialog_id, MessageId from_message_id, + void get_message_calendar_from_server(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, + Promise<td_api::object_ptr<td_api::messageCalendar>> &&promise); + + void on_get_message_calendar_from_database(DialogId dialog_id, MessageId from_message_id, MessageId first_db_message_id, MessageSearchFilter filter, - Result<MessageDbCalendar> r_calendar, Promise<Unit> promise); + Result<MessageDbCalendar> r_calendar, + Promise<td_api::object_ptr<td_api::messageCalendar>> promise); void on_search_dialog_message_db_result(int64 random_id, DialogId dialog_id, MessageId from_message_id, MessageId first_db_message_id, MessageSearchFilter filter, int32 offset, int32 limit, Result<vector<MessageDbDialogMessage>> r_messages, Promise<Unit> promise); - void on_message_db_fts_result(Result<MessageDbFtsResult> result, string offset, int32 limit, int64 random_id, - Promise<Unit> &&promise); + void on_message_db_fts_result(Result<MessageDbFtsResult> result, string offset, int32 limit, + Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); + + void on_message_db_calls_result(Result<MessageDbCallsResult> result, MessageId first_db_message_id, + MessageId offset_message_id, int32 limit, MessageSearchFilter filter, + Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); - void on_message_db_calls_result(Result<MessageDbCallsResult> result, int64 random_id, MessageId first_db_message_id, - MessageSearchFilter filter, Promise<Unit> &&promise); + void process_viewed_message(Dialog *d, const vector<MessageId> &viewed_message_ids, bool is_first); - void on_load_active_live_location_full_message_ids_from_database(string value); + void on_load_active_live_location_message_full_ids_from_database(string value); - void on_load_active_live_location_messages_finished(); + bool try_add_active_live_location(DialogId dialog_id, const Message *m); - void try_add_active_live_location(DialogId dialog_id, const Message *m); + bool add_active_live_location(MessageFullId message_full_id); - void add_active_live_location(FullMessageId full_message_id); + bool delete_active_live_location(MessageFullId message_full_id); - bool delete_active_live_location(DialogId dialog_id, const Message *m); + void schedule_active_live_location_expiration(); void save_active_live_locations(); @@ -2903,7 +2915,7 @@ class MessagesManager final : public Actor { void view_message_live_location_on_server(int64 task_id); - void view_message_live_location_on_server_impl(int64 task_id, FullMessageId full_message_id); + void view_message_live_location_on_server_impl(int64 task_id, MessageFullId message_full_id); void on_message_live_location_viewed_on_server(int64 task_id); @@ -2918,13 +2930,9 @@ class MessagesManager final : public Actor { void change_message_files(DialogId dialog_id, const Message *m, const vector<FileId> &old_file_ids); Result<unique_ptr<ReplyMarkup>> get_dialog_reply_markup( - DialogId dialog_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup_ptr) const TD_WARN_UNUSED_RESULT; - - const DialogPhoto *get_dialog_photo(DialogId dialog_id) const; - - RestrictedRights get_dialog_default_permissions(DialogId dialog_id) const; + DialogId dialog_id, tl_object_ptr<td_api::ReplyMarkup> &&reply_markup) const TD_WARN_UNUSED_RESULT; - bool get_dialog_has_protected_content(DialogId dialog_id) const; + bool get_dialog_view_as_topics(const Dialog *d) const; bool get_dialog_has_scheduled_messages(const Dialog *d) const; @@ -2947,6 +2955,8 @@ class MessagesManager final : public Actor { bool update_dialog_draft_message(Dialog *d, unique_ptr<DraftMessage> &&draft_message, bool from_update, bool need_update_dialog_pos); + void clear_dialog_draft_by_sent_message(Dialog *d, const Message *m, bool need_update_dialog_pos); + void save_dialog_draft_message_on_server(DialogId dialog_id); void on_saved_dialog_draft_message(DialogId dialog_id, uint64 generation); @@ -2968,8 +2978,6 @@ class MessagesManager final : public Actor { int64 get_next_pinned_dialog_order(); - bool is_removed_from_dialog_list(const Dialog *d) const; - void update_dialog_pos(Dialog *d, const char *source, bool need_send_update = true, bool is_loaded_from_database = false); @@ -2999,10 +3007,15 @@ 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, MessageId expected_max_message_id, Promise<Unit> &&promise); + bool need_channel_difference_to_add_message(DialogId dialog_id, MessageId message_id); + + void run_after_channel_difference(DialogId dialog_id, MessageId expected_max_message_id, Promise<Unit> &&promise, + const char *source); bool running_get_channel_difference(DialogId dialog_id) const; + void retry_get_channel_difference_later(DialogId dialog_id); + void on_channel_get_difference_timeout(DialogId dialog_id); void update_expected_channel_pts(DialogId dialog_id, int32 expected_pts); @@ -3010,7 +3023,7 @@ class MessagesManager final : public Actor { 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); + double delay, const char *source); 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); @@ -3050,16 +3063,16 @@ class MessagesManager final : public Actor { static void on_pending_send_dialog_action_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); - static void on_active_dialog_action_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); - - static void on_update_dialog_online_member_count_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); - static void on_preload_folder_dialog_list_timeout_callback(void *messages_manager_ptr, int64 folder_id_int); 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); + static void on_live_location_expire_timeout_callback(void *messages_manager_ptr); + + void on_live_location_expire_timeout(); + void load_secret_thumbnail(FileId thumbnail_file_id); void on_upload_media(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file, @@ -3069,32 +3082,6 @@ class MessagesManager final : public Actor { void on_load_secret_thumbnail(FileId thumbnail_file_id, BufferSlice thumbnail); void on_upload_thumbnail(FileId thumbnail_file_id, tl_object_ptr<telegram_api::InputFile> thumbnail_input_file); - void on_upload_dialog_photo(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file); - void on_upload_dialog_photo_error(FileId file_id, Status status); - - void send_edit_dialog_photo_query(DialogId dialog_id, FileId file_id, - tl_object_ptr<telegram_api::InputChatPhoto> &&input_chat_photo, - Promise<Unit> &&promise); - - void upload_imported_messages(DialogId dialog_id, FileId file_id, vector<FileId> attached_file_ids, bool is_reupload, - Promise<Unit> &&promise, vector<int> bad_parts = {}); - - void on_upload_imported_messages(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file); - void on_upload_imported_messages_error(FileId file_id, Status status); - - void upload_imported_message_attachment(DialogId dialog_id, int64 import_id, FileId file_id, bool is_reupload, - Promise<Unit> &&promise, vector<int> bad_parts = {}); - - void on_upload_imported_message_attachment(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file); - void on_upload_imported_message_attachment_error(FileId file_id, Status status); - - void on_imported_message_attachments_uploaded(int64 random_id, Result<Unit> &&result); - - Status can_import_messages(DialogId dialog_id); - - void send_get_message_public_forwards_query(DcId dc_id, FullMessageId full_message_id, string offset, int32 limit, - Promise<td_api::object_ptr<td_api::foundMessages>> &&promise); - void add_sponsored_dialog(const Dialog *d, DialogSource source); void save_sponsored_dialog(); @@ -3103,6 +3090,8 @@ class MessagesManager final : public Actor { Dialog *get_service_notifications_dialog(); + static void extract_authentication_codes(DialogId dialog_id, const Message *m, vector<string> &authentication_codes); + void save_auth_notification_ids(); MessageId get_next_message_id(Dialog *d, MessageType type) const; @@ -3127,7 +3116,7 @@ class MessagesManager final : public Actor { void update_forward_count(DialogId dialog_id, const Message *m); - void update_forward_count(DialogId dialog_id, MessageId message_id, int32 update_date); + void update_forward_count(MessageFullId message_full_id, int32 update_date); void update_has_outgoing_messages(DialogId dialog_id, const Message *m); @@ -3179,12 +3168,15 @@ class MessagesManager final : public Actor { static uint64 save_reorder_pinned_dialogs_on_server_log_event(FolderId folder_id, const vector<DialogId> &dialog_ids); + static uint64 save_toggle_dialog_view_as_messages_on_server_log_event(DialogId dialog_id, bool view_as_messages); + 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_toggle_dialog_is_blocked_on_server_log_event(DialogId dialog_id, bool is_blocked, + bool is_blocked_for_stories); static uint64 save_read_message_contents_on_server_log_event(DialogId dialog_id, const vector<MessageId> &message_ids); @@ -3206,16 +3198,12 @@ class MessagesManager final : public Actor { void suffix_load_till_date(Dialog *d, int32 date, Promise<Unit> promise); void suffix_load_till_message_id(Dialog *d, MessageId message_id, Promise<Unit> promise); - 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; static int32 get_message_schedule_date(const Message *m); + static int32 get_message_original_date(const Message *m); + static DialogId get_message_original_sender(const Message *m); static DialogId get_message_sender(const Message *m); @@ -3225,28 +3213,27 @@ class MessagesManager final : public Actor { class UploadMediaCallback; class UploadThumbnailCallback; - class UploadDialogPhotoCallback; - class UploadImportedMessagesCallback; - class UploadImportedMessageAttachmentCallback; std::shared_ptr<UploadMediaCallback> upload_media_callback_; std::shared_ptr<UploadThumbnailCallback> upload_thumbnail_callback_; - std::shared_ptr<UploadDialogPhotoCallback> upload_dialog_photo_callback_; - std::shared_ptr<UploadImportedMessagesCallback> upload_imported_messages_callback_; - std::shared_ptr<UploadImportedMessageAttachmentCallback> upload_imported_message_attachment_callback_; double last_channel_pts_jump_warning_time_ = 0; - FlatHashMap<FileId, std::pair<FullMessageId, FileId>, FileIdHash> - being_uploaded_files_; // file_id -> message, thumbnail_file_id + struct UploadedFileInfo { + MessageFullId message_full_id; + FileId thumbnail_file_id; + int32 media_pos; + }; + FlatHashMap<FileId, UploadedFileInfo, FileIdHash> being_uploaded_files_; struct UploadedThumbnailInfo { - FullMessageId full_message_id; + MessageFullId message_full_id; FileId file_id; // original file file_id tl_object_ptr<telegram_api::InputFile> input_file; // original file InputFile + int32 media_pos; }; FlatHashMap<FileId, UploadedThumbnailInfo, FileIdHash> being_uploaded_thumbnails_; // thumbnail_file_id -> ... struct UploadedSecretThumbnailInfo { - FullMessageId full_message_id; + MessageFullId message_full_id; FileId file_id; // original file file_id tl_object_ptr<telegram_api::InputEncryptedFile> input_file; // original file InputEncryptedFile }; @@ -3257,10 +3244,10 @@ class MessagesManager final : public Actor { class TtlNode final : private HeapNode { public: TtlNode(DialogId dialog_id, MessageId message_id, bool by_ttl_period) - : full_message_id_(dialog_id, message_id), by_ttl_period_(by_ttl_period) { + : message_full_id_(dialog_id, message_id), by_ttl_period_(by_ttl_period) { } - FullMessageId full_message_id_; + MessageFullId message_full_id_; bool by_ttl_period_; HeapNode *as_heap_node() const { @@ -3271,12 +3258,12 @@ class MessagesManager final : public Actor { } bool operator==(const TtlNode &other) const { - return full_message_id_ == other.full_message_id_; + return message_full_id_ == other.message_full_id_ && by_ttl_period_ == other.by_ttl_period_; } }; struct TtlNodeHash { uint32 operator()(const TtlNode &ttl_node) const { - return FullMessageIdHash()(ttl_node.full_message_id_) * 2 + static_cast<uint32>(ttl_node.by_ttl_period_); + return MessageFullIdHash()(ttl_node.message_full_id_) * 2 + static_cast<uint32>(ttl_node.by_ttl_period_); } }; std::unordered_set<TtlNode, TtlNodeHash> ttl_nodes_; @@ -3289,71 +3276,15 @@ class MessagesManager final : public Actor { bool ttl_db_has_query_ = false; Slot ttl_db_slot_; - FlatHashMap<int64, FullMessageId> being_sent_messages_; // message_random_id -> message + FlatHashMap<int64, MessageFullId> being_sent_messages_; // message_random_id -> message - FlatHashMap<FullMessageId, MessageId, FullMessageIdHash> update_message_ids_; // new_message_id -> temporary_id + FlatHashMap<MessageFullId, MessageId, MessageFullIdHash> update_message_ids_; // new_message_id -> temporary_id FlatHashMap<DialogId, FlatHashMap<ScheduledServerMessageId, MessageId, ScheduledServerMessageIdHash>, DialogIdHash> update_scheduled_message_ids_; // new_message_id -> temporary_id const char *debug_add_message_to_dialog_fail_reason_ = ""; - struct UploadedDialogPhotoInfo { - DialogId dialog_id; - double main_frame_timestamp; - bool is_animation; - bool is_reupload; - Promise<Unit> promise; - - UploadedDialogPhotoInfo(DialogId dialog_id, double main_frame_timestamp, bool is_animation, bool is_reupload, - Promise<Unit> promise) - : dialog_id(dialog_id) - , main_frame_timestamp(main_frame_timestamp) - , is_animation(is_animation) - , is_reupload(is_reupload) - , promise(std::move(promise)) { - } - }; - FlatHashMap<FileId, UploadedDialogPhotoInfo, FileIdHash> being_uploaded_dialog_photos_; - - struct UploadedImportedMessagesInfo { - DialogId dialog_id; - vector<FileId> attached_file_ids; - bool is_reupload; - Promise<Unit> promise; - - UploadedImportedMessagesInfo(DialogId dialog_id, vector<FileId> &&attached_file_ids, bool is_reupload, - Promise<Unit> &&promise) - : dialog_id(dialog_id) - , attached_file_ids(std::move(attached_file_ids)) - , is_reupload(is_reupload) - , promise(std::move(promise)) { - } - }; - FlatHashMap<FileId, unique_ptr<UploadedImportedMessagesInfo>, FileIdHash> being_uploaded_imported_messages_; - - struct UploadedImportedMessageAttachmentInfo { - DialogId dialog_id; - int64 import_id; - bool is_reupload; - Promise<Unit> promise; - - UploadedImportedMessageAttachmentInfo(DialogId dialog_id, int64 import_id, bool is_reupload, - Promise<Unit> &&promise) - : dialog_id(dialog_id), import_id(import_id), is_reupload(is_reupload), promise(std::move(promise)) { - } - }; - FlatHashMap<FileId, unique_ptr<UploadedImportedMessageAttachmentInfo>, FileIdHash> - being_uploaded_imported_message_attachments_; - - struct PendingMessageImport { - MultiPromiseActor upload_files_multipromise{"UploadAttachedFilesMultiPromiseActor"}; - DialogId dialog_id; - int64 import_id = 0; - Promise<Unit> promise; - }; - FlatHashMap<int64, unique_ptr<PendingMessageImport>> pending_message_imports_; - struct PendingMessageGroupSend { DialogId dialog_id; size_t finished_count = 0; @@ -3363,14 +3294,22 @@ class MessagesManager final : public Actor { }; FlatHashMap<int64, PendingMessageGroupSend> pending_message_group_sends_; // media_album_id -> ... + struct PendingPaidMediaGroupSend { + size_t finished_count = 0; + vector<bool> is_finished; + vector<Status> results; + }; + FlatHashMap<MessageFullId, PendingPaidMediaGroupSend, MessageFullIdHash> pending_paid_media_group_sends_; + WaitFreeHashMap<MessageId, DialogId, MessageIdHash> message_id_to_dialog_id_; FlatHashMap<MessageId, DialogId, MessageIdHash> last_clear_history_message_id_to_dialog_id_; - bool created_public_broadcasts_inited_ = false; - vector<ChannelId> created_public_broadcasts_; - - FlatHashMap<int64, DialogId> created_dialogs_; // random_id -> dialog_id - FlatHashMap<DialogId, Promise<Unit>, DialogIdHash> pending_created_dialogs_; // dialog_id -> promise + struct PendingCreatedDialog { + td_api::object_ptr<td_api::failedToAddMembers> failed_to_add_members_; + Promise<td_api::object_ptr<td_api::createdBasicGroupChat>> chat_promise_; + Promise<td_api::object_ptr<td_api::chat>> channel_promise_; + }; + FlatHashMap<DialogId, PendingCreatedDialog, DialogIdHash> pending_created_dialogs_; bool running_get_difference_ = false; // true after before_get_difference and false after after_get_difference @@ -3386,23 +3325,8 @@ class MessagesManager final : public Actor { FlatHashMap<string, vector<DialogId>> found_public_dialogs_; // TODO time bound cache FlatHashMap<string, vector<DialogId>> found_on_server_dialogs_; // TODO time bound cache - struct CommonDialogs { - vector<DialogId> dialog_ids; - double receive_time = 0; - int32 total_count = 0; - bool is_outdated = false; - }; - FlatHashMap<UserId, CommonDialogs, UserIdHash> found_common_dialogs_; - - FlatHashMap<int64, FullMessageId> get_dialog_message_by_date_results_; - - FlatHashMap<int64, td_api::object_ptr<td_api::messageCalendar>> found_dialog_message_calendars_; 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 struct MessageEmbeddingCodes { FlatHashMap<MessageId, string, MessageIdHash> embedding_codes_; @@ -3412,29 +3336,17 @@ class MessagesManager final : public Actor { FlatHashMap<DialogId, vector<Promise<Unit>>, DialogIdHash> get_dialog_queries_; FlatHashMap<DialogId, uint64, DialogIdHash> get_dialog_query_log_event_id_; - FlatHashMap<FullMessageId, int32, FullMessageIdHash> replied_by_yet_unsent_messages_; - FlatHashMap<FullMessageId, FlatHashSet<MessageId, MessageIdHash>, FullMessageIdHash> replied_yet_unsent_messages_; + FlatHashMap<MessageFullId, int32, MessageFullIdHash> replied_by_yet_unsent_messages_; + FlatHashMap<MessageFullId, FlatHashSet<MessageFullId, MessageFullIdHash>, MessageFullIdHash> + replied_yet_unsent_messages_; - // full_message_id -> replies with media timestamps - FlatHashMap<FullMessageId, FlatHashSet<MessageId, MessageIdHash>, FullMessageIdHash> - replied_by_media_timestamp_messages_; + // message_full_id -> replies with media timestamps + FlatHashMap<MessageFullId, FlatHashSet<MessageFullId, MessageFullIdHash>, MessageFullIdHash> + message_to_replied_media_timestamp_messages_; - struct ActiveDialogAction { - MessageId top_thread_message_id; - DialogId typing_dialog_id; - DialogAction action; - double start_time; - - ActiveDialogAction(MessageId top_thread_message_id, DialogId typing_dialog_id, DialogAction action, - double start_time) - : top_thread_message_id(top_thread_message_id) - , typing_dialog_id(typing_dialog_id) - , action(std::move(action)) - , start_time(start_time) { - } - }; - - FlatHashMap<DialogId, std::vector<ActiveDialogAction>, DialogIdHash> active_dialog_actions_; + // story_full_id -> replies with media timestamps + FlatHashMap<StoryFullId, FlatHashSet<MessageFullId, MessageFullIdHash>, StoryFullIdHash> + story_to_replied_media_timestamp_messages_; FlatHashMap<NotificationGroupId, DialogId, NotificationGroupIdHash> notification_group_id_to_dialog_id_; @@ -3445,6 +3357,7 @@ class MessagesManager final : public Actor { int64 current_pinned_dialog_order_ = static_cast<int64>(MIN_PINNED_DIALOG_DATE) << 32; + int64 current_dialog_list_unique_id_ = 0; std::unordered_map<DialogListId, DialogList, DialogListIdHash> dialog_lists_; std::unordered_map<FolderId, DialogFolder, FolderIdHash> dialog_folders_; @@ -3488,35 +3401,23 @@ class MessagesManager final : public Actor { MultiTimeout pending_unload_dialog_timeout_{"PendingUnloadDialogTimeout"}; MultiTimeout dialog_unmute_timeout_{"DialogUnmuteTimeout"}; MultiTimeout pending_send_dialog_action_timeout_{"PendingSendDialogActionTimeout"}; - MultiTimeout active_dialog_action_timeout_{"ActiveDialogActionTimeout"}; - MultiTimeout update_dialog_online_member_count_timeout_{"UpdateDialogOnlineMemberCountTimeout"}; MultiTimeout preload_folder_dialog_list_timeout_{"PreloadFolderDialogListTimeout"}; MultiTimeout update_viewed_messages_timeout_{"UpdateViewedMessagesTimeout"}; MultiTimeout send_update_chat_read_inbox_timeout_{"SendUpdateChatReadInboxTimeout"}; + Timeout live_location_expire_timeout_; + Hints dialogs_hints_; // search dialogs by title and usernames - FlatHashSet<FullMessageId, FullMessageIdHash> active_live_location_full_message_ids_; + FlatHashSet<MessageFullId, MessageFullIdHash> active_live_location_message_full_ids_; bool are_active_live_location_messages_loaded_ = false; vector<Promise<Unit>> load_active_live_location_messages_queries_; FlatHashMap<DialogId, vector<Promise<Unit>>, DialogIdHash> load_scheduled_messages_from_database_queries_; - struct ResolvedUsername { - DialogId dialog_id; - double expires_at = 0.0; - - ResolvedUsername() = default; - ResolvedUsername(DialogId dialog_id, double expires_at) : dialog_id(dialog_id), expires_at(expires_at) { - } - }; - - WaitFreeHashMap<string, ResolvedUsername> resolved_usernames_; - WaitFreeHashMap<string, DialogId> inaccessible_resolved_usernames_; - FlatHashSet<string> reload_voice_chat_on_search_usernames_; - struct GetDialogsTask { DialogListId dialog_list_id; + int64 dialog_list_unique_id; int32 limit; int32 retry_count; DialogDate last_dialog_date = MIN_DIALOG_DATE; @@ -3544,9 +3445,17 @@ class MessagesManager final : public Actor { FlatHashMap<DialogId, FlatHashMap<int64, MessageId>, DialogIdHash> pending_secret_message_ids_; // random_id -> message_id - FlatHashMap<DialogId, vector<DialogId>, DialogIdHash> pending_add_dialog_last_database_message_dependent_dialogs_; - FlatHashMap<DialogId, std::pair<int32, unique_ptr<Message>>, DialogIdHash> - pending_add_dialog_last_database_message_; // dialog -> dependency counter + message + struct AddDialogData { + int32 dependent_dialog_count_ = 0; + unique_ptr<Message> last_message_; + unique_ptr<DraftMessage> draft_message_; + + AddDialogData() = default; + AddDialogData(int32 dependent_dialog_count, unique_ptr<Message> &&last_message, + unique_ptr<DraftMessage> &&draft_message); + }; + FlatHashMap<DialogId, vector<DialogId>, DialogIdHash> pending_add_dialog_dependent_dialogs_; + FlatHashMap<DialogId, AddDialogData, DialogIdHash> pending_add_dialog_data_; FlatHashMap<DialogId, vector<DialogId>, DialogIdHash> pending_add_default_join_group_call_as_dialog_id_; // dialog_id -> dependent dialogs @@ -3573,7 +3482,7 @@ class MessagesManager final : public Actor { CallsDbState calls_db_state_; int64 viewed_live_location_task_id_ = 0; - FlatHashMap<int64, FullMessageId> viewed_live_location_tasks_; // task_id -> task + FlatHashMap<int64, MessageFullId> viewed_live_location_tasks_; // task_id -> task FlatHashMap<DialogId, FlatHashMap<MessageId, int64, MessageIdHash>, DialogIdHash> pending_viewed_live_locations_; // ... -> task_id @@ -3583,9 +3492,7 @@ class MessagesManager final : public Actor { }; FlatHashMap<uint64, UnsentMediaQueue> yet_unsent_media_queues_; - FlatHashMap<DialogId, NetQueryRef, DialogIdHash> set_typing_query_; - - WaitFreeHashMap<FullMessageId, FileSourceId, FullMessageIdHash> full_message_id_to_file_source_id_; + WaitFreeHashMap<MessageFullId, FileSourceId, MessageFullIdHash> message_full_id_to_file_source_id_; FlatHashMap<DialogId, int32, DialogIdHash> last_outgoing_forwarded_message_date_; @@ -3596,27 +3503,22 @@ class MessagesManager final : public Actor { }; FlatHashMap<DialogId, unique_ptr<ViewedMessagesInfo>, DialogIdHash> dialog_viewed_messages_; - struct OnlineMemberCountInfo { - int32 online_member_count = 0; - double update_time = 0; - bool is_update_sent = false; - }; - FlatHashMap<DialogId, OnlineMemberCountInfo, DialogIdHash> dialog_online_member_counts_; - struct ReactionsToReload { FlatHashSet<MessageId, MessageIdHash> message_ids; bool is_request_sent = false; }; FlatHashMap<DialogId, ReactionsToReload, DialogIdHash> being_reloaded_reactions_; + FlatHashSet<MessageFullId, MessageFullIdHash> being_reloaded_fact_checks_; + FlatHashMap<DialogId, std::pair<bool, bool>, DialogIdHash> pending_dialog_group_call_updates_; FlatHashMap<string, int32> auth_notification_id_date_; 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> + FlatHashMap<MessageFullId, MessageId, MessageFullIdHash> yet_unsent_message_full_id_to_persistent_message_id_; + FlatHashMap<MessageFullId, std::set<MessageId>, MessageFullIdHash> 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_; @@ -3636,12 +3538,14 @@ class MessagesManager final : public Actor { int32 query_count = 0; bool was_updated = false; }; - FlatHashMap<FullMessageId, PendingReaction, FullMessageIdHash> pending_reactions_; + FlatHashMap<MessageFullId, PendingReaction, MessageFullIdHash> pending_reactions_; + + FlatHashMap<MessageFullId, int32, MessageFullIdHash> pending_read_reactions_; - FlatHashMap<FullMessageId, int32, FullMessageIdHash> pending_read_reactions_; + vector<ReactionType> active_reaction_types_; + FlatHashMap<ReactionType, size_t, ReactionTypeHash> active_reaction_pos_; - vector<string> active_reactions_; - FlatHashMap<string, size_t> active_reaction_pos_; + FlatHashMap<PendingGetHistoryQuery, vector<Promise<Unit>>, PendingGetHistoryQueryHash> get_history_queries_; uint32 scheduled_messages_sync_generation_ = 1; @@ -3651,7 +3555,7 @@ class MessagesManager final : public Actor { DialogId sponsored_dialog_id_; DialogSource sponsored_dialog_source_; - FullMessageId being_readded_message_id_; + MessageFullId being_readded_message_id_; DialogId being_added_dialog_id_; DialogId being_added_by_new_message_dialog_id_; @@ -3663,6 +3567,7 @@ class MessagesManager final : public Actor { double start_time_ = 0; bool is_inited_ = false; + int create_folders_source_ = 0; Td *td_; ActorShared<> parent_; |