Update API scheme to layer 119. Count replies.

This commit is contained in:
John Preston 2020-09-01 10:44:18 +04:00
parent fcdc4cd465
commit 55edb3bdfe
54 changed files with 973 additions and 583 deletions

View file

@ -141,8 +141,8 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#d20b9f3c flags:# has_video:flags.0?true photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto; chatPhoto#d20b9f3c flags:# has_video:flags.0?true photo_small:FileLocation photo_big:FileLocation dc_id:int = ChatPhoto;
messageEmpty#83e5de54 id:int = Message; messageEmpty#83e5de54 id:int = Message;
message#452c0e65 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message; message#58ae39c9 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message;
messageService#9e19a1f6 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?int to_id:Peer reply_to_msg_id:flags.3?int date:int action:MessageAction = Message; messageService#286fa604 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction = Message;
messageMediaEmpty#3ded6320 = MessageMedia; messageMediaEmpty#3ded6320 = MessageMedia;
messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia; messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
@ -192,6 +192,7 @@ photoSizeEmpty#e17e23c type:string = PhotoSize;
photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize; photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize; photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize; photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
photoSizeProgressive#5aa86a51 type:string location:FileLocation w:int h:int sizes:Vector<int> = PhotoSize;
geoPointEmpty#1117dd5f = GeoPoint; geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint; geoPoint#296f104 long:double lat:double access_hash:long = GeoPoint;
@ -231,8 +232,6 @@ contact#f911c994 user_id:int mutual:Bool = Contact;
importedContact#d0028438 user_id:int client_id:long = ImportedContact; importedContact#d0028438 user_id:int client_id:long = ImportedContact;
contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus; contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus;
contacts.contactsNotModified#b74ba9d2 = contacts.Contacts; contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
@ -240,8 +239,8 @@ contacts.contacts#eae87e42 contacts:Vector<Contact> saved_count:int users:Vector
contacts.importedContacts#77d01c3b imported:Vector<ImportedContact> popular_invites:Vector<PopularContact> retry_contacts:Vector<long> users:Vector<User> = contacts.ImportedContacts; contacts.importedContacts#77d01c3b imported:Vector<ImportedContact> popular_invites:Vector<PopularContact> retry_contacts:Vector<long> users:Vector<User> = contacts.ImportedContacts;
contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked; contacts.blocked#ade1591 blocked:Vector<PeerBlocked> chats:Vector<Chat> users:Vector<User> = contacts.Blocked;
contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked; contacts.blockedSlice#e1664194 count:int blocked:Vector<PeerBlocked> chats:Vector<Chat> users:Vector<User> = contacts.Blocked;
messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs; messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs; messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
@ -292,7 +291,6 @@ updateEncryptedMessagesRead#38fe25b7 chat_id:int max_date:int date:int = Update;
updateChatParticipantAdd#ea4b0e5c chat_id:int user_id:int inviter_id:int date:int version:int = Update; updateChatParticipantAdd#ea4b0e5c chat_id:int user_id:int inviter_id:int date:int version:int = Update;
updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update; updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update;
updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update; updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
updateUserBlocked#80ece81a user_id:int blocked:Bool = Update;
updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update; updateNotifySettings#bec268ef peer:NotifyPeer notify_settings:PeerNotifySettings = Update;
updateServiceNotification#ebe46819 flags:# popup:flags.0?true inbox_date:flags.1?int type:string message:string media:MessageMedia entities:Vector<MessageEntity> = Update; updateServiceNotification#ebe46819 flags:# popup:flags.0?true inbox_date:flags.1?int type:string message:string media:MessageMedia entities:Vector<MessageEntity> = Update;
updatePrivacy#ee3b272a key:PrivacyKey rules:Vector<PrivacyRule> = Update; updatePrivacy#ee3b272a key:PrivacyKey rules:Vector<PrivacyRule> = Update;
@ -358,6 +356,9 @@ updateDialogFilterOrder#a5d72105 order:Vector<int> = Update;
updateDialogFilters#3504914f = Update; updateDialogFilters#3504914f = Update;
updatePhoneCallSignalingData#2661bf09 phone_call_id:long data:bytes = Update; updatePhoneCallSignalingData#2661bf09 phone_call_id:long data:bytes = Update;
updateChannelParticipant#65d2b464 flags:# channel_id:int date:int user_id:int prev_participant:flags.0?ChannelParticipant new_participant:flags.1?ChannelParticipant qts:int = Update; updateChannelParticipant#65d2b464 flags:# channel_id:int date:int user_id:int prev_participant:flags.0?ChannelParticipant new_participant:flags.1?ChannelParticipant qts:int = Update;
updateChannelMessageForwards#6e8a84df channel_id:int id:int forwards:int = Update;
updateReadDiscussion#119fb587 peer:Peer msg_id:int read_max_id:int = Update;
updatePeerBlocked#246a4b22 peer_id:Peer blocked:Bool = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -367,8 +368,8 @@ updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_mess
updates.differenceTooLong#4afe8f6d pts:int = updates.Difference; updates.differenceTooLong#4afe8f6d pts:int = updates.Difference;
updatesTooLong#e317af7e = Updates; updatesTooLong#e317af7e = Updates;
updateShortMessage#914fbf11 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates; updateShortMessage#2296d2c8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
updateShortChatMessage#16812688 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int entities:flags.7?Vector<MessageEntity> = Updates; updateShortChatMessage#402d5dbb flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
updateShort#78d4dec1 update:Update date:int = Updates; updateShort#78d4dec1 update:Update date:int = Updates;
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates; updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates; updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
@ -601,7 +602,7 @@ channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:
channelParticipant#15ebac1d user_id:int date:int = ChannelParticipant; channelParticipant#15ebac1d user_id:int date:int = ChannelParticipant;
channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelParticipant; channelParticipantSelf#a3289a6d user_id:int inviter_id:int date:int = ChannelParticipant;
channelParticipantCreator#808d15a4 flags:# user_id:int rank:flags.0?string = ChannelParticipant; channelParticipantCreator#447dca4b flags:# user_id:int admin_rights:ChatAdminRights rank:flags.0?string = ChannelParticipant;
channelParticipantAdmin#ccbebbaf flags:# can_edit:flags.0?true self:flags.1?true user_id:int inviter_id:flags.1?int promoted_by:int date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant; channelParticipantAdmin#ccbebbaf flags:# can_edit:flags.0?true self:flags.1?true user_id:int inviter_id:flags.1?int promoted_by:int date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant;
channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant; channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
@ -648,7 +649,7 @@ messages.botResults#947ca848 flags:# gallery:flags.0?true query_id:long next_off
exportedMessageLink#5dab1af4 link:string html:string = ExportedMessageLink; exportedMessageLink#5dab1af4 link:string html:string = ExportedMessageLink;
messageFwdHeader#353a686b flags:# from_id:flags.0?int from_name:flags.5?string date:int channel_id:flags.1?int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int psa_type:flags.6?string = MessageFwdHeader; messageFwdHeader#5f777dce flags:# from_id:flags.0?Peer from_name:flags.5?string date:int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int psa_type:flags.6?string = MessageFwdHeader;
auth.codeTypeSms#72a3158c = auth.CodeType; auth.codeTypeSms#72a3158c = auth.CodeType;
auth.codeTypeCall#741cd3e3 = auth.CodeType; auth.codeTypeCall#741cd3e3 = auth.CodeType;
@ -1029,7 +1030,7 @@ chatOnlines#f041e250 onlines:int = ChatOnlines;
statsURL#47a971e0 url:string = StatsURL; statsURL#47a971e0 url:string = StatsURL;
chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true = ChatAdminRights; chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true anonymous:flags.10?true = ChatAdminRights;
chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true until_date:int = ChatBannedRights; chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true until_date:int = ChatBannedRights;
@ -1157,6 +1158,20 @@ help.country#c3878e23 flags:# hidden:flags.0?true iso2:string default_name:strin
help.countriesListNotModified#93cc1f32 = help.CountriesList; help.countriesListNotModified#93cc1f32 = help.CountriesList;
help.countriesList#87d0759e countries:Vector<help.Country> hash:int = help.CountriesList; help.countriesList#87d0759e countries:Vector<help.Country> hash:int = help.CountriesList;
messageViews#455b853d flags:# views:flags.0?int forwards:flags.1?int replies:flags.2?MessageReplies = MessageViews;
messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> users:Vector<User> = messages.MessageViews;
stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats;
messages.discussionMessage#6d64690e flags:# messages:Vector<Message> max_id:flags.0?int read_max_id:flags.1?int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
messageReplyHeader#a6d57763 flags:# reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader;
messageReplies#4128faac flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?int max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -1264,8 +1279,8 @@ contacts.getContacts#c023849f hash:int = contacts.Contacts;
contacts.importContacts#2c800be5 contacts:Vector<InputContact> = contacts.ImportedContacts; contacts.importContacts#2c800be5 contacts:Vector<InputContact> = contacts.ImportedContacts;
contacts.deleteContacts#96a0e00 id:Vector<InputUser> = Updates; contacts.deleteContacts#96a0e00 id:Vector<InputUser> = Updates;
contacts.deleteByPhones#1013fd9e phones:Vector<string> = Bool; contacts.deleteByPhones#1013fd9e phones:Vector<string> = Bool;
contacts.block#332b49fc id:InputUser = Bool; contacts.block#68cc1411 id:InputPeer = Bool;
contacts.unblock#e54100bd id:InputUser = Bool; contacts.unblock#bea65d50 id:InputPeer = Bool;
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked; contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
contacts.search#11f812d8 q:string limit:int = contacts.Found; contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer; contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer;
@ -1281,7 +1296,7 @@ contacts.getLocated#d348bc44 flags:# background:flags.1?true geo_point:InputGeoP
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages; messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs; messages.getDialogs#a0ee3b73 flags:# exclude_pinned:flags.0?true folder_id:flags.1?int offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:int = messages.Dialogs;
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages; messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
messages.search#8614ef68 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages; messages.search#4e17810b flags:# peer:InputPeer q:string from_id:flags.0?InputUser top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages; messages.readHistory#e306d3a peer:InputPeer max_id:int = messages.AffectedMessages;
messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory; messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory;
messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages; messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector<int> = messages.AffectedMessages;
@ -1289,7 +1304,7 @@ messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool; messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
messages.sendMessage#520c3870 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates; messages.sendMessage#520c3870 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates;
messages.sendMedia#3491eba9 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates; messages.sendMedia#3491eba9 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates;
messages.forwardMessages#d9fee60e flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true grouped:flags.9?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int = Updates; messages.forwardMessages#d9fee60e flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true from_peer:InputPeer id:Vector<int> random_id:Vector<long> to_peer:InputPeer schedule_date:flags.10?int = Updates;
messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.reportSpam#cf1592db peer:InputPeer = Bool;
messages.getPeerSettings#3672e09c peer:InputPeer = PeerSettings; messages.getPeerSettings#3672e09c peer:InputPeer = PeerSettings;
messages.report#bd82b658 peer:InputPeer id:Vector<int> reason:ReportReason = Bool; messages.report#bd82b658 peer:InputPeer id:Vector<int> reason:ReportReason = Bool;
@ -1322,10 +1337,10 @@ messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet
messages.installStickerSet#c78fe460 stickerset:InputStickerSet archived:Bool = messages.StickerSetInstallResult; messages.installStickerSet#c78fe460 stickerset:InputStickerSet archived:Bool = messages.StickerSetInstallResult;
messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool; messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_param:string = Updates; messages.startBot#e6df7378 bot:InputUser peer:InputPeer random_id:long start_param:string = Updates;
messages.getMessagesViews#c4c8a55d peer:InputPeer id:Vector<int> increment:Bool = Vector<int>; messages.getMessagesViews#5784d3e1 peer:InputPeer id:Vector<int> increment:Bool = messages.MessageViews;
messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool; messages.editChatAdmin#a9e69f2e chat_id:int user_id:InputUser is_admin:Bool = Bool;
messages.migrateChat#15a3b8e3 chat_id:int = Updates; messages.migrateChat#15a3b8e3 chat_id:int = Updates;
messages.searchGlobal#bf7225a4 flags:# folder_id:flags.0?int q:string offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages; messages.searchGlobal#4bc6589a flags:# folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
messages.reorderStickerSets#78337739 flags:# masks:flags.0?true order:Vector<long> = Bool; messages.reorderStickerSets#78337739 flags:# masks:flags.0?true order:Vector<long> = Bool;
messages.getDocumentByHash#338e2464 sha256:bytes size:int mime_type:string = Document; messages.getDocumentByHash#338e2464 sha256:bytes size:int mime_type:string = Document;
messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs; messages.getSavedGifs#83bf3d52 hash:int = messages.SavedGifs;
@ -1401,6 +1416,9 @@ messages.getSuggestedDialogFilters#a29cd42c = Vector<DialogFilterSuggested>;
messages.updateDialogFilter#1ad4a04a flags:# id:int filter:flags.0?DialogFilter = Bool; messages.updateDialogFilter#1ad4a04a flags:# id:int filter:flags.0?DialogFilter = Bool;
messages.updateDialogFiltersOrder#c563c1e4 order:Vector<int> = Bool; messages.updateDialogFiltersOrder#c563c1e4 order:Vector<int> = Bool;
messages.getOldFeaturedStickers#5fe7025b offset:int limit:int hash:int = messages.FeaturedStickers; messages.getOldFeaturedStickers#5fe7025b offset:int limit:int hash:int = messages.FeaturedStickers;
messages.getReplies#fda52fdc peer:InputPeer msg_id:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
messages.getDiscussionMessage#446972fd peer:InputPeer msg_id:int = messages.DiscussionMessage;
messages.readDiscussion#f731a9f4 peer:InputPeer msg_id:int read_max_id:int = Bool;
updates.getState#edd4882a = updates.State; updates.getState#edd4882a = updates.State;
updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference; updates.getDifference#25939651 flags:# pts:int pts_total_limit:flags.0?int date:int qts:int = updates.Difference;
@ -1462,7 +1480,7 @@ channels.joinChannel#24b524c5 channel:InputChannel = Updates;
channels.leaveChannel#f836aa95 channel:InputChannel = Updates; channels.leaveChannel#f836aa95 channel:InputChannel = Updates;
channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates; channels.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = Updates;
channels.deleteChannel#c0111fe3 channel:InputChannel = Updates; channels.deleteChannel#c0111fe3 channel:InputChannel = Updates;
channels.exportMessageLink#ceb77163 channel:InputChannel id:int grouped:Bool = ExportedMessageLink; channels.exportMessageLink#e63fadeb flags:# grouped:flags.0?true thread:flags.1?true channel:InputChannel id:int = ExportedMessageLink;
channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates; channels.toggleSignatures#1f69b606 channel:InputChannel enabled:Bool = Updates;
channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true = messages.Chats; channels.getAdminedPublicChannels#f8b036af flags:# by_location:flags.0?true check_limit:flags.1?true = messages.Chats;
channels.editBanned#72796912 channel:InputChannel user_id:InputUser banned_rights:ChatBannedRights = Updates; channels.editBanned#72796912 channel:InputChannel user_id:InputUser banned_rights:ChatBannedRights = Updates;
@ -1519,5 +1537,7 @@ folders.deleteFolder#1c295881 folder_id:int = Updates;
stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats; stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats;
stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph; stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats; stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats;
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
// LAYER 118 // LAYER 119

View file

@ -79,7 +79,7 @@ void SendExistingMedia(
auto clientFlags = NewMessageClientFlags(); auto clientFlags = NewMessageClientFlags();
auto sendFlags = MTPmessages_SendMedia::Flags(0); auto sendFlags = MTPmessages_SendMedia::Flags(0);
if (message.action.replyTo) { if (message.action.replyTo) {
flags |= MTPDmessage::Flag::f_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to;
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
} }
const auto channelPost = peer->isChannel() && !peer->isMegagroup(); const auto channelPost = peer->isChannel() && !peer->isMegagroup();
@ -89,7 +89,7 @@ void SendExistingMedia(
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent; sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
} }
auto messageFromId = channelPost ? 0 : session->userId(); auto messageFromId = channelPost ? 0 : session->userPeerId();
auto messagePostAuthor = channelPost ? session->user()->name : QString(); auto messagePostAuthor = channelPost ? session->user()->name : QString();
auto caption = TextWithEntities{ auto caption = TextWithEntities{
@ -249,9 +249,10 @@ bool SendDice(Api::MessageToSend &message) {
auto clientFlags = NewMessageClientFlags(); auto clientFlags = NewMessageClientFlags();
auto sendFlags = MTPmessages_SendMedia::Flags(0); auto sendFlags = MTPmessages_SendMedia::Flags(0);
if (message.action.replyTo) { if (message.action.replyTo) {
flags |= MTPDmessage::Flag::f_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to;
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
} }
const auto replyHeader = NewMessageReplyHeader(message.action);
const auto channelPost = peer->isChannel() && !peer->isMegagroup(); const auto channelPost = peer->isChannel() && !peer->isMegagroup();
const auto silentPost = message.action.options.silent const auto silentPost = message.action.options.silent
|| (channelPost && session->data().notifySilentPosts(peer)); || (channelPost && session->data().notifySilentPosts(peer));
@ -259,7 +260,7 @@ bool SendDice(Api::MessageToSend &message) {
if (silentPost) { if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent; sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
} }
auto messageFromId = channelPost ? 0 : session->userId(); auto messageFromId = channelPost ? 0 : session->userPeerId();
auto messagePostAuthor = channelPost ? session->user()->name : QString(); auto messagePostAuthor = channelPost ? session->user()->name : QString();
const auto replyTo = message.action.replyTo; const auto replyTo = message.action.replyTo;
@ -272,23 +273,27 @@ bool SendDice(Api::MessageToSend &message) {
session->data().registerMessageRandomId(randomId, newId); session->data().registerMessageRandomId(randomId, newId);
const auto views = 1;
const auto forwards = 0;
history->addNewMessage( history->addNewMessage(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), peerToMTP(messageFromId),
peerToMTP(history->peer->id), peerToMTP(history->peer->id),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTP_int(0), MTPint(), // via_bot_id
MTP_int(replyTo), replyHeader,
MTP_int(HistoryItem::NewMessageDate( MTP_int(HistoryItem::NewMessageDate(
message.action.options.scheduled)), message.action.options.scheduled)),
MTP_string(), MTP_string(),
MTP_messageMediaDice(MTP_int(0), MTP_string(emoji)), MTP_messageMediaDice(MTP_int(0), MTP_string(emoji)),
MTPReplyMarkup(), MTPReplyMarkup(),
MTP_vector<MTPMessageEntity>(), MTP_vector<MTPMessageEntity>(),
MTP_int(1), MTP_int(views),
MTPint(), MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor), MTP_string(messagePostAuthor),
MTPlong(), MTPlong(),
//MTPMessageReactions(), //MTPMessageReactions(),
@ -387,8 +392,9 @@ void SendConfirmedFile(
| MTPDmessage::Flag::f_media; | MTPDmessage::Flag::f_media;
auto clientFlags = NewMessageClientFlags(); auto clientFlags = NewMessageClientFlags();
if (file->to.replyTo) { if (file->to.replyTo) {
flags |= MTPDmessage::Flag::f_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to;
} }
const auto replyHeader = NewMessageReplyHeader(action);
const auto channelPost = peer->isChannel() && !peer->isMegagroup(); const auto channelPost = peer->isChannel() && !peer->isMegagroup();
const auto silentPost = file->to.options.silent; const auto silentPost = file->to.options.silent;
Api::FillMessagePostFlags(action, peer, flags); Api::FillMessagePostFlags(action, peer, flags);
@ -406,11 +412,13 @@ void SendConfirmedFile(
clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry; clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry;
} }
const auto messageFromId = channelPost ? 0 : session->userId(); const auto messageFromId = channelPost ? 0 : session->userPeerId();
const auto messagePostAuthor = channelPost const auto messagePostAuthor = channelPost
? session->user()->name ? session->user()->name
: QString(); : QString();
const auto views = 1;
const auto forwards = 0;
if (file->type == SendMediaType::Photo) { if (file->type == SendMediaType::Photo) {
const auto photoFlags = MTPDmessageMediaPhoto::Flag::f_photo | 0; const auto photoFlags = MTPDmessageMediaPhoto::Flag::f_photo | 0;
const auto photo = MTP_messageMediaPhoto( const auto photo = MTP_messageMediaPhoto(
@ -421,18 +429,20 @@ void SendConfirmedFile(
const auto mtpMessage = MTP_message( const auto mtpMessage = MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), peerToMTP(messageFromId),
peerToMTP(file->to.peer), peerToMTP(file->to.peer),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTP_int(file->to.replyTo), replyHeader,
MTP_int(HistoryItem::NewMessageDate(file->to.options.scheduled)), MTP_int(HistoryItem::NewMessageDate(file->to.options.scheduled)),
MTP_string(caption.text), MTP_string(caption.text),
photo, photo,
MTPReplyMarkup(), MTPReplyMarkup(),
localEntities, localEntities,
MTP_int(1), MTP_int(views),
MTPint(), MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor), MTP_string(messagePostAuthor),
MTP_long(groupId), MTP_long(groupId),
//MTPMessageReactions(), //MTPMessageReactions(),
@ -457,18 +467,20 @@ void SendConfirmedFile(
const auto mtpMessage = MTP_message( const auto mtpMessage = MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), peerToMTP(messageFromId),
peerToMTP(file->to.peer), peerToMTP(file->to.peer),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTP_int(file->to.replyTo), replyHeader,
MTP_int(HistoryItem::NewMessageDate(file->to.options.scheduled)), MTP_int(HistoryItem::NewMessageDate(file->to.options.scheduled)),
MTP_string(caption.text), MTP_string(caption.text),
document, document,
MTPReplyMarkup(), MTPReplyMarkup(),
localEntities, localEntities,
MTP_int(1), MTP_int(views),
MTPint(), MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor), MTP_string(messagePostAuthor),
MTP_long(groupId), MTP_long(groupId),
//MTPMessageReactions(), //MTPMessageReactions(),
@ -496,19 +508,21 @@ void SendConfirmedFile(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), peerToMTP(messageFromId),
peerToMTP(file->to.peer), peerToMTP(file->to.peer),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTP_int(file->to.replyTo), replyHeader,
MTP_int( MTP_int(
HistoryItem::NewMessageDate(file->to.options.scheduled)), HistoryItem::NewMessageDate(file->to.options.scheduled)),
MTP_string(caption.text), MTP_string(caption.text),
document, document,
MTPReplyMarkup(), MTPReplyMarkup(),
localEntities, localEntities,
MTP_int(1), MTP_int(views),
MTPint(), MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor), MTP_string(messagePostAuthor),
MTP_long(groupId), MTP_long(groupId),
//MTPMessageReactions(), //MTPMessageReactions(),

View file

@ -97,20 +97,9 @@ bool ForwardedInfoDataLoaded(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const MTPMessageFwdHeader &header) { const MTPMessageFwdHeader &header) {
return header.match([&](const MTPDmessageFwdHeader &data) { return header.match([&](const MTPDmessageFwdHeader &data) {
if (const auto channelId = data.vchannel_id()) { if (const auto fromId = data.vfrom_id()) {
if (!session->data().channelLoaded(channelId->v)) {
return false;
}
if (const auto fromId = data.vfrom_id()) {
const auto from = session->data().user(fromId->v);
// Minimal loaded is fine in this case.
if (from->loadedStatus == PeerData::NotLoaded) {
return false;
}
}
} else if (const auto fromId = data.vfrom_id()) {
// Fully loaded is required in this case. // Fully loaded is required in this case.
if (!session->data().userLoaded(fromId->v)) { if (!session->data().peerLoaded(peerFromMTP(*fromId))) {
return false; return false;
} }
} }
@ -145,7 +134,7 @@ DataIsLoadedResult AllDataLoadedForMessage(
return message.match([&](const MTPDmessage &message) { return message.match([&](const MTPDmessage &message) {
if (const auto fromId = message.vfrom_id()) { if (const auto fromId = message.vfrom_id()) {
if (!message.is_post() if (!message.is_post()
&& !session->data().userLoaded(fromId->v)) { && !session->data().peerLoaded(peerFromMTP(*fromId))) {
return DataIsLoadedResult::FromNotLoaded; return DataIsLoadedResult::FromNotLoaded;
} }
} }
@ -168,7 +157,7 @@ DataIsLoadedResult AllDataLoadedForMessage(
}, [&](const MTPDmessageService &message) { }, [&](const MTPDmessageService &message) {
if (const auto fromId = message.vfrom_id()) { if (const auto fromId = message.vfrom_id()) {
if (!message.is_post() if (!message.is_post()
&& !session->data().userLoaded(fromId->v)) { && !session->data().peerLoaded(peerFromMTP(*fromId))) {
return DataIsLoadedResult::FromNotLoaded; return DataIsLoadedResult::FromNotLoaded;
} }
} }
@ -890,23 +879,26 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
const auto peerUserId = d.is_out() const auto peerUserId = d.is_out()
? d.vuser_id() ? d.vuser_id()
: MTP_int(_session->userId()); : MTP_int(_session->userId());
const auto fwd = d.vfwd_from();
_session->data().addNewMessage( _session->data().addNewMessage(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
d.vid(), d.vid(),
d.is_out() ? MTP_int(_session->userId()) : d.vuser_id(), (d.is_out()
MTP_peerUser(peerUserId), ? peerToMTP(_session->userPeerId())
fwd ? (*fwd) : MTPMessageFwdHeader(), : MTP_peerUser(d.vuser_id())),
MTP_peerUser(d.vuser_id()),
d.vfwd_from() ? *d.vfwd_from() : MTPMessageFwdHeader(),
MTP_int(d.vvia_bot_id().value_or_empty()), MTP_int(d.vvia_bot_id().value_or_empty()),
MTP_int(d.vreply_to_msg_id().value_or_empty()), d.vreply_to() ? *d.vreply_to() : MTPMessageReplyHeader(),
d.vdate(), d.vdate(),
d.vmessage(), d.vmessage(),
MTP_messageMediaEmpty(), MTP_messageMediaEmpty(),
MTPReplyMarkup(), MTPReplyMarkup(),
MTP_vector<MTPMessageEntity>(d.ventities().value_or_empty()), MTP_vector<MTPMessageEntity>(d.ventities().value_or_empty()),
MTPint(), MTPint(), // views
MTPint(), MTPint(), // forwards
MTPMessageReplies(),
MTPint(), // edit_date
MTPstring(), MTPstring(),
MTPlong(), MTPlong(),
//MTPMessageReactions(), //MTPMessageReactions(),
@ -917,24 +909,26 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
case mtpc_updateShortChatMessage: { case mtpc_updateShortChatMessage: {
const auto &d = updates.c_updateShortChatMessage(); const auto &d = updates.c_updateShortChatMessage();
const auto flags = mtpCastFlags(d.vflags().v) | MTPDmessage::Flag::f_from_id; const auto flags = mtpCastFlags(d.vflags().v)
const auto fwd = d.vfwd_from(); | MTPDmessage::Flag::f_from_id;
_session->data().addNewMessage( _session->data().addNewMessage(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
d.vid(), d.vid(),
d.vfrom_id(), MTP_peerUser(d.vfrom_id()),
MTP_peerChat(d.vchat_id()), MTP_peerChat(d.vchat_id()),
fwd ? (*fwd) : MTPMessageFwdHeader(), d.vfwd_from() ? *d.vfwd_from() : MTPMessageFwdHeader(),
MTP_int(d.vvia_bot_id().value_or_empty()), MTP_int(d.vvia_bot_id().value_or_empty()),
MTP_int(d.vreply_to_msg_id().value_or_empty()), d.vreply_to() ? *d.vreply_to() : MTPMessageReplyHeader(),
d.vdate(), d.vdate(),
d.vmessage(), d.vmessage(),
MTP_messageMediaEmpty(), MTP_messageMediaEmpty(),
MTPReplyMarkup(), MTPReplyMarkup(),
MTP_vector<MTPMessageEntity>(d.ventities().value_or_empty()), MTP_vector<MTPMessageEntity>(d.ventities().value_or_empty()),
MTPint(), MTPint(), // views
MTPint(), MTPint(), // forwards
MTPMessageReplies(),
MTPint(), // edit_date
MTPstring(), MTPstring(),
MTPlong(), MTPlong(),
//MTPMessageReactions(), //MTPMessageReactions(),
@ -1731,10 +1725,10 @@ void Updates::feedUpdate(const MTPUpdate &update) {
Core::App().calls().handleUpdate(&session(), update); Core::App().calls().handleUpdate(&session(), update);
} break; } break;
case mtpc_updateUserBlocked: { case mtpc_updatePeerBlocked: {
const auto &d = update.c_updateUserBlocked(); const auto &d = update.c_updatePeerBlocked();
if (const auto user = session().data().userLoaded(d.vuser_id().v)) { if (const auto peer = session().data().peerLoaded(peerFromMTP(d.vpeer_id()))) {
user->setIsBlocked(mtpIsTrue(d.vblocked())); peer->setIsBlocked(mtpIsTrue(d.vblocked()));
} }
} break; } break;
@ -1912,12 +1906,19 @@ void Updates::feedUpdate(const MTPUpdate &update) {
} break; } break;
case mtpc_updateChannelMessageViews: { case mtpc_updateChannelMessageViews: {
auto &d = update.c_updateChannelMessageViews(); const auto &d = update.c_updateChannelMessageViews();
if (auto item = session().data().message(d.vchannel_id().v, d.vid().v)) { if (const auto item = session().data().message(d.vchannel_id().v, d.vid().v)) {
item->setViewsCount(d.vviews().v); item->setViewsCount(d.vviews().v);
} }
} break; } break;
case mtpc_updateChannelMessageForwards: {
const auto &d = update.c_updateChannelMessageForwards();
if (const auto item = session().data().message(d.vchannel_id().v, d.vid().v)) {
item->setForwardsCount(d.vforwards().v);
}
} break;
case mtpc_updateChannelAvailableMessages: { case mtpc_updateChannelAvailableMessages: {
auto &d = update.c_updateChannelAvailableMessages(); auto &d = update.c_updateChannelAvailableMessages();
if (const auto channel = session().data().channelLoaded(d.vchannel_id().v)) { if (const auto channel = session().data().channelLoaded(d.vchannel_id().v)) {

View file

@ -158,19 +158,19 @@ std::optional<ApiWrap::Privacy::Key> ApiWrap::Privacy::KeyFromMTP(
return std::nullopt; return std::nullopt;
} }
bool ApiWrap::BlockedUsersSlice::Item::operator==(const Item &other) const { bool ApiWrap::BlockedPeersSlice::Item::operator==(const Item &other) const {
return (user == other.user) && (date == other.date); return (peer == other.peer) && (date == other.date);
} }
bool ApiWrap::BlockedUsersSlice::Item::operator!=(const Item &other) const { bool ApiWrap::BlockedPeersSlice::Item::operator!=(const Item &other) const {
return !(*this == other); return !(*this == other);
} }
bool ApiWrap::BlockedUsersSlice::operator==(const BlockedUsersSlice &other) const { bool ApiWrap::BlockedPeersSlice::operator==(const BlockedPeersSlice &other) const {
return (total == other.total) && (list == other.list); return (total == other.total) && (list == other.list);
} }
bool ApiWrap::BlockedUsersSlice::operator!=(const BlockedUsersSlice &other) const { bool ApiWrap::BlockedPeersSlice::operator!=(const BlockedPeersSlice &other) const {
return !(*this == other); return !(*this == other);
} }
@ -709,9 +709,9 @@ QString ApiWrap::exportDirectMessageLink(not_null<HistoryItem*> item) {
? i->second ? i->second
: fallback(); : fallback();
request(MTPchannels_ExportMessageLink( request(MTPchannels_ExportMessageLink(
MTP_flags(0),
channel->inputChannel, channel->inputChannel,
MTP_int(item->id), MTP_int(item->id)
MTP_bool(false)
)).done([=](const MTPExportedMessageLink &result) { )).done([=](const MTPExportedMessageLink &result) {
const auto link = result.match([&](const auto &data) { const auto link = result.match([&](const auto &data) {
return qs(data.vlink()); return qs(data.vlink());
@ -2003,64 +2003,66 @@ void ApiWrap::leaveChannel(not_null<ChannelData*> channel) {
} }
} }
void ApiWrap::blockUser(not_null<UserData*> user) { void ApiWrap::blockPeer(not_null<PeerData*> peer) {
if (user->isBlocked()) { if (peer->isBlocked()) {
session().changes().peerUpdated( session().changes().peerUpdated(
user, peer,
Data::PeerUpdate::Flag::IsBlocked); Data::PeerUpdate::Flag::IsBlocked);
} else if (_blockRequests.find(user) == end(_blockRequests)) { } else if (_blockRequests.find(peer) == end(_blockRequests)) {
const auto requestId = request(MTPcontacts_Block(user->inputUser)).done([this, user](const MTPBool &result) { const auto requestId = request(MTPcontacts_Block(
_blockRequests.erase(user); peer->input
user->setIsBlocked(true); )).done([=](const MTPBool &result) {
if (_blockedUsersSlice) { _blockRequests.erase(peer);
_blockedUsersSlice->list.insert( peer->setIsBlocked(true);
_blockedUsersSlice->list.begin(), if (_blockedPeersSlice) {
{ user, base::unixtime::now() }); _blockedPeersSlice->list.insert(
++_blockedUsersSlice->total; _blockedPeersSlice->list.begin(),
_blockedUsersChanges.fire_copy(*_blockedUsersSlice); { peer, base::unixtime::now() });
++_blockedPeersSlice->total;
_blockedPeersChanges.fire_copy(*_blockedPeersSlice);
} }
}).fail([this, user](const RPCError &error) { }).fail([=](const RPCError &error) {
_blockRequests.erase(user); _blockRequests.erase(peer);
}).send(); }).send();
_blockRequests.emplace(user, requestId); _blockRequests.emplace(peer, requestId);
} }
} }
void ApiWrap::unblockUser(not_null<UserData*> user, Fn<void()> onDone) { void ApiWrap::unblockPeer(not_null<PeerData*> peer, Fn<void()> onDone) {
if (!user->isBlocked()) { if (!peer->isBlocked()) {
session().changes().peerUpdated( session().changes().peerUpdated(
user, peer,
Data::PeerUpdate::Flag::IsBlocked); Data::PeerUpdate::Flag::IsBlocked);
return; return;
} else if (_blockRequests.find(user) != end(_blockRequests)) { } else if (_blockRequests.find(peer) != end(_blockRequests)) {
return; return;
} }
const auto requestId = request(MTPcontacts_Unblock( const auto requestId = request(MTPcontacts_Unblock(
user->inputUser peer->input
)).done([=](const MTPBool &result) { )).done([=](const MTPBool &result) {
_blockRequests.erase(user); _blockRequests.erase(peer);
user->setIsBlocked(false); peer->setIsBlocked(false);
if (_blockedUsersSlice) { if (_blockedPeersSlice) {
auto &list = _blockedUsersSlice->list; auto &list = _blockedPeersSlice->list;
for (auto i = list.begin(); i != list.end(); ++i) { for (auto i = list.begin(); i != list.end(); ++i) {
if (i->user == user) { if (i->peer == peer) {
list.erase(i); list.erase(i);
break; break;
} }
} }
if (_blockedUsersSlice->total > list.size()) { if (_blockedPeersSlice->total > list.size()) {
--_blockedUsersSlice->total; --_blockedPeersSlice->total;
} }
_blockedUsersChanges.fire_copy(*_blockedUsersSlice); _blockedPeersChanges.fire_copy(*_blockedPeersSlice);
} }
if (onDone) { if (onDone) {
onDone(); onDone();
} }
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
_blockRequests.erase(user); _blockRequests.erase(peer);
}).send(); }).send();
_blockRequests.emplace(user, requestId); _blockRequests.emplace(peer, requestId);
} }
void ApiWrap::exportInviteLink(not_null<PeerData*> peer) { void ApiWrap::exportInviteLink(not_null<PeerData*> peer) {
@ -2203,7 +2205,7 @@ void ApiWrap::handlePrivacyChange(
void ApiWrap::updatePrivacyLastSeens(const QVector<MTPPrivacyRule> &rules) { void ApiWrap::updatePrivacyLastSeens(const QVector<MTPPrivacyRule> &rules) {
const auto now = base::unixtime::now(); const auto now = base::unixtime::now();
_session->data().enumerateUsers([&](UserData *user) { _session->data().enumerateUsers([&](UserData *user) {
if (user->isSelf() || user->loadedStatus != PeerData::FullLoaded) { if (user->isSelf() || !user->isFullLoaded()) {
return; return;
} }
if (user->onlineTill <= 0) { if (user->onlineTill <= 0) {
@ -3915,7 +3917,6 @@ void ApiWrap::forwardMessages(
} }
auto forwardFrom = items.front()->history()->peer; auto forwardFrom = items.front()->history()->peer;
auto currentGroupId = items.front()->groupId();
auto ids = QVector<MTPint>(); auto ids = QVector<MTPint>();
auto randomIds = QVector<MTPlong>(); auto randomIds = QVector<MTPlong>();
auto localIds = std::shared_ptr<base::flat_map<uint64, FullMsgId>>(); auto localIds = std::shared_ptr<base::flat_map<uint64, FullMsgId>>();
@ -3924,14 +3925,10 @@ void ApiWrap::forwardMessages(
if (shared) { if (shared) {
++shared->requestsLeft; ++shared->requestsLeft;
} }
const auto finalFlags = sendFlags
| (currentGroupId == MessageGroupId()
? MTPmessages_ForwardMessages::Flag(0)
: MTPmessages_ForwardMessages::Flag::f_grouped);
const auto requestType = Data::Histories::RequestType::Send; const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) { histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_ForwardMessages( history->sendRequestId = request(MTPmessages_ForwardMessages(
MTP_flags(finalFlags), MTP_flags(sendFlags),
forwardFrom->input, forwardFrom->input,
MTP_vector<MTPint>(ids), MTP_vector<MTPint>(ids),
MTP_vector<MTPlong>(randomIds), MTP_vector<MTPlong>(randomIds),
@ -3974,8 +3971,8 @@ void ApiWrap::forwardMessages(
_session->data().nextLocalMessageId()); _session->data().nextLocalMessageId());
const auto self = _session->user(); const auto self = _session->user();
const auto messageFromId = channelPost const auto messageFromId = channelPost
? UserId(0) ? PeerId(0)
: peerToUser(self->id); : self->id;
const auto messagePostAuthor = channelPost const auto messagePostAuthor = channelPost
? self->name ? self->name
: QString(); : QString();
@ -3996,11 +3993,9 @@ void ApiWrap::forwardMessages(
} }
const auto newFrom = item->history()->peer; const auto newFrom = item->history()->peer;
const auto newGroupId = item->groupId(); const auto newGroupId = item->groupId();
if (forwardFrom != newFrom if (forwardFrom != newFrom) {
|| currentGroupId != newGroupId) {
sendAccumulated(); sendAccumulated();
forwardFrom = newFrom; forwardFrom = newFrom;
currentGroupId = newGroupId;
} }
ids.push_back(MTP_int(item->id)); ids.push_back(MTP_int(item->id));
randomIds.push_back(MTP_long(randomId)); randomIds.push_back(MTP_long(randomId));
@ -4053,15 +4048,16 @@ void ApiWrap::sendSharedContact(
auto flags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media; auto flags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media;
auto clientFlags = NewMessageClientFlags(); auto clientFlags = NewMessageClientFlags();
if (action.replyTo) { if (action.replyTo) {
flags |= MTPDmessage::Flag::f_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to;
} }
const auto replyHeader = NewMessageReplyHeader(action);
FillMessagePostFlags(action, peer, flags); FillMessagePostFlags(action, peer, flags);
if (action.options.scheduled) { if (action.options.scheduled) {
flags |= MTPDmessage::Flag::f_from_scheduled; flags |= MTPDmessage::Flag::f_from_scheduled;
} else { } else {
clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry; clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry;
} }
const auto messageFromId = channelPost ? 0 : _session->userId(); const auto messageFromId = channelPost ? 0 : _session->userPeerId();
const auto messagePostAuthor = channelPost const auto messagePostAuthor = channelPost
? _session->user()->name ? _session->user()->name
: QString(); : QString();
@ -4072,11 +4068,11 @@ void ApiWrap::sendSharedContact(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), peerToMTP(messageFromId),
peerToMTP(peer->id), peerToMTP(peer->id),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTPint(), MTPint(), // via_bot_id
MTP_int(action.replyTo), replyHeader,
MTP_int(HistoryItem::NewMessageDate(action.options.scheduled)), MTP_int(HistoryItem::NewMessageDate(action.options.scheduled)),
MTP_string(), MTP_string(),
MTP_messageMediaContact( MTP_messageMediaContact(
@ -4088,7 +4084,9 @@ void ApiWrap::sendSharedContact(
MTPReplyMarkup(), MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(), MTPVector<MTPMessageEntity>(),
MTP_int(views), MTP_int(views),
MTPint(), MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor), MTP_string(messagePostAuthor),
MTPlong(), MTPlong(),
//MTPMessageReactions(), //MTPMessageReactions(),
@ -4310,9 +4308,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
auto clientFlags = NewMessageClientFlags(); auto clientFlags = NewMessageClientFlags();
auto sendFlags = MTPmessages_SendMessage::Flags(0); auto sendFlags = MTPmessages_SendMessage::Flags(0);
if (action.replyTo) { if (action.replyTo) {
flags |= MTPDmessage::Flag::f_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to;
sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to_msg_id; sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to_msg_id;
} }
const auto replyHeader = NewMessageReplyHeader(action);
MTPMessageMedia media = MTP_messageMediaEmpty(); MTPMessageMedia media = MTP_messageMediaEmpty();
if (message.webPageId == CancelledWebPageId) { if (message.webPageId == CancelledWebPageId) {
sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage; sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;
@ -4346,7 +4345,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
history->clearCloudDraft(); history->clearCloudDraft();
history->setSentDraftText(QString()); history->setSentDraftText(QString());
} }
auto messageFromId = channelPost ? 0 : _session->userId(); auto messageFromId = channelPost ? 0 : _session->userPeerId();
auto messagePostAuthor = channelPost auto messagePostAuthor = channelPost
? _session->user()->name ? _session->user()->name
: QString(); : QString();
@ -4356,23 +4355,27 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
} else { } else {
clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry; clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry;
} }
const auto views = 1;
const auto forwards = 0;
lastMessage = history->addNewMessage( lastMessage = history->addNewMessage(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), peerToMTP(messageFromId),
peerToMTP(peer->id), peerToMTP(peer->id),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTPint(), MTPint(), // via_bot_id
MTP_int(action.replyTo), replyHeader,
MTP_int( MTP_int(
HistoryItem::NewMessageDate(action.options.scheduled)), HistoryItem::NewMessageDate(action.options.scheduled)),
msgText, msgText,
media, media,
MTPReplyMarkup(), MTPReplyMarkup(),
localEntities, localEntities,
MTP_int(1), MTP_int(views),
MTPint(), MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor), MTP_string(messagePostAuthor),
MTPlong(), MTPlong(),
//MTPMessageReactions(), //MTPMessageReactions(),
@ -4459,7 +4462,7 @@ void ApiWrap::sendInlineResult(
auto clientFlags = NewMessageClientFlags(); auto clientFlags = NewMessageClientFlags();
auto sendFlags = MTPmessages_SendInlineBotResult::Flag::f_clear_draft | 0; auto sendFlags = MTPmessages_SendInlineBotResult::Flag::f_clear_draft | 0;
if (action.replyTo) { if (action.replyTo) {
flags |= MTPDmessage::Flag::f_reply_to_msg_id; flags |= MTPDmessage::Flag::f_reply_to;
sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_reply_to_msg_id; sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_reply_to_msg_id;
} }
bool channelPost = peer->isChannel() && !peer->isMegagroup(); bool channelPost = peer->isChannel() && !peer->isMegagroup();
@ -4479,7 +4482,7 @@ void ApiWrap::sendInlineResult(
clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry; clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry;
} }
const auto messageFromId = channelPost ? 0 : _session->userId(); const auto messageFromId = channelPost ? 0 : _session->userPeerId();
const auto messagePostAuthor = channelPost const auto messagePostAuthor = channelPost
? _session->user()->name ? _session->user()->name
: QString(); : QString();
@ -5119,34 +5122,34 @@ auto ApiWrap::privacyValue(Privacy::Key key) -> rpl::producer<Privacy> {
} }
} }
void ApiWrap::reloadBlockedUsers() { void ApiWrap::reloadBlockedPeers() {
if (_blockedUsersRequestId) { if (_blockedPeersRequestId) {
return; return;
} }
_blockedUsersRequestId = request(MTPcontacts_GetBlocked( _blockedPeersRequestId = request(MTPcontacts_GetBlocked(
MTP_int(0), MTP_int(0),
MTP_int(kBlockedFirstSlice) MTP_int(kBlockedFirstSlice)
)).done([=](const MTPcontacts_Blocked &result) { )).done([=](const MTPcontacts_Blocked &result) {
_blockedUsersRequestId = 0; _blockedPeersRequestId = 0;
const auto push = [&]( const auto push = [&](
int count, int count,
const QVector<MTPContactBlocked> &list) { const QVector<MTPPeerBlocked> &list) {
auto slice = BlockedUsersSlice(); auto slice = BlockedPeersSlice();
slice.total = std::max(count, list.size()); slice.total = std::max(count, list.size());
slice.list.reserve(list.size()); slice.list.reserve(list.size());
for (const auto &contact : list) { for (const auto &contact : list) {
contact.match([&](const MTPDcontactBlocked &data) { contact.match([&](const MTPDpeerBlocked &data) {
const auto user = _session->data().userLoaded( const auto peer = _session->data().peerLoaded(
data.vuser_id().v); peerFromMTP(data.vpeer_id()));
if (user) { if (peer) {
user->setIsBlocked(true); peer->setIsBlocked(true);
slice.list.push_back({ user, data.vdate().v }); slice.list.push_back({ peer, data.vdate().v });
} }
}); });
} }
if (!_blockedUsersSlice || *_blockedUsersSlice != slice) { if (!_blockedPeersSlice || *_blockedPeersSlice != slice) {
_blockedUsersSlice = slice; _blockedPeersSlice = slice;
_blockedUsersChanges.fire(std::move(slice)); _blockedPeersChanges.fire(std::move(slice));
} }
}; };
result.match([&](const MTPDcontacts_blockedSlice &data) { result.match([&](const MTPDcontacts_blockedSlice &data) {
@ -5157,17 +5160,17 @@ void ApiWrap::reloadBlockedUsers() {
push(0, data.vblocked().v); push(0, data.vblocked().v);
}); });
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
_blockedUsersRequestId = 0; _blockedPeersRequestId = 0;
}).send(); }).send();
} }
auto ApiWrap::blockedUsersSlice() -> rpl::producer<BlockedUsersSlice> { auto ApiWrap::blockedPeersSlice() -> rpl::producer<BlockedPeersSlice> {
if (!_blockedUsersSlice) { if (!_blockedPeersSlice) {
reloadBlockedUsers(); reloadBlockedPeers();
} }
return _blockedUsersSlice return _blockedPeersSlice
? _blockedUsersChanges.events_starting_with_copy(*_blockedUsersSlice) ? _blockedPeersChanges.events_starting_with_copy(*_blockedPeersSlice)
: (_blockedUsersChanges.events() | rpl::type_erased()); : (_blockedPeersChanges.events() | rpl::type_erased());
} }
Api::SelfDestruct &ApiWrap::selfDestruct() { Api::SelfDestruct &ApiWrap::selfDestruct() {

View file

@ -121,9 +121,9 @@ public:
static std::optional<Key> KeyFromMTP(mtpTypeId type); static std::optional<Key> KeyFromMTP(mtpTypeId type);
}; };
struct BlockedUsersSlice { struct BlockedPeersSlice {
struct Item { struct Item {
UserData *user = nullptr; PeerData *peer = nullptr;
TimeId date = 0; TimeId date = 0;
bool operator==(const Item &other) const; bool operator==(const Item &other) const;
@ -133,8 +133,8 @@ public:
QVector<Item> list; QVector<Item> list;
int total = 0; int total = 0;
bool operator==(const BlockedUsersSlice &other) const; bool operator==(const BlockedPeersSlice &other) const;
bool operator!=(const BlockedUsersSlice &other) const; bool operator!=(const BlockedPeersSlice &other) const;
}; };
explicit ApiWrap(not_null<Main::Session*> session); explicit ApiWrap(not_null<Main::Session*> session);
@ -279,8 +279,8 @@ public:
void joinChannel(not_null<ChannelData*> channel); void joinChannel(not_null<ChannelData*> channel);
void leaveChannel(not_null<ChannelData*> channel); void leaveChannel(not_null<ChannelData*> channel);
void blockUser(not_null<UserData*> user); void blockPeer(not_null<PeerData*> peer);
void unblockUser(not_null<UserData*> user, Fn<void()> onDone = nullptr); void unblockPeer(not_null<PeerData*> peer, Fn<void()> onDone = nullptr);
void exportInviteLink(not_null<PeerData*> peer); void exportInviteLink(not_null<PeerData*> peer);
void requestNotifySettings(const MTPInputNotifyPeer &peer); void requestNotifySettings(const MTPInputNotifyPeer &peer);
@ -448,8 +448,8 @@ public:
void reloadPrivacy(Privacy::Key key); void reloadPrivacy(Privacy::Key key);
rpl::producer<Privacy> privacyValue(Privacy::Key key); rpl::producer<Privacy> privacyValue(Privacy::Key key);
void reloadBlockedUsers(); void reloadBlockedPeers();
rpl::producer<BlockedUsersSlice> blockedUsersSlice(); rpl::producer<BlockedPeersSlice> blockedPeersSlice();
[[nodiscard]] Api::SelfDestruct &selfDestruct(); [[nodiscard]] Api::SelfDestruct &selfDestruct();
[[nodiscard]] Api::SensitiveContent &sensitiveContent(); [[nodiscard]] Api::SensitiveContent &sensitiveContent();
@ -690,7 +690,7 @@ private:
QMap<uint64, QPair<uint64, mtpRequestId> > _stickerSetRequests; QMap<uint64, QPair<uint64, mtpRequestId> > _stickerSetRequests;
QMap<ChannelData*, mtpRequestId> _channelAmInRequests; QMap<ChannelData*, mtpRequestId> _channelAmInRequests;
base::flat_map<not_null<UserData*>, mtpRequestId> _blockRequests; base::flat_map<not_null<PeerData*>, mtpRequestId> _blockRequests;
base::flat_map<not_null<PeerData*>, mtpRequestId> _exportInviteRequests; base::flat_map<not_null<PeerData*>, mtpRequestId> _exportInviteRequests;
base::flat_map<PeerId, mtpRequestId> _notifySettingRequests; base::flat_map<PeerId, mtpRequestId> _notifySettingRequests;
base::flat_map<not_null<History*>, mtpRequestId> _draftsSaveRequestIds; base::flat_map<not_null<History*>, mtpRequestId> _draftsSaveRequestIds;
@ -809,9 +809,9 @@ private:
base::flat_map<Privacy::Key, Privacy> _privacyValues; base::flat_map<Privacy::Key, Privacy> _privacyValues;
std::map<Privacy::Key, rpl::event_stream<Privacy>> _privacyChanges; std::map<Privacy::Key, rpl::event_stream<Privacy>> _privacyChanges;
mtpRequestId _blockedUsersRequestId = 0; mtpRequestId _blockedPeersRequestId = 0;
std::optional<BlockedUsersSlice> _blockedUsersSlice; std::optional<BlockedPeersSlice> _blockedPeersSlice;
rpl::event_stream<BlockedUsersSlice> _blockedUsersChanges; rpl::event_stream<BlockedPeersSlice> _blockedPeersChanges;
const std::unique_ptr<Api::SelfDestruct> _selfDestruct; const std::unique_ptr<Api::SelfDestruct> _selfDestruct;
const std::unique_ptr<Api::SensitiveContent> _sensitiveContent; const std::unique_ptr<Api::SensitiveContent> _sensitiveContent;

View file

@ -618,6 +618,7 @@ void AddSpecialBoxController::editAdminDone(
_additional.applyParticipant(MTP_channelParticipantCreator( _additional.applyParticipant(MTP_channelParticipantCreator(
MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank), MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank),
MTP_int(user->bareId()), MTP_int(user->bareId()),
MTP_chatAdminRights(MTP_flags(0)), // #TODO anonymous
MTP_string(rank))); MTP_string(rank)));
} else if (rights.c_chatAdminRights().vflags().v == 0) { } else if (rights.c_chatAdminRights().vflags().v == 0) {
_additional.applyParticipant(MTP_channelParticipant( _additional.applyParticipant(MTP_channelParticipant(

View file

@ -1504,6 +1504,7 @@ void ParticipantsBoxController::editAdminDone(
_additional.applyParticipant(MTP_channelParticipantCreator( _additional.applyParticipant(MTP_channelParticipantCreator(
MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank), MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank),
MTP_int(user->bareId()), MTP_int(user->bareId()),
MTP_chatAdminRights(MTP_flags(0)), // #TODO anonymous
MTP_string(rank))); MTP_string(rank)));
} else if (rights.c_chatAdminRights().vflags().v == 0) { } else if (rights.c_chatAdminRights().vflags().v == 0) {
_additional.applyParticipant(MTP_channelParticipant( _additional.applyParticipant(MTP_channelParticipant(

View file

@ -294,6 +294,7 @@ void BoxController::loadMoreRows() {
MTP_inputPeerEmpty(), MTP_inputPeerEmpty(),
MTP_string(), MTP_string(),
MTP_inputUserEmpty(), MTP_inputUserEmpty(),
MTPint(), // top_msg_id
MTP_inputMessagesFilterPhoneCalls(MTP_flags(0)), MTP_inputMessagesFilterPhoneCalls(MTP_flags(0)),
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),

View file

@ -53,6 +53,7 @@ generate({
'ipPortSecret#37982646', 'ipPortSecret#37982646',
'accessPointRule#4679b65f', 'accessPointRule#4679b65f',
'help.configSimple#5a592a6c', 'help.configSimple#5a592a6c',
'messageReplies#81834865',
], ],
'renamedTypes': { 'renamedTypes': {

View file

@ -58,12 +58,12 @@ struct PeerUpdate {
Migration = (1 << 5), Migration = (1 << 5),
UnavailableReason = (1 << 6), UnavailableReason = (1 << 6),
PinnedMessage = (1 << 7), PinnedMessage = (1 << 7),
IsBlocked = (1 << 8),
// For users // For users
CanShareContact = (1 << 8), CanShareContact = (1 << 9),
IsContact = (1 << 9), IsContact = (1 << 10),
PhoneNumber = (1 << 10), PhoneNumber = (1 << 11),
IsBlocked = (1 << 11),
OnlineStatus = (1 << 12), OnlineStatus = (1 << 12),
BotCommands = (1 << 13), BotCommands = (1 << 13),
BotCanBeInvited = (1 << 14), BotCanBeInvited = (1 << 14),

View file

@ -815,6 +815,28 @@ bool PeerData::canSendPolls() const {
return false; return false;
} }
void PeerData::setIsBlocked(bool is) {
const auto status = is
? BlockStatus::Blocked
: BlockStatus::NotBlocked;
if (_blockStatus != status) {
_blockStatus = status;
if (const auto user = asUser()) {
const auto flags = user->fullFlags();
if (is) {
user->setFullFlags(flags | MTPDuserFull::Flag::f_blocked);
} else {
user->setFullFlags(flags & ~MTPDuserFull::Flag::f_blocked);
}
}
session().changes().peerUpdated(this, UpdateFlag::IsBlocked);
}
}
void PeerData::setLoadedStatus(LoadedStatus status) {
_loadedStatus = status;
}
namespace Data { namespace Data {
std::vector<ChatRestrictions> ListOfRestrictions() { std::vector<ChatRestrictions> ListOfRestrictions() {

View file

@ -349,15 +349,37 @@ public:
: (_settings.value() | rpl::type_erased()); : (_settings.value() | rpl::type_erased());
} }
enum LoadedStatus { enum class BlockStatus : char {
NotLoaded = 0x00, Unknown,
MinimalLoaded = 0x01, Blocked,
FullLoaded = 0x02, NotBlocked,
}; };
[[nodiscard]] BlockStatus blockStatus() const {
return _blockStatus;
}
[[nodiscard]] bool isBlocked() const {
return (blockStatus() == BlockStatus::Blocked);
}
void setIsBlocked(bool is);
enum class LoadedStatus : char {
Not,
Minimal,
Full,
};
[[nodiscard]] LoadedStatus loadedStatus() const {
return _loadedStatus;
}
[[nodiscard]] bool isMinimalLoaded() const {
return (loadedStatus() != LoadedStatus::Not);
}
[[nodiscard]] bool isFullLoaded() const {
return (loadedStatus() == LoadedStatus::Full);
}
void setLoadedStatus(LoadedStatus status);
const PeerId id; const PeerId id;
QString name; QString name;
LoadedStatus loadedStatus = NotLoaded;
MTPinputPeer input; MTPinputPeer input;
int nameVersion = 1; int nameVersion = 1;
@ -400,6 +422,8 @@ private:
MsgId _pinnedMessageId = 0; MsgId _pinnedMessageId = 0;
Settings _settings = { kSettingsUnknown }; Settings _settings = { kSettingsUnknown };
BlockStatus _blockStatus = BlockStatus::Unknown;
LoadedStatus _loadedStatus = LoadedStatus::Not;
QString _about; QString _about;

View file

@ -145,9 +145,7 @@ bool PollData::applyResults(const MTPPollResults &results) {
recent->v recent->v
) | ranges::view::transform([&](MTPint userId) { ) | ranges::view::transform([&](MTPint userId) {
const auto user = _owner->user(userId.v); const auto user = _owner->user(userId.v);
return (user->loadedStatus != PeerData::NotLoaded) return user->isMinimalLoaded() ? user.get() : nullptr;
? user.get()
: nullptr;
}) | ranges::view::filter([](UserData *user) { }) | ranges::view::filter([](UserData *user) {
return user != nullptr; return user != nullptr;
}) | ranges::view::transform([](UserData *user) { }) | ranges::view::transform([](UserData *user) {

View file

@ -35,30 +35,30 @@ MTPMessage PrepareMessage(const MTPMessage &message, MsgId id) {
| MTPDmessageService::Flag( | MTPDmessageService::Flag(
MTPDmessage::Flag::f_from_scheduled)), MTPDmessage::Flag::f_from_scheduled)),
MTP_int(id), MTP_int(id),
MTP_int(data.vfrom_id().value_or_empty()), data.vfrom_id() ? *data.vfrom_id() : MTPPeer(),
data.vto_id(), data.vpeer_id(),
MTP_int(data.vreply_to_msg_id().value_or_empty()), data.vreply_to() ? *data.vreply_to() : MTPMessageReplyHeader(),
data.vdate(), data.vdate(),
data.vaction()); data.vaction());
}, [&](const MTPDmessage &data) { }, [&](const MTPDmessage &data) {
const auto fwdFrom = data.vfwd_from();
const auto media = data.vmedia();
const auto markup = data.vreply_markup();
const auto entities = data.ventities();
return MTP_message( return MTP_message(
MTP_flags(data.vflags().v | MTPDmessage::Flag::f_from_scheduled), MTP_flags(data.vflags().v | MTPDmessage::Flag::f_from_scheduled),
MTP_int(id), MTP_int(id),
MTP_int(data.vfrom_id().value_or_empty()), data.vfrom_id() ? *data.vfrom_id() : MTPPeer(),
data.vto_id(), data.vpeer_id(),
fwdFrom ? *fwdFrom : MTPMessageFwdHeader(), data.vfwd_from() ? *data.vfwd_from() : MTPMessageFwdHeader(),
MTP_int(data.vvia_bot_id().value_or_empty()), MTP_int(data.vvia_bot_id().value_or_empty()),
MTP_int(data.vreply_to_msg_id().value_or_empty()), data.vreply_to() ? *data.vreply_to() : MTPMessageReplyHeader(),
data.vdate(), data.vdate(),
data.vmessage(), data.vmessage(),
media ? *media : MTPMessageMedia(), data.vmedia() ? *data.vmedia() : MTPMessageMedia(),
markup ? *markup : MTPReplyMarkup(), data.vreply_markup() ? *data.vreply_markup() : MTPReplyMarkup(),
entities ? *entities : MTPVector<MTPMessageEntity>(), (data.ventities()
? *data.ventities()
: MTPVector<MTPMessageEntity>()),
MTP_int(data.vviews().value_or_empty()), MTP_int(data.vviews().value_or_empty()),
MTP_int(data.vforwards().value_or_empty()),
data.vreplies() ? *data.vreplies() : MTPMessageReplies(),
MTP_int(data.vedit_date().value_or_empty()), MTP_int(data.vedit_date().value_or_empty()),
MTP_bytes(data.vpost_author().value_or_empty()), MTP_bytes(data.vpost_author().value_or_empty()),
MTP_long(data.vgrouped_id().value_or_empty()), MTP_long(data.vgrouped_id().value_or_empty()),
@ -157,24 +157,28 @@ void ScheduledMessages::sendNowSimpleMessage(
// views count, etc. // views count, etc.
const auto history = local->history(); const auto history = local->history();
auto action = Api::SendAction(history);
action.replyTo = local->replyToId();
const auto replyHeader = NewMessageReplyHeader(action);
auto flags = NewMessageFlags(history->peer) auto flags = NewMessageFlags(history->peer)
| MTPDmessage::Flag::f_entities | MTPDmessage::Flag::f_entities
| MTPDmessage::Flag::f_from_id | MTPDmessage::Flag::f_from_id
| (local->replyToId() | (local->replyToId()
? MTPDmessage::Flag::f_reply_to_msg_id ? MTPDmessage::Flag::f_reply_to
: MTPDmessage::Flag(0)); : MTPDmessage::Flag(0));
auto clientFlags = NewMessageClientFlags() auto clientFlags = NewMessageClientFlags()
| MTPDmessage_ClientFlag::f_local_history_entry; | MTPDmessage_ClientFlag::f_local_history_entry;
const auto views = 1;
const auto forwards = 0;
history->addNewMessage( history->addNewMessage(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
update.vid(), update.vid(),
MTP_int(_session->userId()), peerToMTP(_session->userPeerId()),
peerToMTP(history->peer->id), peerToMTP(history->peer->id),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTP_int(local->replyToId()), replyHeader,
update.vdate(), update.vdate(),
MTP_string(local->originalText().text), MTP_string(local->originalText().text),
MTP_messageMediaEmpty(), MTP_messageMediaEmpty(),
@ -182,8 +186,10 @@ void ScheduledMessages::sendNowSimpleMessage(
Api::EntitiesToMTP( Api::EntitiesToMTP(
&history->session(), &history->session(),
local->originalText().entities), local->originalText().entities),
MTP_int(1), MTP_int(views),
MTPint(), MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(), MTP_string(),
MTPlong(), MTPlong(),
//MTPMessageReactions(), //MTPMessageReactions(),
@ -215,7 +221,7 @@ void ScheduledMessages::checkEntitiesAndUpdate(const MTPDmessage &data) {
// while the recipient is already online, the server sends // while the recipient is already online, the server sends
// updateNewMessage to the client and the client calls this method. // updateNewMessage to the client and the client calls this method.
const auto peer = peerFromMTP(data.vto_id()); const auto peer = peerFromMTP(data.vpeer_id());
if (!peerIsUser(peer)) { if (!peerIsUser(peer)) {
return; return;
} }

View file

@ -88,6 +88,7 @@ std::optional<MTPmessages_Search> PrepareSearchRequest(
peer->input, peer->input,
MTP_string(query), MTP_string(query),
MTP_inputUserEmpty(), MTP_inputUserEmpty(),
MTPint(), // top_msg_id
filter, filter,
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),

View file

@ -333,7 +333,7 @@ PeerData *Session::peerLoaded(PeerId id) const {
const auto i = _peers.find(id); const auto i = _peers.find(id);
if (i == end(_peers)) { if (i == end(_peers)) {
return nullptr; return nullptr;
} else if (i->second->loadedStatus != PeerData::FullLoaded) { } else if (!i->second->isFullLoaded()) {
return nullptr; return nullptr;
} }
return i->second.get(); return i->second.get();
@ -507,12 +507,12 @@ not_null<UserData*> Session::processUser(const MTPUser &data) {
}); });
if (minimal) { if (minimal) {
if (result->loadedStatus == PeerData::NotLoaded) { if (!result->isMinimalLoaded()) {
result->loadedStatus = PeerData::MinimalLoaded; result->setLoadedStatus(PeerData::LoadedStatus::Minimal);
} }
} else if (result->loadedStatus != PeerData::FullLoaded } else if (!result->isFullLoaded()
&& (!result->isSelf() || !result->phone().isEmpty())) { && (!result->isSelf() || !result->phone().isEmpty())) {
result->loadedStatus = PeerData::FullLoaded; result->setLoadedStatus(PeerData::LoadedStatus::Full);
} }
if (status && !minimal) { if (status && !minimal) {
@ -618,10 +618,8 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
const auto channel = result->asChannel(); const auto channel = result->asChannel();
minimal = data.is_min(); minimal = data.is_min();
if (minimal) { if (minimal && !result->isFullLoaded()) {
if (result->loadedStatus != PeerData::FullLoaded) { LOG(("API Warning: not loaded minimal channel applied."));
LOG(("API Warning: not loaded minimal channel applied."));
}
} }
const auto wasInChannel = channel->amIn(); const auto wasInChannel = channel->amIn();
@ -728,11 +726,11 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
}); });
if (minimal) { if (minimal) {
if (result->loadedStatus == PeerData::NotLoaded) { if (!result->isMinimalLoaded()) {
result->loadedStatus = PeerData::MinimalLoaded; result->setLoadedStatus(PeerData::LoadedStatus::Minimal);
} }
} else if (result->loadedStatus != PeerData::FullLoaded) { } else if (!result->isFullLoaded()) {
result->loadedStatus = PeerData::FullLoaded; result->setLoadedStatus(PeerData::LoadedStatus::Full);
} }
if (flags) { if (flags) {
session().changes().peerUpdated(result, flags); session().changes().peerUpdated(result, flags);
@ -1052,7 +1050,7 @@ void Session::setupUserIsContactViewer() {
requestViewResize(view); requestViewResize(view);
} }
} }
if (user->loadedStatus != PeerData::FullLoaded) { if (!user->isFullLoaded()) {
LOG(("API Error: " LOG(("API Error: "
"userIsContactChanged() called for a not loaded user!")); "userIsContactChanged() called for a not loaded user!"));
return; return;
@ -1650,36 +1648,44 @@ void Session::reorderTwoPinnedChats(
} }
bool Session::checkEntitiesAndViewsUpdate(const MTPDmessage &data) { bool Session::checkEntitiesAndViewsUpdate(const MTPDmessage &data) {
const auto peer = [&] { const auto peer = peerFromMTP(data.vpeer_id());
const auto result = peerFromMTP(data.vto_id()); const auto existing = message(peerToChannel(peer), data.vid().v);
if (const auto fromId = data.vfrom_id()) { if (!existing) {
if (result == session().userPeerId()) {
return peerFromUser(*fromId);
}
}
return result;
}();
if (const auto existing = message(peerToChannel(peer), data.vid().v)) {
existing->updateSentContent({
qs(data.vmessage()),
Api::EntitiesFromMTP(
&session(),
data.ventities().value_or_empty())
}, data.vmedia());
existing->updateReplyMarkup(data.vreply_markup());
existing->updateForwardedInfo(data.vfwd_from());
existing->setViewsCount(data.vviews().value_or(-1));
existing->indexAsNewItem();
existing->contributeToSlowmode(data.vdate().v);
requestItemTextRefresh(existing);
updateDependentMessages(existing);
if (existing->mainView()) {
stickers().checkSavedGif(existing);
return true;
}
return false; return false;
} }
return false; existing->updateSentContent({
qs(data.vmessage()),
Api::EntitiesFromMTP(
&session(),
data.ventities().value_or_empty())
}, data.vmedia());
existing->updateReplyMarkup(data.vreply_markup());
existing->updateForwardedInfo(data.vfwd_from());
existing->setViewsCount(data.vviews().value_or(-1));
if (const auto replies = data.vreplies()) {
replies->match([&](const MTPDmessageReplies &data) {
existing->setRepliesCount(
data.vreplies().v,
data.vreplies_pts().v);
});
}
existing->setForwardsCount(data.vforwards().value_or(-1));
if (const auto reply = data.vreply_to()) {
reply->match([&](const MTPDmessageReplyHeader &data) {
existing->setReplyToTop(
data.vreply_to_top_id().value_or(
data.vreply_to_msg_id().v));
});
}
existing->indexAsNewItem();
existing->contributeToSlowmode(data.vdate().v);
requestItemTextRefresh(existing);
updateDependentMessages(existing);
const auto result = (existing->mainView() != nullptr);
if (result) {
stickers().checkSavedGif(existing);
}
return result;
} }
void Session::updateEditedMessage(const MTPMessage &data) { void Session::updateEditedMessage(const MTPMessage &data) {
@ -1687,15 +1693,7 @@ void Session::updateEditedMessage(const MTPMessage &data) {
-> HistoryItem* { -> HistoryItem* {
return nullptr; return nullptr;
}, [&](const auto &data) { }, [&](const auto &data) {
const auto peer = [&] { const auto peer = peerFromMTP(data.vpeer_id());
const auto result = peerFromMTP(data.vto_id());
if (const auto fromId = data.vfrom_id()) {
if (result == session().userPeerId()) {
return peerFromUser(*fromId);
}
}
return result;
}();
return message(peerToChannel(peer), data.vid().v); return message(peerToChannel(peer), data.vid().v);
}); });
if (!existing) { if (!existing) {
@ -3742,18 +3740,20 @@ void Session::insertCheckedServiceNotification(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(nextLocalMessageId()), MTP_int(nextLocalMessageId()),
MTP_int(peerToUser(PeerData::kServiceNotificationsId)), peerToMTP(PeerData::kServiceNotificationsId),
MTP_peerUser(MTP_int(_session->userId())), peerToMTP(PeerData::kServiceNotificationsId),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTPint(), MTPint(), // via_bot_id
MTPint(), MTPMessageReplyHeader(),
MTP_int(date), MTP_int(date),
MTP_string(sending.text), MTP_string(sending.text),
media, media,
MTPReplyMarkup(), MTPReplyMarkup(),
Api::EntitiesToMTP(&session(), sending.entities), Api::EntitiesToMTP(&session(), sending.entities),
MTPint(), MTPint(), // views
MTPint(), MTPint(), // forwards
MTPMessageReplies(),
MTPint(), // edit_date
MTPstring(), MTPstring(),
MTPlong(), MTPlong(),
//MTPMessageReactions(), //MTPMessageReactions(),

View file

@ -140,29 +140,24 @@ HistoryItem *FileClickHandler::getActionItem() const {
PeerId PeerFromMessage(const MTPmessage &message) { PeerId PeerFromMessage(const MTPmessage &message) {
return message.match([](const MTPDmessageEmpty &) { return message.match([](const MTPDmessageEmpty &) {
return PeerId(0); return PeerId(0);
}, [](const auto &message) { }, [](const auto &data) {
const auto fromId = message.vfrom_id(); return peerFromMTP(data.vpeer_id());
const auto toId = peerFromMTP(message.vto_id());
const auto out = message.is_out();
return (out || !fromId || !peerIsUser(toId))
? toId
: peerFromUser(*fromId);
}); });
} }
MTPDmessage::Flags FlagsFromMessage(const MTPmessage &message) { MTPDmessage::Flags FlagsFromMessage(const MTPmessage &message) {
return message.match([](const MTPDmessageEmpty &) { return message.match([](const MTPDmessageEmpty &) {
return MTPDmessage::Flags(0); return MTPDmessage::Flags(0);
}, [](const MTPDmessage &message) { }, [](const MTPDmessage &data) {
return message.vflags().v; return data.vflags().v;
}, [](const MTPDmessageService &message) { }, [](const MTPDmessageService &data) {
return mtpCastFlags(message.vflags().v); return mtpCastFlags(data.vflags().v);
}); });
} }
MsgId IdFromMessage(const MTPmessage &message) { MsgId IdFromMessage(const MTPmessage &message) {
return message.match([](const auto &message) { return message.match([](const auto &data) {
return message.vid().v; return data.vid().v;
}); });
} }

View file

@ -228,21 +228,6 @@ void UserData::setAccessHash(uint64 accessHash) {
} }
} }
void UserData::setIsBlocked(bool is) {
const auto status = is
? BlockStatus::Blocked
: BlockStatus::NotBlocked;
if (_blockStatus != status) {
_blockStatus = status;
if (is) {
_fullFlags.add(MTPDuserFull::Flag::f_blocked);
} else {
_fullFlags.remove(MTPDuserFull::Flag::f_blocked);
}
session().changes().peerUpdated(this, UpdateFlag::IsBlocked);
}
}
void UserData::setCallsStatus(CallsStatus callsStatus) { void UserData::setCallsStatus(CallsStatus callsStatus) {
if (callsStatus != _callsStatus) { if (callsStatus != _callsStatus) {
_callsStatus = callsStatus; _callsStatus = callsStatus;

View file

@ -180,19 +180,6 @@ public:
} }
void setIsContact(bool is); void setIsContact(bool is);
enum class BlockStatus : char {
Unknown,
Blocked,
NotBlocked,
};
BlockStatus blockStatus() const {
return _blockStatus;
}
bool isBlocked() const {
return (blockStatus() == BlockStatus::Blocked);
}
void setIsBlocked(bool is);
enum class CallsStatus : char { enum class CallsStatus : char {
Unknown, Unknown,
Enabled, Enabled,
@ -225,7 +212,6 @@ private:
std::vector<Data::UnavailableReason> _unavailableReasons; std::vector<Data::UnavailableReason> _unavailableReasons;
QString _phone; QString _phone;
ContactStatus _contactStatus = ContactStatus::Unknown; ContactStatus _contactStatus = ContactStatus::Unknown;
BlockStatus _blockStatus = BlockStatus::Unknown;
CallsStatus _callsStatus = CallsStatus::Unknown; CallsStatus _callsStatus = CallsStatus::Unknown;
int _commonChatsCount = 0; int _commonChatsCount = 0;

View file

@ -837,6 +837,7 @@ bool Widget::onSearchMessages(bool searchCache) {
(_searchQueryFrom (_searchQueryFrom
? _searchQueryFrom->inputUser ? _searchQueryFrom->inputUser
: MTP_inputUserEmpty()), : MTP_inputUserEmpty()),
MTPint(), // top_msg_id
MTP_inputMessagesFilterEmpty(), MTP_inputMessagesFilterEmpty(),
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),
@ -883,6 +884,9 @@ bool Widget::onSearchMessages(bool searchCache) {
MTP_flags(flags), MTP_flags(flags),
MTP_int(folderId), MTP_int(folderId),
MTP_string(_searchQuery), MTP_string(_searchQuery),
MTP_inputMessagesFilterEmpty(),
MTP_int(0), // min_date
MTP_int(0), // max_date
MTP_int(0), MTP_int(0),
MTP_inputPeerEmpty(), MTP_inputPeerEmpty(),
MTP_int(0), MTP_int(0),
@ -1006,6 +1010,7 @@ void Widget::onSearchMore() {
(_searchQueryFrom (_searchQueryFrom
? _searchQueryFrom->inputUser ? _searchQueryFrom->inputUser
: MTP_inputUserEmpty()), : MTP_inputUserEmpty()),
MTPint(), // top_msg_id
MTP_inputMessagesFilterEmpty(), MTP_inputMessagesFilterEmpty(),
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),
@ -1062,6 +1067,9 @@ void Widget::onSearchMore() {
MTP_flags(flags), MTP_flags(flags),
MTP_int(folderId), MTP_int(folderId),
MTP_string(_searchQuery), MTP_string(_searchQuery),
MTP_inputMessagesFilterEmpty(),
MTP_int(0), // min_date
MTP_int(0), // max_date
MTP_int(_searchNextRate), MTP_int(_searchNextRate),
offsetPeer offsetPeer
? offsetPeer->input ? offsetPeer->input
@ -1096,6 +1104,7 @@ void Widget::onSearchMore() {
(_searchQueryFrom (_searchQueryFrom
? _searchQueryFrom->inputUser ? _searchQueryFrom->inputUser
: MTP_inputUserEmpty()), : MTP_inputUserEmpty()),
MTPint(), // top_msg_id
MTP_inputMessagesFilterEmpty(), MTP_inputMessagesFilterEmpty(),
MTP_int(0), MTP_int(0),
MTP_int(0), MTP_int(0),

View file

@ -264,6 +264,9 @@ Image ParseMaxImage(
if constexpr (MTPDphotoCachedSize::Is<decltype(data)>()) { if constexpr (MTPDphotoCachedSize::Is<decltype(data)>()) {
result.file.content = data.vbytes().v; result.file.content = data.vbytes().v;
result.file.size = result.file.content.size(); result.file.size = result.file.content.size();
} else if constexpr (MTPDphotoSizeProgressive::Is<decltype(data)>()) {
result.file.content = QByteArray();
result.file.size = data.vsizes().v.size();
} else { } else {
result.file.content = QByteArray(); result.file.content = QByteArray();
result.file.size = data.vsize().v; result.file.size = data.vsize().v;
@ -422,6 +425,9 @@ Image ParseDocumentThumb(
if constexpr (MTPDphotoCachedSize::Is<decltype(data)>()) { if constexpr (MTPDphotoCachedSize::Is<decltype(data)>()) {
result.file.content = data.vbytes().v; result.file.content = data.vbytes().v;
result.file.size = result.file.content.size(); result.file.size = result.file.content.size();
} else if constexpr (MTPDphotoSizeProgressive::Is<decltype(data)>()) {
result.file.content = QByteArray();
result.file.size = data.vsizes().v.size();
} else { } else {
result.file.content = QByteArray(); result.file.content = QByteArray();
result.file.size = data.vsize().v; result.file.size = data.vsize().v;
@ -1122,24 +1128,27 @@ Message ParseMessage(
data.match([&](const auto &data) { data.match([&](const auto &data) {
result.id = data.vid().v; result.id = data.vid().v;
if constexpr (!MTPDmessageEmpty::Is<decltype(data)>()) { if constexpr (!MTPDmessageEmpty::Is<decltype(data)>()) {
result.toId = ParsePeerId(data.vto_id());
const auto fromId = data.vfrom_id();
const auto peerId = (!data.is_out()
&& fromId
&& data.vto_id().type() == mtpc_peerUser)
? UserPeerId(fromId->v)
: result.toId;
if (IsChatPeerId(peerId)) {
result.chatId = BarePeerId(peerId);
}
if (fromId) {
result.fromId = fromId->v;
}
if (const auto replyToMsgId = data.vreply_to_msg_id()) {
result.replyToMsgId = replyToMsgId->v;
}
result.date = data.vdate().v; result.date = data.vdate().v;
result.out = data.is_out(); result.out = data.is_out();
result.selfId = context.selfPeerId;
result.peerId = ParsePeerId(data.vpeer_id());
const auto fromId = data.vfrom_id();
if (IsChatPeerId(result.peerId)) {
result.chatId = BarePeerId(result.peerId);
}
if (fromId) {
result.fromId = ParsePeerId(*fromId);
} else {
result.fromId = result.peerId;
}
if (const auto replyTo = data.vreply_to()) {
replyTo->match([&](const MTPDmessageReplyHeader &data) {
result.replyToMsgId = data.vreply_to_msg_id().v;
result.replyToPeerId = data.vreply_to_peer_id()
? ParsePeerId(*data.vreply_to_peer_id())
: 0;
});
}
} }
}); });
data.match([&](const MTPDmessage &data) { data.match([&](const MTPDmessage &data) {
@ -1149,12 +1158,9 @@ Message ParseMessage(
if (const auto fwdFrom = data.vfwd_from()) { if (const auto fwdFrom = data.vfwd_from()) {
result.forwardedFromId = fwdFrom->match( result.forwardedFromId = fwdFrom->match(
[](const MTPDmessageFwdHeader &data) { [](const MTPDmessageFwdHeader &data) {
if (const auto channelId = data.vchannel_id()) { return data.vfrom_id()
return ChatPeerId(channelId->v); ? ParsePeerId(*data.vfrom_id())
} else if (const auto fromId = data.vfrom_id()) { : PeerId(0);
return UserPeerId(fromId->v);
}
return PeerId(0);
}); });
result.forwardedFromName = fwdFrom->match( result.forwardedFromName = fwdFrom->match(
[](const MTPDmessageFwdHeader &data) { [](const MTPDmessageFwdHeader &data) {
@ -1180,8 +1186,13 @@ Message ParseMessage(
if (const auto postAuthor = data.vpost_author()) { if (const auto postAuthor = data.vpost_author()) {
result.signature = ParseString(*postAuthor); result.signature = ParseString(*postAuthor);
} }
if (const auto replyToMsgId = data.vreply_to_msg_id()) { if (const auto replyTo = data.vreply_to()) {
result.replyToMsgId = replyToMsgId->v; replyTo->match([&](const MTPDmessageReplyHeader &data) {
result.replyToMsgId = data.vreply_to_msg_id().v;
result.replyToPeerId = data.vreply_to_peer_id()
? ParsePeerId(*data.vreply_to_peer_id())
: PeerId(0);
});
} }
if (const auto viaBotId = data.vvia_bot_id()) { if (const auto viaBotId = data.vvia_bot_id()) {
result.viaBotId = viaBotId->v; result.viaBotId = viaBotId->v;
@ -1219,9 +1230,10 @@ Message ParseMessage(
} }
std::map<uint64, Message> ParseMessagesList( std::map<uint64, Message> ParseMessagesList(
PeerId selfId,
const MTPVector<MTPMessage> &data, const MTPVector<MTPMessage> &data,
const QString &mediaFolder) { const QString &mediaFolder) {
auto context = ParseMediaContext(); auto context = ParseMediaContext{ .selfPeerId = selfId };
auto result = std::map<uint64, Message>(); auto result = std::map<uint64, Message>();
for (const auto &message : data.v) { for (const auto &message : data.v) {
auto parsed = ParseMessage(context, message, mediaFolder); auto parsed = ParseMessage(context, message, mediaFolder);
@ -1460,7 +1472,10 @@ DialogsInfo ParseDialogsInfo(const MTPmessages_Dialogs &data) {
Unexpected("dialogsNotModified in ParseDialogsInfo."); Unexpected("dialogsNotModified in ParseDialogsInfo.");
}, [&](const auto &data) { // MTPDmessages_dialogs &data) { }, [&](const auto &data) { // MTPDmessages_dialogs &data) {
const auto peers = ParsePeersLists(data.vusers(), data.vchats()); const auto peers = ParsePeersLists(data.vusers(), data.vchats());
const auto messages = ParseMessagesList(data.vmessages(), folder); const auto messages = ParseMessagesList(
PeerId(0), // selfId, not used, we want only messages dates here.
data.vmessages(),
folder);
result.chats.reserve(result.chats.size() + data.vdialogs().v.size()); result.chats.reserve(result.chats.size() + data.vdialogs().v.size());
for (const auto &dialog : data.vdialogs().v) { for (const auto &dialog : data.vdialogs().v) {
if (dialog.type() != mtpc_dialog) { if (dialog.type() != mtpc_dialog) {

View file

@ -328,6 +328,7 @@ struct Media {
}; };
struct ParseMediaContext { struct ParseMediaContext {
PeerId selfPeerId = 0;
int photos = 0; int photos = 0;
int audios = 0; int audios = 0;
int videos = 0; int videos = 0;
@ -509,8 +510,9 @@ struct Message {
int32 chatId = 0; int32 chatId = 0;
TimeId date = 0; TimeId date = 0;
TimeId edited = 0; TimeId edited = 0;
int32 fromId = 0; PeerId fromId = 0;
PeerId toId = 0; PeerId peerId = 0;
PeerId selfId = 0;
PeerId forwardedFromId = 0; PeerId forwardedFromId = 0;
Utf8String forwardedFromName; Utf8String forwardedFromName;
TimeId forwardedDate = 0; TimeId forwardedDate = 0;
@ -519,6 +521,7 @@ struct Message {
Utf8String signature; Utf8String signature;
int32 viaBotId = 0; int32 viaBotId = 0;
int32 replyToMsgId = 0; int32 replyToMsgId = 0;
PeerId replyToPeerId = 0;
std::vector<TextPart> text; std::vector<TextPart> text;
Media media; Media media;
ServiceAction action; ServiceAction action;
@ -541,6 +544,7 @@ Message ParseMessage(
const MTPMessage &data, const MTPMessage &data,
const QString &mediaFolder); const QString &mediaFolder);
std::map<uint64, Message> ParseMessagesList( std::map<uint64, Message> ParseMessagesList(
PeerId selfId,
const MTPVector<MTPMessage> &data, const MTPVector<MTPMessage> &data,
const QString &mediaFolder); const QString &mediaFolder);

View file

@ -660,18 +660,37 @@ void ApiWrap::startMainSession(FnMut<void()> done) {
? Flag::f_message_channels ? Flag::f_message_channels
: Flag(0)); : Flag(0));
_mtp.request(MTPaccount_InitTakeoutSession( _mtp.request(MTPusers_GetUsers(
MTP_flags(flags), MTP_vector<MTPInputUser>(1, MTP_inputUserSelf())
MTP_int(sizeLimit)
)).done([=, done = std::move(done)]( )).done([=, done = std::move(done)](
const MTPaccount_Takeout &result) mutable { const MTPVector<MTPUser> &result) mutable {
_takeoutId = result.match([](const MTPDaccount_takeout &data) { for (const auto &user : result.v) {
return data.vid().v; user.match([&](const MTPDuser &data) {
}); if (data.is_self()) {
done(); _selfId = data.vid().v;
}
}, [&](const MTPDuserEmpty&) {
});
}
if (!_selfId) {
error("Could not retrieve selfId.");
return;
}
_mtp.request(MTPaccount_InitTakeoutSession(
MTP_flags(flags),
MTP_int(sizeLimit)
)).done([=, done = std::move(done)](
const MTPaccount_Takeout &result) mutable {
_takeoutId = result.match([](const MTPDaccount_takeout &data) {
return data.vid().v;
});
done();
}).fail([=](RPCError &&result) {
error(std::move(result));
}).toDC(MTP::ShiftDcId(0, MTP::kExportDcShift)).send();
}).fail([=](RPCError &&result) { }).fail([=](RPCError &&result) {
error(std::move(result)); error(std::move(result));
}).toDC(MTP::ShiftDcId(0, MTP::kExportDcShift)).send(); }).send();
} }
void ApiWrap::requestPersonalInfo(FnMut<void(Data::PersonalInfo&&)> done) { void ApiWrap::requestPersonalInfo(FnMut<void(Data::PersonalInfo&&)> done) {
@ -943,8 +962,10 @@ void ApiWrap::requestMessages(
Fn<bool(Data::MessagesSlice&&)> slice, Fn<bool(Data::MessagesSlice&&)> slice,
FnMut<void()> done) { FnMut<void()> done) {
Expects(_chatProcess == nullptr); Expects(_chatProcess == nullptr);
Expects(_selfId.has_value());
_chatProcess = std::make_unique<ChatProcess>(); _chatProcess = std::make_unique<ChatProcess>();
_chatProcess->context.selfPeerId = Data::UserPeerId(*_selfId);
_chatProcess->info = info; _chatProcess->info = info;
_chatProcess->start = std::move(start); _chatProcess->start = std::move(start);
_chatProcess->fileProgress = std::move(progress); _chatProcess->fileProgress = std::move(progress);
@ -1409,6 +1430,7 @@ void ApiWrap::requestChatMessages(
realPeerInput, realPeerInput,
MTP_string(), // query MTP_string(), // query
_user, _user,
MTPint(), // top_msg_id
MTP_inputMessagesFilterEmpty(), MTP_inputMessagesFilterEmpty(),
MTP_int(0), // min_date MTP_int(0), // min_date
MTP_int(0), // max_date MTP_int(0), // max_date
@ -1878,7 +1900,10 @@ void ApiWrap::filePartExtractReference(
result.match([&](const MTPDmessages_messagesNotModified &data) { result.match([&](const MTPDmessages_messagesNotModified &data) {
error("Unexpected messagesNotModified received."); error("Unexpected messagesNotModified received.");
}, [&](const auto &data) { }, [&](const auto &data) {
Expects(_selfId.has_value());
auto context = Data::ParseMediaContext(); auto context = Data::ParseMediaContext();
context.selfPeerId = Data::UserPeerId(*_selfId);
const auto messages = Data::ParseMessagesSlice( const auto messages = Data::ParseMessagesSlice(
context, context,
data.vmessages(), data.vmessages(),

View file

@ -209,6 +209,7 @@ private:
MTP::ConcurrentSender _mtp; MTP::ConcurrentSender _mtp;
std::optional<uint64> _takeoutId; std::optional<uint64> _takeoutId;
std::optional<int32> _selfId;
Output::Stats *_stats = nullptr; Output::Stats *_stats = nullptr;
std::unique_ptr<Settings> _settings; std::unique_ptr<Settings> _settings;

View file

@ -1604,7 +1604,9 @@ MediaData HtmlWriter::Wrap::prepareMediaData(
const auto &action = message.action; const auto &action = message.action;
if (const auto call = base::get_if<ActionPhoneCall>(&action.content)) { if (const auto call = base::get_if<ActionPhoneCall>(&action.content)) {
result.classes = "media_call"; result.classes = "media_call";
result.title = peers.peer(message.toId).name(); result.title = peers.peer(message.out
? message.peerId
: message.selfId).name();
result.status = [&] { result.status = [&] {
using Reason = ActionPhoneCall::DiscardReason; using Reason = ActionPhoneCall::DiscardReason;
const auto reason = call->discardReason; const auto reason = call->discardReason;

View file

@ -51,49 +51,48 @@ MTPMessage PrepareLogMessage(
TimeId newDate) { TimeId newDate) {
return message.match([&](const MTPDmessageEmpty &) { return message.match([&](const MTPDmessageEmpty &) {
return MTP_messageEmpty(MTP_int(newId)); return MTP_messageEmpty(MTP_int(newId));
}, [&](const MTPDmessageService &message) { }, [&](const MTPDmessageService &data) {
const auto removeFlags = MTPDmessageService::Flag::f_out const auto removeFlags = MTPDmessageService::Flag::f_out
| MTPDmessageService::Flag::f_post | MTPDmessageService::Flag::f_post
/* | MTPDmessageService::Flag::f_reply_to_msg_id*/; | MTPDmessageService::Flag::f_reply_to;
const auto flags = message.vflags().v & ~removeFlags;
const auto fromId = message.vfrom_id();
return MTP_messageService( return MTP_messageService(
MTP_flags(flags), MTP_flags(data.vflags().v & ~removeFlags),
MTP_int(newId), MTP_int(newId),
MTP_int(message.vfrom_id().value_or_empty()), data.vfrom_id() ? *data.vfrom_id() : MTPPeer(),
message.vto_id(), data.vpeer_id(),
MTP_int(0), // reply_to_msg_id MTPMessageReplyHeader(),
MTP_int(newDate), MTP_int(newDate),
message.vaction()); data.vaction());
}, [&](const MTPDmessage &message) { }, [&](const MTPDmessage &data) {
const auto removeFlags = MTPDmessage::Flag::f_out const auto removeFlags = MTPDmessage::Flag::f_out
| MTPDmessage::Flag::f_post | MTPDmessage::Flag::f_post
| MTPDmessage::Flag::f_reply_to_msg_id | MTPDmessage::Flag::f_reply_to
| MTPDmessage::Flag::f_replies
| MTPDmessage::Flag::f_edit_date | MTPDmessage::Flag::f_edit_date
| MTPDmessage::Flag::f_grouped_id | MTPDmessage::Flag::f_grouped_id
| MTPDmessage::Flag::f_views | MTPDmessage::Flag::f_views
| MTPDmessage::Flag::f_forwards
//| MTPDmessage::Flag::f_reactions //| MTPDmessage::Flag::f_reactions
| MTPDmessage::Flag::f_restriction_reason; | MTPDmessage::Flag::f_restriction_reason;
const auto flags = message.vflags().v & ~removeFlags;
const auto fwdFrom = message.vfwd_from();
const auto media = message.vmedia();
const auto markup = message.vreply_markup();
const auto entities = message.ventities();
return MTP_message( return MTP_message(
MTP_flags(flags), MTP_flags(data.vflags().v & ~removeFlags),
MTP_int(newId), MTP_int(newId),
MTP_int(message.vfrom_id().value_or_empty()), data.vfrom_id() ? *data.vfrom_id() : MTPPeer(),
message.vto_id(), data.vpeer_id(),
fwdFrom ? *fwdFrom : MTPMessageFwdHeader(), data.vfwd_from() ? *data.vfwd_from() : MTPMessageFwdHeader(),
MTP_int(message.vvia_bot_id().value_or_empty()), MTP_int(data.vvia_bot_id().value_or_empty()),
MTP_int(0), // reply_to_msg_id MTPMessageReplyHeader(),
MTP_int(newDate), MTP_int(newDate),
message.vmessage(), data.vmessage(),
media ? *media : MTPMessageMedia(), data.vmedia() ? *data.vmedia() : MTPMessageMedia(),
markup ? *markup : MTPReplyMarkup(), data.vreply_markup() ? *data.vreply_markup() : MTPReplyMarkup(),
entities ? *entities : MTPVector<MTPMessageEntity>(), (data.ventities()
MTP_int(message.vviews().value_or_empty()), ? *data.ventities()
MTP_int(0), // edit_date : MTPVector<MTPMessageEntity>()),
MTP_int(data.vviews().value_or_empty()),
MTP_int(data.vforwards().value_or_empty()),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(), MTP_string(),
MTP_long(0), // grouped_id MTP_long(0), // grouped_id
//MTPMessageReactions(), //MTPMessageReactions(),

View file

@ -658,7 +658,7 @@ void History::destroyMessage(not_null<HistoryItem*> item) {
const auto peerId = peer->id; const auto peerId = peer->id;
if (item->isHistoryEntry()) { if (item->isHistoryEntry()) {
// All this must be done for all items manually in History::clear()! // All this must be done for all items manually in History::clear()!
item->eraseFromUnreadMentions(); item->destroyHistoryEntry();
if (IsServerMsgId(item->id)) { if (IsServerMsgId(item->id)) {
if (const auto types = item->sharedMediaTypes()) { if (const auto types = item->sharedMediaTypes()) {
session().storage().remove(Storage::SharedMediaRemoveOne( session().storage().remove(Storage::SharedMediaRemoveOne(
@ -735,7 +735,7 @@ not_null<HistoryItem*> History::addNewLocalMessage(
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<HistoryMessage*> forwardOriginal) { not_null<HistoryMessage*> forwardOriginal) {
return addNewItem( return addNewItem(
@ -757,7 +757,7 @@ not_null<HistoryItem*> History::addNewLocalMessage(
UserId viaBotId, UserId viaBotId,
MsgId replyTo, MsgId replyTo,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<DocumentData*> document, not_null<DocumentData*> document,
const TextWithEntities &caption, const TextWithEntities &caption,
@ -785,7 +785,7 @@ not_null<HistoryItem*> History::addNewLocalMessage(
UserId viaBotId, UserId viaBotId,
MsgId replyTo, MsgId replyTo,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<PhotoData*> photo, not_null<PhotoData*> photo,
const TextWithEntities &caption, const TextWithEntities &caption,
@ -813,7 +813,7 @@ not_null<HistoryItem*> History::addNewLocalMessage(
UserId viaBotId, UserId viaBotId,
MsgId replyTo, MsgId replyTo,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<GameData*> game, not_null<GameData*> game,
const MTPReplyMarkup &markup) { const MTPReplyMarkup &markup) {
@ -1238,10 +1238,13 @@ void History::applyServiceChanges(
} break; } break;
case mtpc_messageActionPinMessage: { case mtpc_messageActionPinMessage: {
if (const auto replyToMsgId = data.vreply_to_msg_id()) { if (const auto replyTo = data.vreply_to()) {
if (item) { replyTo->match([&](const MTPDmessageReplyHeader &data) {
item->history()->peer->setPinnedMessageId(replyToMsgId->v); if (item) {
} item->history()->peer->setPinnedMessageId(
data.vreply_to_msg_id().v);
}
});
} }
} break; } break;
@ -1317,6 +1320,7 @@ void History::newItemAdded(not_null<HistoryItem*> item) {
if (item->out() && !item->unread()) { if (item->out() && !item->unread()) {
outboxRead(item); outboxRead(item);
} }
item->incrementReplyToTopCounter();
if (!folderKnown()) { if (!folderKnown()) {
owner().histories().requestDialogEntry(this); owner().histories().requestDialogEntry(this);
} }

View file

@ -127,7 +127,7 @@ public:
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<HistoryMessage*> forwardOriginal); not_null<HistoryMessage*> forwardOriginal);
not_null<HistoryItem*> addNewLocalMessage( not_null<HistoryItem*> addNewLocalMessage(
@ -137,7 +137,7 @@ public:
UserId viaBotId, UserId viaBotId,
MsgId replyTo, MsgId replyTo,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<DocumentData*> document, not_null<DocumentData*> document,
const TextWithEntities &caption, const TextWithEntities &caption,
@ -149,7 +149,7 @@ public:
UserId viaBotId, UserId viaBotId,
MsgId replyTo, MsgId replyTo,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<PhotoData*> photo, not_null<PhotoData*> photo,
const TextWithEntities &caption, const TextWithEntities &caption,
@ -161,7 +161,7 @@ public:
UserId viaBotId, UserId viaBotId,
MsgId replyTo, MsgId replyTo,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<GameData*> game, not_null<GameData*> game,
const MTPReplyMarkup &markup); const MTPReplyMarkup &markup);

View file

@ -65,7 +65,7 @@ not_null<HistoryItem*> CreateUnsupportedMessage(
MsgId replyTo, MsgId replyTo,
UserId viaBotId, UserId viaBotId,
TimeId date, TimeId date,
UserId from) { PeerId from) {
const auto siteLink = qsl("https://desktop.telegram.org"); const auto siteLink = qsl("https://desktop.telegram.org");
auto text = TextWithEntities{ auto text = TextWithEntities{
tr::lng_message_unsupported(tr::now, lt_link, siteLink) tr::lng_message_unsupported(tr::now, lt_link, siteLink)
@ -174,10 +174,10 @@ HistoryItem::HistoryItem(
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
TimeId date, TimeId date,
UserId from) PeerId from)
: id(id) : id(id)
, _history(history) , _history(history)
, _from(from ? history->owner().user(from) : history->peer) , _from(from ? history->owner().peer(from) : history->peer)
, _flags(flags) , _flags(flags)
, _clientFlags(clientFlags) , _clientFlags(clientFlags)
, _date(date) { , _date(date) {
@ -440,15 +440,13 @@ void HistoryItem::addToUnreadMentions(UnreadMentionType type) {
} }
void HistoryItem::applyEditionToHistoryCleared() { void HistoryItem::applyEditionToHistoryCleared() {
const auto fromId = 0;
const auto replyToId = 0;
applyEdition( applyEdition(
MTP_messageService( MTP_messageService(
MTP_flags(0), MTP_flags(0),
MTP_int(id), MTP_int(id),
MTP_int(fromId), peerToMTP(PeerId(0)), // from_id
peerToMTP(history()->peer->id), peerToMTP(history()->peer->id),
MTP_int(replyToId), MTPMessageReplyHeader(),
MTP_int(date()), MTP_int(date()),
MTP_messageActionHistoryClear() MTP_messageActionHistoryClear()
).c_messageService()); ).c_messageService());
@ -456,9 +454,7 @@ void HistoryItem::applyEditionToHistoryCleared() {
void HistoryItem::indexAsNewItem() { void HistoryItem::indexAsNewItem() {
if (IsServerMsgId(id)) { if (IsServerMsgId(id)) {
CrashReports::SetAnnotation("addToUnreadMentions", QString::number(id));
addToUnreadMentions(UnreadMentionType::New); addToUnreadMentions(UnreadMentionType::New);
CrashReports::ClearAnnotation("addToUnreadMentions");
if (const auto types = sharedMediaTypes()) { if (const auto types = sharedMediaTypes()) {
_history->session().storage().add(Storage::SharedMediaAddNew( _history->session().storage().add(Storage::SharedMediaAddNew(
history()->peer->id, history()->peer->id,
@ -657,6 +653,13 @@ MsgId HistoryItem::replyToId() const {
return 0; return 0;
} }
MsgId HistoryItem::replyToTop() const {
if (const auto reply = Get<HistoryMessageReply>()) {
return reply->replyToTop();
}
return 0;
}
not_null<PeerData*> HistoryItem::author() const { not_null<PeerData*> HistoryItem::author() const {
return isPost() ? history()->peer : from(); return isPost() ? history()->peer : from();
} }
@ -955,12 +958,12 @@ not_null<HistoryItem*> HistoryItem::Create(
data.vid().v, data.vid().v,
data.vflags().v, data.vflags().v,
clientFlags, clientFlags,
data.vreply_to_msg_id().value_or_empty(), 0, // #TODO replies data.vreply_to()
data.vvia_bot_id().value_or_empty(), data.vvia_bot_id().value_or_empty(),
data.vdate().v, data.vdate().v,
data.vfrom_id().value_or_empty()); data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0));
} else if (checked == MediaCheckResult::Empty) { } else if (checked == MediaCheckResult::Empty) {
const auto text = HistoryService::PreparedText { const auto text = HistoryService::PreparedText{
tr::lng_message_empty(tr::now) tr::lng_message_empty(tr::now)
}; };
return history->makeServiceMessage( return history->makeServiceMessage(
@ -969,7 +972,7 @@ not_null<HistoryItem*> HistoryItem::Create(
data.vdate().v, data.vdate().v,
text, text,
data.vflags().v, data.vflags().v,
data.vfrom_id().value_or_empty()); data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0));
} else if (checked == MediaCheckResult::HasTimeToLive) { } else if (checked == MediaCheckResult::HasTimeToLive) {
return history->makeServiceMessage(data, clientFlags); return history->makeServiceMessage(data, clientFlags);
} }

View file

@ -192,6 +192,9 @@ public:
[[nodiscard]] virtual int viewsCount() const { [[nodiscard]] virtual int viewsCount() const {
return hasViews() ? 1 : -1; return hasViews() ? 1 : -1;
} }
[[nodiscard]] virtual int repliesCount() const {
return 0;
}
[[nodiscard]] virtual bool needCheck() const; [[nodiscard]] virtual bool needCheck() const;
@ -215,7 +218,7 @@ public:
} }
virtual void addToUnreadMentions(UnreadMentionType type); virtual void addToUnreadMentions(UnreadMentionType type);
virtual void eraseFromUnreadMentions() { virtual void destroyHistoryEntry() {
} }
[[nodiscard]] virtual Storage::SharedMediaTypesMask sharedMediaTypes() const = 0; [[nodiscard]] virtual Storage::SharedMediaTypesMask sharedMediaTypes() const = 0;
@ -245,9 +248,17 @@ public:
return TextForMimeData(); return TextForMimeData();
} }
virtual void setViewsCount(int32 count) { virtual void setViewsCount(int count) {
}
virtual void setForwardsCount(int count) {
}
virtual void setRepliesCount(int count, int pts) {
}
virtual void setReplyToTop(MsgId replyToTop) {
} }
virtual void setRealId(MsgId newId); virtual void setRealId(MsgId newId);
virtual void incrementReplyToTopCounter() {
}
void drawInDialog( void drawInDialog(
Painter &p, Painter &p,
@ -301,6 +312,7 @@ public:
return nullptr; return nullptr;
} }
[[nodiscard]] MsgId replyToId() const; [[nodiscard]] MsgId replyToId() const;
[[nodiscard]] MsgId replyToTop() const;
[[nodiscard]] not_null<PeerData*> author() const; [[nodiscard]] not_null<PeerData*> author() const;
@ -348,7 +360,7 @@ protected:
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
TimeId date, TimeId date,
UserId from); PeerId from);
virtual void markMediaAsReadHook() { virtual void markMediaAsReadHook() {
} }

View file

@ -34,9 +34,10 @@ struct HistoryMessageVia : public RuntimeComponent<HistoryMessageVia, HistoryIte
}; };
struct HistoryMessageViews : public RuntimeComponent<HistoryMessageViews, HistoryItem> { struct HistoryMessageViews : public RuntimeComponent<HistoryMessageViews, HistoryItem> {
QString _viewsText; QString text;
int _views = 0; int textWidth = 0;
int _viewsWidth = 0; int views = -1;
int replies = 0;
}; };
struct HistoryMessageSigned : public RuntimeComponent<HistoryMessageSigned, HistoryItem> { struct HistoryMessageSigned : public RuntimeComponent<HistoryMessageSigned, HistoryItem> {
@ -96,6 +97,7 @@ struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply, Histor
HistoryMessageReply &operator=(const HistoryMessageReply &other) = delete; HistoryMessageReply &operator=(const HistoryMessageReply &other) = delete;
HistoryMessageReply &operator=(HistoryMessageReply &&other) { HistoryMessageReply &operator=(HistoryMessageReply &&other) {
replyToMsgId = other.replyToMsgId; replyToMsgId = other.replyToMsgId;
replyToMsgTop = other.replyToMsgTop;
replyToDocumentId = other.replyToDocumentId; replyToDocumentId = other.replyToDocumentId;
std::swap(replyToMsg, other.replyToMsg); std::swap(replyToMsg, other.replyToMsg);
replyToLnk = std::move(other.replyToLnk); replyToLnk = std::move(other.replyToLnk);
@ -139,6 +141,9 @@ struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply, Histor
[[nodiscard]] MsgId replyToId() const { [[nodiscard]] MsgId replyToId() const {
return replyToMsgId; return replyToMsgId;
} }
[[nodiscard]] MsgId replyToTop() const {
return replyToMsgTop;
}
[[nodiscard]] int replyToWidth() const { [[nodiscard]] int replyToWidth() const {
return maxReplyWidth; return maxReplyWidth;
} }
@ -151,6 +156,7 @@ struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply, Histor
void refreshReplyToDocument(); void refreshReplyToDocument();
MsgId replyToMsgId = 0; MsgId replyToMsgId = 0;
MsgId replyToMsgTop = 0;
HistoryItem *replyToMsg = nullptr; HistoryItem *replyToMsg = nullptr;
DocumentId replyToDocumentId = 0; DocumentId replyToDocumentId = 0;
ClickHandlerPtr replyToLnk; ClickHandlerPtr replyToLnk;

View file

@ -54,7 +54,7 @@ namespace {
[[nodiscard]] MTPDmessage::Flags NewForwardedFlags( [[nodiscard]] MTPDmessage::Flags NewForwardedFlags(
not_null<PeerData*> peer, not_null<PeerData*> peer,
UserId from, PeerId from,
not_null<HistoryMessage*> fwd) { not_null<HistoryMessage*> fwd) {
auto result = NewMessageFlags(peer) | MTPDmessage::Flag::f_fwd_from; auto result = NewMessageFlags(peer) | MTPDmessage::Flag::f_fwd_from;
if (from) { if (from) {
@ -210,7 +210,6 @@ void FastShareMessage(not_null<HistoryItem*> item) {
const auto data = std::make_shared<ShareData>( const auto data = std::make_shared<ShareData>(
history->peer, history->peer,
owner->itemOrItsGroup(item)); owner->itemOrItsGroup(item));
const auto isGroup = (owner->groups().find(item) != nullptr);
const auto isGame = item->getMessageBot() const auto isGame = item->getMessageBot()
&& item->media() && item->media()
&& (item->media()->game() != nullptr); && (item->media()->game() != nullptr);
@ -276,9 +275,6 @@ void FastShareMessage(not_null<HistoryItem*> item) {
const auto sendFlags = MTPmessages_ForwardMessages::Flag(0) const auto sendFlags = MTPmessages_ForwardMessages::Flag(0)
| MTPmessages_ForwardMessages::Flag::f_with_my_score | MTPmessages_ForwardMessages::Flag::f_with_my_score
| (isGroup
? MTPmessages_ForwardMessages::Flag::f_grouped
: MTPmessages_ForwardMessages::Flag(0))
| (options.silent | (options.silent
? MTPmessages_ForwardMessages::Flag::f_silent ? MTPmessages_ForwardMessages::Flag::f_silent
: MTPmessages_ForwardMessages::Flag(0)) : MTPmessages_ForwardMessages::Flag(0))
@ -375,6 +371,28 @@ MTPDmessage::Flags NewMessageFlags(not_null<PeerData*> peer) {
return result; return result;
} }
MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action) {
if (const auto id = action.replyTo) {
const auto history = action.history;
const auto &owner = history->owner();
if (const auto item = owner.message(history->channelId(), id)) {
if (item->replyToId()) {
return MTP_messageReplyHeader(
MTP_flags(MTPDmessageReplyHeader::Flag::f_reply_to_top_id),
MTP_int(id),
MTPPeer(),
MTP_int(item->replyToTop()));
}
}
return MTP_messageReplyHeader(
MTP_flags(0),
MTP_int(id),
MTPPeer(),
MTPint());
}
return MTPMessageReplyHeader();
}
MTPDmessage_ClientFlags NewMessageClientFlags() { MTPDmessage_ClientFlags NewMessageClientFlags() {
return MTPDmessage_ClientFlag::f_sending; return MTPDmessage_ClientFlag::f_sending;
} }
@ -388,8 +406,10 @@ QString GetErrorTextForSending(
struct HistoryMessage::CreateConfig { struct HistoryMessage::CreateConfig {
MsgId replyTo = 0; MsgId replyTo = 0;
MsgId replyToTop = 0;
UserId viaBotId = 0; UserId viaBotId = 0;
int viewsCount = -1; int viewsCount = -1;
int repliesCount = 0;
QString author; QString author;
PeerId senderOriginal = 0; PeerId senderOriginal = 0;
QString senderNameOriginal; QString senderNameOriginal;
@ -411,10 +431,8 @@ struct HistoryMessage::CreateConfig {
void HistoryMessage::FillForwardedInfo( void HistoryMessage::FillForwardedInfo(
CreateConfig &config, CreateConfig &config,
const MTPDmessageFwdHeader &data) { const MTPDmessageFwdHeader &data) {
if (const auto channelId = data.vchannel_id()) { if (const auto fromId = data.vfrom_id()) {
config.senderOriginal = peerFromChannel(*channelId); config.senderOriginal = peerFromMTP(*fromId);
} else if (const auto fromId = data.vfrom_id()) {
config.senderOriginal = peerFromUser(*fromId);
} }
config.originalDate = data.vdate().v; config.originalDate = data.vdate().v;
config.senderNameOriginal = qs(data.vfrom_name().value_or_empty()); config.senderNameOriginal = qs(data.vfrom_name().value_or_empty());
@ -439,16 +457,28 @@ HistoryMessage::HistoryMessage(
data.vflags().v, data.vflags().v,
clientFlags, clientFlags,
data.vdate().v, data.vdate().v,
data.vfrom_id().value_or_empty()) { data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) {
auto config = CreateConfig(); auto config = CreateConfig();
if (const auto forwarded = data.vfwd_from()) { if (const auto forwarded = data.vfwd_from()) {
forwarded->match([&](const MTPDmessageFwdHeader &data) { forwarded->match([&](const MTPDmessageFwdHeader &data) {
FillForwardedInfo(config, data); FillForwardedInfo(config, data);
}); });
} }
config.replyTo = data.vreply_to_msg_id().value_or_empty(); if (const auto reply = data.vreply_to()) {
reply->match([&](const MTPDmessageReplyHeader &data) {
// #TODO replies reply_to_peer_id.
config.replyTo = data.vreply_to_msg_id().v;
config.replyToTop = data.vreply_to_top_id().value_or(
config.replyTo);
});
}
config.viaBotId = data.vvia_bot_id().value_or_empty(); config.viaBotId = data.vvia_bot_id().value_or_empty();
config.viewsCount = data.vviews().value_or(-1); config.viewsCount = data.vviews().value_or(-1);
if (const auto replies = data.vreplies()) {
replies->match([&](const MTPDmessageReplies &data) {
config.repliesCount = data.vreplies().v;
});
}
config.mtpMarkup = data.vreply_markup(); config.mtpMarkup = data.vreply_markup();
config.editDate = data.vedit_date().value_or_empty(); config.editDate = data.vedit_date().value_or_empty();
config.author = qs(data.vpost_author().value_or_empty()); config.author = qs(data.vpost_author().value_or_empty());
@ -483,10 +513,16 @@ HistoryMessage::HistoryMessage(
mtpCastFlags(data.vflags().v), mtpCastFlags(data.vflags().v),
clientFlags, clientFlags,
data.vdate().v, data.vdate().v,
data.vfrom_id().value_or_empty()) { data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) {
auto config = CreateConfig(); auto config = CreateConfig();
config.replyTo = data.vreply_to_msg_id().value_or_empty(); if (const auto reply = data.vreply_to()) {
reply->match([&](const MTPDmessageReplyHeader &data) {
config.replyTo = data.vreply_to_msg_id().v;
config.replyToTop = data.vreply_to_top_id().value_or(
config.replyTo);
});
}
createComponents(config); createComponents(config);
@ -504,7 +540,7 @@ HistoryMessage::HistoryMessage(
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<HistoryMessage*> original) not_null<HistoryMessage*> original)
: HistoryItem( : HistoryItem(
@ -590,7 +626,7 @@ HistoryMessage::HistoryMessage(
MsgId replyTo, MsgId replyTo,
UserId viaBotId, UserId viaBotId,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
const TextWithEntities &textWithEntities) const TextWithEntities &textWithEntities)
: HistoryItem( : HistoryItem(
@ -618,7 +654,7 @@ HistoryMessage::HistoryMessage(
MsgId replyTo, MsgId replyTo,
UserId viaBotId, UserId viaBotId,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<DocumentData*> document, not_null<DocumentData*> document,
const TextWithEntities &caption, const TextWithEntities &caption,
@ -644,7 +680,7 @@ HistoryMessage::HistoryMessage(
MsgId replyTo, MsgId replyTo,
UserId viaBotId, UserId viaBotId,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<PhotoData*> photo, not_null<PhotoData*> photo,
const TextWithEntities &caption, const TextWithEntities &caption,
@ -670,7 +706,7 @@ HistoryMessage::HistoryMessage(
MsgId replyTo, MsgId replyTo,
UserId viaBotId, UserId viaBotId,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<GameData*> game, not_null<GameData*> game,
const MTPReplyMarkup &markup) const MTPReplyMarkup &markup)
@ -696,7 +732,9 @@ void HistoryMessage::createComponentsHelper(
auto config = CreateConfig(); auto config = CreateConfig();
if (flags & MTPDmessage::Flag::f_via_bot_id) config.viaBotId = viaBotId; if (flags & MTPDmessage::Flag::f_via_bot_id) config.viaBotId = viaBotId;
if (flags & MTPDmessage::Flag::f_reply_to_msg_id) config.replyTo = replyTo; if (flags & MTPDmessage::Flag::f_reply_to) {
config.replyToTop = config.replyTo = replyTo;
}
if (flags & MTPDmessage::Flag::f_reply_markup) config.mtpMarkup = &markup; if (flags & MTPDmessage::Flag::f_reply_markup) config.mtpMarkup = &markup;
if (flags & MTPDmessage::Flag::f_post_author) config.author = postAuthor; if (flags & MTPDmessage::Flag::f_post_author) config.author = postAuthor;
if (flags & MTPDmessage::Flag::f_views) config.viewsCount = 1; if (flags & MTPDmessage::Flag::f_views) config.viewsCount = 1;
@ -706,11 +744,18 @@ void HistoryMessage::createComponentsHelper(
int HistoryMessage::viewsCount() const { int HistoryMessage::viewsCount() const {
if (const auto views = Get<HistoryMessageViews>()) { if (const auto views = Get<HistoryMessageViews>()) {
return views->_views; return views->views;
} }
return HistoryItem::viewsCount(); return HistoryItem::viewsCount();
} }
int HistoryMessage::repliesCount() const {
if (const auto views = Get<HistoryMessageViews>()) {
return views->replies;
}
return HistoryItem::repliesCount();
}
bool HistoryMessage::updateDependencyItem() { bool HistoryMessage::updateDependencyItem() {
if (const auto reply = Get<HistoryMessageReply>()) { if (const auto reply = Get<HistoryMessageReply>()) {
const auto documentId = reply->replyToDocumentId; const auto documentId = reply->replyToDocumentId;
@ -803,7 +848,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
if (config.viaBotId) { if (config.viaBotId) {
mask |= HistoryMessageVia::Bit(); mask |= HistoryMessageVia::Bit();
} }
if (config.viewsCount >= 0) { if (config.viewsCount >= 0 || config.repliesCount > 0) {
mask |= HistoryMessageViews::Bit(); mask |= HistoryMessageViews::Bit();
} }
if (!config.author.isEmpty()) { if (!config.author.isEmpty()) {
@ -829,6 +874,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
if (const auto reply = Get<HistoryMessageReply>()) { if (const auto reply = Get<HistoryMessageReply>()) {
reply->replyToMsgId = config.replyTo; reply->replyToMsgId = config.replyTo;
reply->replyToMsgTop = isScheduled() ? 0 : config.replyToTop;
if (!reply->updateData(this)) { if (!reply->updateData(this)) {
history()->session().api().requestMessageData( history()->session().api().requestMessageData(
history()->peer->asChannel(), history()->peer->asChannel(),
@ -840,7 +886,8 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
via->create(&history()->owner(), config.viaBotId); via->create(&history()->owner(), config.viaBotId);
} }
if (const auto views = Get<HistoryMessageViews>()) { if (const auto views = Get<HistoryMessageViews>()) {
views->_views = config.viewsCount; views->views = config.viewsCount;
views->replies = config.repliesCount;
} }
if (const auto edited = Get<HistoryMessageEdited>()) { if (const auto edited = Get<HistoryMessageEdited>()) {
edited->date = config.editDate; edited->date = config.editDate;
@ -1088,6 +1135,7 @@ void HistoryMessage::applyEdition(const MTPDmessage &message) {
refreshMedia(message.vmedia()); refreshMedia(message.vmedia());
} }
setViewsCount(message.vviews().value_or(-1)); setViewsCount(message.vviews().value_or(-1));
setForwardsCount(message.vforwards().value_or(-1));
setText(_media ? textWithEntities : EnsureNonEmpty(textWithEntities)); setText(_media ? textWithEntities : EnsureNonEmpty(textWithEntities));
finishEdition(keyboardTop); finishEdition(keyboardTop);
@ -1099,6 +1147,7 @@ void HistoryMessage::applyEdition(const MTPDmessageService &message) {
refreshMedia(nullptr); refreshMedia(nullptr);
setEmptyText(); setEmptyText();
setViewsCount(-1); setViewsCount(-1);
setForwardsCount(-1);
finishEditionToEmpty(); finishEditionToEmpty();
} }
@ -1159,10 +1208,13 @@ void HistoryMessage::addToUnreadMentions(UnreadMentionType type) {
} }
} }
void HistoryMessage::eraseFromUnreadMentions() { void HistoryMessage::destroyHistoryEntry() {
if (isUnreadMention()) { if (isUnreadMention()) {
history()->eraseFromUnreadMentions(id); history()->eraseFromUnreadMentions(id);
} }
if (const auto reply = Get<HistoryMessageReply>()) {
decrementReplyToTopCounter(reply);
}
} }
Storage::SharedMediaTypesMask HistoryMessage::sharedMediaTypes() const { Storage::SharedMediaTypesMask HistoryMessage::sharedMediaTypes() const {
@ -1345,29 +1397,79 @@ bool HistoryMessage::textHasLinks() const {
return emptyText() ? false : _text.hasLinks(); return emptyText() ? false : _text.hasLinks();
} }
void HistoryMessage::setViewsCount(int32 count) { void HistoryMessage::setViewsCount(int count) {
const auto views = Get<HistoryMessageViews>(); const auto views = Get<HistoryMessageViews>();
if (!views if (!views
|| views->_views == count || views->views == count
|| (count >= 0 && views->_views > count)) { || (count >= 0 && views->views > count)) {
return; return;
} }
const auto was = views->_viewsWidth; views->views = count;
views->_views = count; views->text = (views->views > 0)
views->_viewsText = (views->_views > 0) ? Lang::FormatCountToShort(views->views).string
? Lang::FormatCountToShort(views->_views).string
: QString("1"); : QString("1");
views->_viewsWidth = views->_viewsText.isEmpty() const auto was = views->textWidth;
views->textWidth = views->text.isEmpty()
? 0 ? 0
: st::msgDateFont->width(views->_viewsText); : st::msgDateFont->width(views->text);
if (was == views->_viewsWidth) { if (was == views->textWidth) {
history()->owner().requestItemRepaint(this); history()->owner().requestItemRepaint(this);
} else { } else {
history()->owner().requestItemResize(this); history()->owner().requestItemResize(this);
} }
} }
void HistoryMessage::setForwardsCount(int count) {
}
void HistoryMessage::setRepliesCount(int count, int pts) {
auto views = Get<HistoryMessageViews>();
if (!views) {
if (!count) {
return;
}
AddComponents(HistoryMessageViews::Bit());
views = Get<HistoryMessageViews>();
}
if (views->replies == count) {
return;
}
views->replies = count;
if (views->views >= 0) {
return;
} else if (!views->replies) {
RemoveComponents(HistoryMessageViews::Bit());
history()->owner().requestItemResize(this);
return;
}
views->text = (views->replies > 0)
? Lang::FormatCountToShort(views->replies).string
: QString();
const auto was = views->textWidth;
views->textWidth = views->text.isEmpty()
? 0
: st::msgDateFont->width(views->text);
if (was == views->textWidth) {
history()->owner().requestItemRepaint(this);
} else {
history()->owner().requestItemResize(this);
}
}
void HistoryMessage::setReplyToTop(MsgId replyToTop) {
const auto reply = Get<HistoryMessageReply>();
if (!reply
|| (reply->replyToMsgTop == replyToTop)
|| (reply->replyToMsgTop != 0)
|| isScheduled()) {
return;
}
reply->replyToMsgTop = replyToTop;
incrementReplyToTopCounter(reply);
}
void HistoryMessage::setRealId(MsgId newId) { void HistoryMessage::setRealId(MsgId newId) {
HistoryItem::setRealId(newId); HistoryItem::setRealId(newId);
@ -1377,6 +1479,43 @@ void HistoryMessage::setRealId(MsgId newId) {
if (reply->replyToLink()) { if (reply->replyToLink()) {
reply->setReplyToLinkFrom(this); reply->setReplyToLinkFrom(this);
} }
incrementReplyToTopCounter(reply);
}
}
void HistoryMessage::incrementReplyToTopCounter() {
if (const auto reply = Get<HistoryMessageReply>()) {
incrementReplyToTopCounter(reply);
}
}
void HistoryMessage::incrementReplyToTopCounter(
not_null<HistoryMessageReply*> reply) {
if (!IsServerMsgId(id) || !reply->replyToTop()) {
return;
}
if (const auto channelId = history()->channelId()) {
const auto top = history()->owner().message(
channelId,
reply->replyToTop());
if (top) {
top->setRepliesCount(top->repliesCount() + 1, 0);
}
}
}
void HistoryMessage::decrementReplyToTopCounter(
not_null<HistoryMessageReply*> reply) {
if (!IsServerMsgId(id) || !reply->replyToTop()) {
return;
}
if (const auto channelId = history()->channelId()) {
const auto top = history()->owner().message(
channelId,
reply->replyToTop());
if (const auto replies = (top ? top->repliesCount() : 0)) {
top->setRepliesCount(replies - 1, 0);
}
} }
} }

View file

@ -9,16 +9,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_item.h" #include "history/history_item.h"
namespace Api {
struct SendAction;
} // namespace Api
namespace HistoryView { namespace HistoryView {
class Message; class Message;
} // namespace HistoryView } // namespace HistoryView
struct HistoryMessageEdited; struct HistoryMessageEdited;
struct HistoryMessageReply;
Fn<void(ChannelData*, MsgId)> HistoryDependentItemCallback( Fn<void(ChannelData*, MsgId)> HistoryDependentItemCallback(
not_null<HistoryItem*> item); not_null<HistoryItem*> item);
MTPDmessage::Flags NewMessageFlags(not_null<PeerData*> peer); MTPDmessage::Flags NewMessageFlags(not_null<PeerData*> peer);
MTPDmessage_ClientFlags NewMessageClientFlags(); MTPDmessage_ClientFlags NewMessageClientFlags();
MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action);
QString GetErrorTextForSending( QString GetErrorTextForSending(
not_null<PeerData*> peer, not_null<PeerData*> peer,
const HistoryItemsList &items, const HistoryItemsList &items,
@ -46,7 +52,7 @@ public:
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<HistoryMessage*> original); // local forwarded not_null<HistoryMessage*> original); // local forwarded
HistoryMessage( HistoryMessage(
@ -57,7 +63,7 @@ public:
MsgId replyTo, MsgId replyTo,
UserId viaBotId, UserId viaBotId,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
const TextWithEntities &textWithEntities); // local message const TextWithEntities &textWithEntities); // local message
HistoryMessage( HistoryMessage(
@ -68,7 +74,7 @@ public:
MsgId replyTo, MsgId replyTo,
UserId viaBotId, UserId viaBotId,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<DocumentData*> document, not_null<DocumentData*> document,
const TextWithEntities &caption, const TextWithEntities &caption,
@ -81,7 +87,7 @@ public:
MsgId replyTo, MsgId replyTo,
UserId viaBotId, UserId viaBotId,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<PhotoData*> photo, not_null<PhotoData*> photo,
const TextWithEntities &caption, const TextWithEntities &caption,
@ -94,7 +100,7 @@ public:
MsgId replyTo, MsgId replyTo,
UserId viaBotId, UserId viaBotId,
TimeId date, TimeId date,
UserId from, PeerId from,
const QString &postAuthor, const QString &postAuthor,
not_null<GameData*> game, not_null<GameData*> game,
const MTPReplyMarkup &markup); // local game const MTPReplyMarkup &markup); // local game
@ -125,8 +131,12 @@ public:
void applyGroupAdminChanges( void applyGroupAdminChanges(
const base::flat_set<UserId> &changes) override; const base::flat_set<UserId> &changes) override;
void setViewsCount(int32 count) override; void setViewsCount(int count) override;
void setForwardsCount(int count) override;
void setRepliesCount(int count, int pts) override;
void setReplyToTop(MsgId replyToTop) override;
void setRealId(MsgId newId) override; void setRealId(MsgId newId) override;
void incrementReplyToTopCounter() override;
void dependencyItemRemoved(HistoryItem *dependency) override; void dependencyItemRemoved(HistoryItem *dependency) override;
@ -144,7 +154,7 @@ public:
void contributeToSlowmode(TimeId realDate = 0) override; void contributeToSlowmode(TimeId realDate = 0) override;
void addToUnreadMentions(UnreadMentionType type) override; void addToUnreadMentions(UnreadMentionType type) override;
void eraseFromUnreadMentions() override; void destroyHistoryEntry() override;
[[nodiscard]] Storage::SharedMediaTypesMask sharedMediaTypes() const override; [[nodiscard]] Storage::SharedMediaTypesMask sharedMediaTypes() const override;
void setText(const TextWithEntities &textWithEntities) override; void setText(const TextWithEntities &textWithEntities) override;
@ -154,6 +164,7 @@ public:
[[nodiscard]] bool textHasLinks() const override; [[nodiscard]] bool textHasLinks() const override;
[[nodiscard]] int viewsCount() const override; [[nodiscard]] int viewsCount() const override;
[[nodiscard]] int repliesCount() const override;
bool updateDependencyItem() override; bool updateDependencyItem() override;
[[nodiscard]] MsgId dependencyMsgId() const override { [[nodiscard]] MsgId dependencyMsgId() const override {
return replyToId(); return replyToId();
@ -193,6 +204,8 @@ private:
void createComponentsHelper(MTPDmessage::Flags flags, MsgId replyTo, UserId viaBotId, const QString &postAuthor, const MTPReplyMarkup &markup); void createComponentsHelper(MTPDmessage::Flags flags, MsgId replyTo, UserId viaBotId, const QString &postAuthor, const MTPReplyMarkup &markup);
void createComponents(const CreateConfig &config); void createComponents(const CreateConfig &config);
void setupForwardedComponent(const CreateConfig &config); void setupForwardedComponent(const CreateConfig &config);
void incrementReplyToTopCounter(not_null<HistoryMessageReply*> reply);
void decrementReplyToTopCounter(not_null<HistoryMessageReply*> reply);
static void FillForwardedInfo( static void FillForwardedInfo(
CreateConfig &config, CreateConfig &config,

View file

@ -508,7 +508,7 @@ HistoryService::HistoryService(
data.vflags().v, data.vflags().v,
clientFlags, clientFlags,
data.vdate().v, data.vdate().v,
data.vfrom_id().value_or_empty()) { data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) {
createFromMtp(data); createFromMtp(data);
} }
@ -522,7 +522,7 @@ HistoryService::HistoryService(
mtpCastFlags(data.vflags().v), mtpCastFlags(data.vflags().v),
clientFlags, clientFlags,
data.vdate().v, data.vdate().v,
data.vfrom_id().value_or_empty()) { data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) {
createFromMtp(data); createFromMtp(data);
} }
@ -533,7 +533,7 @@ HistoryService::HistoryService(
TimeId date, TimeId date,
const PreparedText &message, const PreparedText &message,
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
UserId from, PeerId from,
PhotoData *photo) PhotoData *photo)
: HistoryItem(history, id, flags, clientFlags, date, from) { : HistoryItem(history, id, flags, clientFlags, date, from) {
setServiceText(message); setServiceText(message);
@ -680,19 +680,21 @@ void HistoryService::createFromMtp(const MTPDmessageService &message) {
auto currency = qs(message.vaction().c_messageActionPaymentSent().vcurrency()); auto currency = qs(message.vaction().c_messageActionPaymentSent().vcurrency());
Get<HistoryServicePayment>()->amount = HistoryView::FillAmountAndCurrency(amount, currency); Get<HistoryServicePayment>()->amount = HistoryView::FillAmountAndCurrency(amount, currency);
} }
if (const auto replyToMsgId = message.vreply_to_msg_id()) { if (const auto replyTo = message.vreply_to()) {
if (message.vaction().type() == mtpc_messageActionPinMessage) { if (message.vaction().type() == mtpc_messageActionPinMessage) {
UpdateComponents(HistoryServicePinned::Bit()); UpdateComponents(HistoryServicePinned::Bit());
} }
if (const auto dependent = GetDependentData()) { replyTo->match([&](const MTPDmessageReplyHeader &data) {
dependent->msgId = replyToMsgId->v; if (const auto dependent = GetDependentData()) {
if (!updateDependent()) { dependent->msgId = data.vreply_to_msg_id().v;
history()->session().api().requestMessageData( if (!updateDependent()) {
history()->peer->asChannel(), history()->session().api().requestMessageData(
dependent->msgId, history()->peer->asChannel(),
HistoryDependentItemCallback(this)); dependent->msgId,
HistoryDependentItemCallback(this));
}
} }
} });
} }
setMessageByAction(message.vaction()); setMessageByAction(message.vaction());
} }

View file

@ -73,7 +73,7 @@ public:
TimeId date, TimeId date,
const PreparedText &message, const PreparedText &message,
MTPDmessage::Flags flags = 0, MTPDmessage::Flags flags = 0,
UserId from = 0, PeerId from = 0,
PhotoData *photo = nullptr); PhotoData *photo = nullptr);
bool updateDependencyItem() override; bool updateDependencyItem() override;

View file

@ -1452,7 +1452,12 @@ void HistoryWidget::setInnerFocus() {
if (_scroll->isHidden()) { if (_scroll->isHidden()) {
setFocus(); setFocus();
} else if (_list) { } else if (_list) {
if (_nonEmptySelection || (_list && _list->wasSelectedText()) || _recording || isBotStart() || isBlocked() || !_canSendMessages) { if (_nonEmptySelection
|| (_list && _list->wasSelectedText())
|| _recording
|| isBotStart()
|| isBlocked()
|| !_canSendMessages) {
_list->setFocus(); _list->setFocus();
} else { } else {
_field->setFocus(); _field->setFocus();

View file

@ -406,7 +406,7 @@ void ContactStatus::setupReportHandler(not_null<PeerData*> peer) {
_controller->showBackFromStack(); _controller->showBackFromStack();
}); });
if (const auto user = peer->asUser()) { if (const auto user = peer->asUser()) {
peer->session().api().blockUser(user); peer->session().api().blockPeer(user);
} }
const auto text = ((peer->isChat() || peer->isMegagroup()) const auto text = ((peer->isChat() || peer->isMegagroup())
? tr::lng_report_spam_sure_group ? tr::lng_report_spam_sure_group

View file

@ -1354,9 +1354,9 @@ void Message::drawInfo(
}(); }();
if (item->id > 0) { if (item->id > 0) {
icon->paint(p, infoRight - infoW, infoBottom + st::historyViewsTop, width); icon->paint(p, infoRight - infoW, infoBottom + st::historyViewsTop, width);
p.drawText(infoRight - infoW + st::historyViewsWidth, infoBottom - st::msgDateFont->descent, views->_viewsText); p.drawText(infoRight - infoW + st::historyViewsWidth, infoBottom - st::msgDateFont->descent, views->text);
} else if (!outbg) { // sending outbg icon will be painted below } else if (!outbg) { // sending outbg icon will be painted below
auto iconSkip = st::historyViewsSpace + views->_viewsWidth; auto iconSkip = st::historyViewsSpace + views->textWidth;
icon->paint(p, infoRight - infoW + iconSkip, infoBottom + st::historyViewsTop, width); icon->paint(p, infoRight - infoW + iconSkip, infoBottom + st::historyViewsTop, width);
} }
} else if (item->id < 0 && item->history()->peer->isSelf() && !outbg) { } else if (item->id < 0 && item->history()->peer->isSelf() && !outbg) {
@ -1413,7 +1413,7 @@ int Message::infoWidth() const {
auto result = item->_timeWidth; auto result = item->_timeWidth;
if (auto views = item->Get<HistoryMessageViews>()) { if (auto views = item->Get<HistoryMessageViews>()) {
result += st::historyViewsSpace result += st::historyViewsSpace
+ views->_viewsWidth + views->textWidth
+ st::historyViewsWidth; + st::historyViewsWidth;
} else if (item->id < 0 && item->history()->peer->isSelf()) { } else if (item->id < 0 && item->history()->peer->isSelf()) {
if (!hasOutLayout()) { if (!hasOutLayout()) {
@ -1453,7 +1453,7 @@ int Message::timeLeft() const {
const auto item = message(); const auto item = message();
auto result = 0; auto result = 0;
if (auto views = item->Get<HistoryMessageViews>()) { if (auto views = item->Get<HistoryMessageViews>()) {
result += st::historyViewsSpace + views->_viewsWidth + st::historyViewsWidth; result += st::historyViewsSpace + views->textWidth + st::historyViewsWidth;
} else if (item->id < 0 && item->history()->peer->isSelf()) { } else if (item->id < 0 && item->history()->peer->isSelf()) {
if (!hasOutLayout()) { if (!hasOutLayout()) {
result += st::historySendStateSpace; result += st::historySendStateSpace;
@ -1989,12 +1989,16 @@ void Message::initTime() {
item->_timeWidth = st::msgDateFont->width(item->_timeText); item->_timeWidth = st::msgDateFont->width(item->_timeText);
} }
if (const auto views = item->Get<HistoryMessageViews>()) { if (const auto views = item->Get<HistoryMessageViews>()) {
views->_viewsText = (views->_views > 0) views->text = (views->views > 0)
? Lang::FormatCountToShort(views->_views).string ? Lang::FormatCountToShort(views->views).string
: (views->views < 0)
? (views->replies > 0
? Lang::FormatCountToShort(views->replies).string
: QString())
: QString("1"); : QString("1");
views->_viewsWidth = views->_viewsText.isEmpty() views->textWidth = views->text.isEmpty()
? 0 ? 0
: st::msgDateFont->width(views->_viewsText); : st::msgDateFont->width(views->text);
} }
if (item->_text.hasSkipBlock()) { if (item->_text.hasSkipBlock()) {
if (item->_text.updateSkipBlock(skipBlockWidth(), skipBlockHeight())) { if (item->_text.updateSkipBlock(skipBlockWidth(), skipBlockHeight())) {

View file

@ -281,7 +281,7 @@ void ListController::loadMoreRows() {
for (const auto &vote : data.vvotes().v) { for (const auto &vote : data.vvotes().v) {
vote.match([&](const auto &data) { vote.match([&](const auto &data) {
const auto user = owner.user(data.vuser_id().v); const auto user = owner.user(data.vuser_id().v);
if (user->loadedStatus != PeerData::NotLoaded) { if (user->isMinimalLoaded()) {
if (add) { if (add) {
appendRow(user); appendRow(user);
--add; --add;

View file

@ -628,7 +628,7 @@ void ActionsFiller::addBlockAction(not_null<UserData*> user) {
Ui::showPeerHistory(user, ShowAtUnreadMsgId); Ui::showPeerHistory(user, ShowAtUnreadMsgId);
} }
} else if (user->isBot()) { } else if (user->isBot()) {
user->session().api().blockUser(user); user->session().api().blockPeer(user);
} else { } else {
window->show( window->show(
Box(Window::PeerMenuBlockUserBox, window, user, false)); Box(Window::PeerMenuBlockUserBox, window, user, false));

View file

@ -366,7 +366,7 @@ void Result::addToHistory(
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,

View file

@ -62,7 +62,7 @@ public:
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,

View file

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h" #include "storage/localstorage.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_message.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "app.h" #include "app.h"
@ -33,7 +34,7 @@ void SendDataCommon::addToHistory(
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,
@ -43,22 +44,32 @@ void SendDataCommon::addToHistory(
if (!fields.entities.v.isEmpty()) { if (!fields.entities.v.isEmpty()) {
flags |= MTPDmessage::Flag::f_entities; flags |= MTPDmessage::Flag::f_entities;
} }
auto action = Api::SendAction(history);
action.replyTo = replyToId;
const auto replyHeader = NewMessageReplyHeader(action);
if (replyToId) {
flags |= MTPDmessage::Flag::f_reply_to;
}
const auto views = 1;
const auto forwards = 0;
history->addNewMessage( history->addNewMessage(
MTP_message( MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(msgId), MTP_int(msgId),
MTP_int(fromId), peerToMTP(fromId),
peerToMTP(history->peer->id), peerToMTP(history->peer->id),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTP_int(viaBotId), MTP_int(viaBotId),
MTP_int(replyToId), replyHeader,
mtpDate, mtpDate,
fields.text, fields.text,
fields.media, fields.media,
markup, markup,
fields.entities, fields.entities,
MTP_int(1), MTP_int(views),
MTPint(), MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(postAuthor), MTP_string(postAuthor),
MTPlong(), MTPlong(),
//MTPMessageReactions(), //MTPMessageReactions(),
@ -129,7 +140,7 @@ void SendPhoto::addToHistory(
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,
@ -164,7 +175,7 @@ void SendFile::addToHistory(
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,
@ -213,7 +224,7 @@ void SendGame::addToHistory(
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,

View file

@ -44,7 +44,7 @@ public:
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,
@ -88,7 +88,7 @@ public:
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,
@ -242,7 +242,7 @@ public:
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,
@ -284,7 +284,7 @@ public:
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,
@ -320,7 +320,7 @@ public:
MTPDmessage::Flags flags, MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags, MTPDmessage_ClientFlags clientFlags,
MsgId msgId, MsgId msgId,
UserId fromId, PeerId fromId,
MTPint mtpDate, MTPint mtpDate,
UserId viaBotId, UserId viaBotId,
MsgId replyToId, MsgId replyToId,

View file

@ -1276,7 +1276,7 @@ void MainWidget::viewsIncrement() {
i->first->input, i->first->input,
MTP_vector<MTPint>(ids), MTP_vector<MTPint>(ids),
MTP_bool(true) MTP_bool(true)
)).done([=](const MTPVector<MTPint> &result, mtpRequestId requestId) { )).done([=](const MTPmessages_MessageViews &result, mtpRequestId requestId) {
viewsIncrementDone(ids, result, requestId); viewsIncrementDone(ids, result, requestId);
}).fail([=](const RPCError &error, mtpRequestId requestId) { }).fail([=](const RPCError &error, mtpRequestId requestId) {
viewsIncrementFail(error, requestId); viewsIncrementFail(error, requestId);
@ -1287,8 +1287,14 @@ void MainWidget::viewsIncrement() {
} }
} }
void MainWidget::viewsIncrementDone(QVector<MTPint> ids, const MTPVector<MTPint> &result, mtpRequestId requestId) { void MainWidget::viewsIncrementDone(
auto &v = result.v; QVector<MTPint> ids,
const MTPmessages_MessageViews &result,
mtpRequestId requestId) {
const auto &data = result.c_messages_messageViews();
session().data().processUsers(data.vusers());
session().data().processChats(data.vchats());
auto &v = data.vviews().v;
if (ids.size() == v.size()) { if (ids.size() == v.size()) {
for (auto i = _viewsIncrementRequests.begin(); i != _viewsIncrementRequests.cend(); ++i) { for (auto i = _viewsIncrementRequests.begin(); i != _viewsIncrementRequests.cend(); ++i) {
if (i->second == requestId) { if (i->second == requestId) {
@ -1296,7 +1302,23 @@ void MainWidget::viewsIncrementDone(QVector<MTPint> ids, const MTPVector<MTPint>
const auto channel = peerToChannel(peer->id); const auto channel = peerToChannel(peer->id);
for (int32 j = 0, l = ids.size(); j < l; ++j) { for (int32 j = 0, l = ids.size(); j < l; ++j) {
if (const auto item = session().data().message(channel, ids[j].v)) { if (const auto item = session().data().message(channel, ids[j].v)) {
item->setViewsCount(v[j].v); v[j].match([&](const MTPDmessageViews &data) {
if (const auto views = data.vviews()) {
item->setViewsCount(views->v);
}
if (const auto forwards = data.vforwards()) {
item->setForwardsCount(forwards->v);
}
if (const auto replies = data.vreplies()) {
item->setRepliesCount(
replies->match([&](const MTPDmessageReplies &data) {
return data.vreplies().v;
}),
replies->match([&](const MTPDmessageReplies &data) {
return data.vreplies_pts().v;
}));
}
});
} }
} }
_viewsIncrementRequests.erase(i); _viewsIncrementRequests.erase(i);

View file

@ -322,7 +322,7 @@ private:
void viewsIncrementDone( void viewsIncrementDone(
QVector<MTPint> ids, QVector<MTPint> ids,
const MTPVector<MTPint> &result, const MTPmessages_MessageViews &result,
mtpRequestId requestId); mtpRequestId requestId);
void viewsIncrementFail(const RPCError &error, mtpRequestId requestId); void viewsIncrementFail(const RPCError &error, mtpRequestId requestId);

View file

@ -46,62 +46,60 @@ namespace {
constexpr auto kBlockedPerPage = 40; constexpr auto kBlockedPerPage = 40;
class BlockUserBoxController class BlockPeerBoxController
: public ChatsListBoxController : public ChatsListBoxController
, private base::Subscriber { , private base::Subscriber {
public: public:
explicit BlockUserBoxController( explicit BlockPeerBoxController(
not_null<Window::SessionNavigation*> navigation); not_null<Window::SessionNavigation*> navigation);
Main::Session &session() const override; Main::Session &session() const override;
void rowClicked(not_null<PeerListRow*> row) override; void rowClicked(not_null<PeerListRow*> row) override;
void setBlockUserCallback(Fn<void(not_null<UserData*> user)> callback) { void setBlockPeerCallback(Fn<void(not_null<PeerData*> peer)> callback) {
_blockUserCallback = std::move(callback); _blockPeerCallback = std::move(callback);
} }
protected: protected:
void prepareViewHook() override; void prepareViewHook() override;
std::unique_ptr<Row> createRow(not_null<History*> history) override; std::unique_ptr<Row> createRow(not_null<History*> history) override;
void updateRowHook(not_null<Row*> row) override { void updateRowHook(not_null<Row*> row) override {
updateIsBlocked(row, row->peer()->asUser()); updateIsBlocked(row, row->peer());
delegate()->peerListUpdateRow(row); delegate()->peerListUpdateRow(row);
} }
private: private:
void updateIsBlocked(not_null<PeerListRow*> row, UserData *user) const; void updateIsBlocked(not_null<PeerListRow*> row, PeerData *peer) const;
const not_null<Window::SessionNavigation*> _navigation; const not_null<Window::SessionNavigation*> _navigation;
Fn<void(not_null<UserData*> user)> _blockUserCallback; Fn<void(not_null<PeerData*> peer)> _blockPeerCallback;
}; };
BlockUserBoxController::BlockUserBoxController( BlockPeerBoxController::BlockPeerBoxController(
not_null<Window::SessionNavigation*> navigation) not_null<Window::SessionNavigation*> navigation)
: ChatsListBoxController(navigation) : ChatsListBoxController(navigation)
, _navigation(navigation) { , _navigation(navigation) {
} }
Main::Session &BlockUserBoxController::session() const { Main::Session &BlockPeerBoxController::session() const {
return _navigation->session(); return _navigation->session();
} }
void BlockUserBoxController::prepareViewHook() { void BlockPeerBoxController::prepareViewHook() {
delegate()->peerListSetTitle(tr::lng_blocked_list_add_title()); delegate()->peerListSetTitle(tr::lng_blocked_list_add_title());
session().changes().peerUpdates( session().changes().peerUpdates(
Data::PeerUpdate::Flag::IsBlocked Data::PeerUpdate::Flag::IsBlocked
) | rpl::start_with_next([=](const Data::PeerUpdate &update) { ) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
if (const auto user = update.peer->asUser()) { if (auto row = delegate()->peerListFindRow(update.peer->id)) {
if (auto row = delegate()->peerListFindRow(user->id)) { updateIsBlocked(row, update.peer);
updateIsBlocked(row, user); delegate()->peerListUpdateRow(row);
delegate()->peerListUpdateRow(row);
}
} }
}, lifetime()); }, lifetime());
} }
void BlockUserBoxController::updateIsBlocked(not_null<PeerListRow*> row, UserData *user) const { void BlockPeerBoxController::updateIsBlocked(not_null<PeerListRow*> row, PeerData *peer) const {
auto blocked = user->isBlocked(); auto blocked = peer->isBlocked();
row->setDisabledState(blocked ? PeerListRow::State::DisabledChecked : PeerListRow::State::Active); row->setDisabledState(blocked ? PeerListRow::State::DisabledChecked : PeerListRow::State::Active);
if (blocked) { if (blocked) {
row->setCustomStatus(tr::lng_blocked_list_already_blocked(tr::now)); row->setCustomStatus(tr::lng_blocked_list_already_blocked(tr::now));
@ -110,20 +108,20 @@ void BlockUserBoxController::updateIsBlocked(not_null<PeerListRow*> row, UserDat
} }
} }
void BlockUserBoxController::rowClicked(not_null<PeerListRow*> row) { void BlockPeerBoxController::rowClicked(not_null<PeerListRow*> row) {
_blockUserCallback(row->peer()->asUser()); _blockPeerCallback(row->peer());
} }
std::unique_ptr<BlockUserBoxController::Row> BlockUserBoxController::createRow(not_null<History*> history) { auto BlockPeerBoxController::createRow(not_null<History*> history)
if (history->peer->isSelf()) { -> std::unique_ptr<BlockPeerBoxController::Row> {
if (!history->peer->isUser()
|| history->peer->isServiceUser()
|| history->peer->isSelf()) {
return nullptr; return nullptr;
} }
if (auto user = history->peer->asUser()) { auto row = std::make_unique<Row>(history);
auto row = std::make_unique<Row>(history); updateIsBlocked(row.get(), history->peer);
updateIsBlocked(row.get(), user); return row;
return row;
}
return nullptr;
} }
AdminLog::OwnedItem GenerateForwardedItem( AdminLog::OwnedItem GenerateForwardedItem(
@ -142,27 +140,28 @@ AdminLog::OwnedItem GenerateForwardedItem(
const auto item = MTP_message( const auto item = MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(++id), MTP_int(++id),
MTP_int(peerToUser(history->peer->id)), peerToMTP(history->peer->id),
peerToMTP(history->session().userPeerId()), peerToMTP(history->peer->id),
MTP_messageFwdHeader( MTP_messageFwdHeader(
MTP_flags(FwdFlag::f_from_id), MTP_flags(FwdFlag::f_from_id),
MTP_int(history->session().userId()), peerToMTP(history->session().userPeerId()),
MTPstring(), // from_name MTPstring(), // from_name
MTP_int(base::unixtime::now()), MTP_int(base::unixtime::now()),
MTPint(), // channel_id
MTPint(), // channel_post MTPint(), // channel_post
MTPstring(), // post_author MTPstring(), // post_author
MTPPeer(), // saved_from_peer MTPPeer(), // saved_from_peer
MTPint(), // saved_from_msg_id MTPint(), // saved_from_msg_id
MTPstring()), // psa_type MTPstring()), // psa_type
MTPint(), // via_bot_id MTPint(), // via_bot_id
MTPint(), // reply_to_msg_id, MTPMessageReplyHeader(),
MTP_int(base::unixtime::now()), // date MTP_int(base::unixtime::now()), // date
MTP_string(text), MTP_string(text),
MTPMessageMedia(), MTPMessageMedia(),
MTPReplyMarkup(), MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(), MTPVector<MTPMessageEntity>(),
MTPint(), // views MTPint(), // views
MTPint(), // forwards
MTPMessageReplies(),
MTPint(), // edit_date MTPint(), // edit_date
MTPstring(), // post_author MTPstring(), // post_author
MTPlong(), // grouped_id MTPlong(), // grouped_id
@ -199,22 +198,20 @@ void BlockedBoxController::prepare() {
session().changes().peerUpdates( session().changes().peerUpdates(
Data::PeerUpdate::Flag::IsBlocked Data::PeerUpdate::Flag::IsBlocked
) | rpl::start_with_next([=](const Data::PeerUpdate &update) { ) | rpl::start_with_next([=](const Data::PeerUpdate &update) {
if (const auto user = update.peer->asUser()) { handleBlockedEvent(update.peer);
handleBlockedEvent(user);
}
}, lifetime()); }, lifetime());
_loadRequestId = -1; _loadRequestId = -1;
_window->session().api().blockedUsersSlice( _window->session().api().blockedPeersSlice(
) | rpl::take( ) | rpl::take(
1 1
) | rpl::start_with_next([=](const ApiWrap::BlockedUsersSlice &result) { ) | rpl::start_with_next([=](const ApiWrap::BlockedPeersSlice &result) {
setDescriptionText(tr::lng_blocked_list_about(tr::now)); setDescriptionText(tr::lng_blocked_list_about(tr::now));
_loadRequestId = 0; _loadRequestId = 0;
_offset = result.list.size(); _offset = result.list.size();
_allLoaded = (_offset >= result.total); _allLoaded = (_offset >= result.total);
for (const auto item : result.list) { for (const auto item : result.list) {
appendRow(item.user); appendRow(item.peer);
}; };
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
loadMoreRows(); loadMoreRows();
@ -234,15 +231,16 @@ void BlockedBoxController::loadMoreRows() {
auto handleContactsBlocked = [&](auto &list) { auto handleContactsBlocked = [&](auto &list) {
_window->session().data().processUsers(list.vusers()); _window->session().data().processUsers(list.vusers());
_window->session().data().processChats(list.vchats());
return list.vblocked().v; return list.vblocked().v;
}; };
switch (result.type()) { switch (result.type()) {
case mtpc_contacts_blockedSlice: { case mtpc_contacts_blockedSlice: {
receivedUsers(handleContactsBlocked(result.c_contacts_blockedSlice())); receivedPeers(handleContactsBlocked(result.c_contacts_blockedSlice()));
} break; } break;
case mtpc_contacts_blocked: { case mtpc_contacts_blocked: {
_allLoaded = true; _allLoaded = true;
receivedUsers(handleContactsBlocked(result.c_contacts_blocked())); receivedPeers(handleContactsBlocked(result.c_contacts_blocked()));
} break; } break;
default: Unexpected("Bad type() in MTPcontacts_GetBlocked() result."); default: Unexpected("Bad type() in MTPcontacts_GetBlocked() result.");
} }
@ -259,30 +257,28 @@ void BlockedBoxController::rowClicked(not_null<PeerListRow*> row) {
} }
void BlockedBoxController::rowActionClicked(not_null<PeerListRow*> row) { void BlockedBoxController::rowActionClicked(not_null<PeerListRow*> row) {
auto user = row->peer()->asUser(); _window->session().api().unblockPeer(row->peer());
Expects(user != nullptr);
_window->session().api().unblockUser(user);
} }
void BlockedBoxController::receivedUsers(const QVector<MTPContactBlocked> &result) { void BlockedBoxController::receivedPeers(
const QVector<MTPPeerBlocked> &result) {
if (result.empty()) { if (result.empty()) {
_allLoaded = true; _allLoaded = true;
} }
_offset += result.size(); _offset += result.size();
for (const auto &item : result) { for (const auto &item : result) {
item.match([&](const MTPDcontactBlocked &data) { item.match([&](const MTPDpeerBlocked &data) {
if (const auto user = _window->session().data().userLoaded(data.vuser_id().v)) { if (const auto peer = _window->session().data().peerLoaded(peerFromMTP(data.vpeer_id()))) {
appendRow(user); appendRow(peer);
user->setIsBlocked(true); peer->setIsBlocked(true);
} }
}); });
} }
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
} }
void BlockedBoxController::handleBlockedEvent(not_null<UserData*> user) { void BlockedBoxController::handleBlockedEvent(not_null<PeerData*> user) {
if (user->isBlocked()) { if (user->isBlocked()) {
if (prependRow(user)) { if (prependRow(user)) {
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
@ -294,13 +290,13 @@ void BlockedBoxController::handleBlockedEvent(not_null<UserData*> user) {
} }
} }
void BlockedBoxController::BlockNewUser( void BlockedBoxController::BlockNewPeer(
not_null<Window::SessionController*> window) { not_null<Window::SessionController*> window) {
auto controller = std::make_unique<BlockUserBoxController>(window); auto controller = std::make_unique<BlockPeerBoxController>(window);
auto initBox = [=, controller = controller.get()]( auto initBox = [=, controller = controller.get()](
not_null<PeerListBox*> box) { not_null<PeerListBox*> box) {
controller->setBlockUserCallback([=](not_null<UserData*> user) { controller->setBlockPeerCallback([=](not_null<PeerData*> peer) {
window->session().api().blockUser(user); window->session().api().blockPeer(peer);
box->closeBox(); box->closeBox();
}); });
box->addButton(tr::lng_cancel(), [box] { box->closeBox(); }); box->addButton(tr::lng_cancel(), [box] { box->closeBox(); });
@ -310,28 +306,31 @@ void BlockedBoxController::BlockNewUser(
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
} }
bool BlockedBoxController::appendRow(not_null<UserData*> user) { bool BlockedBoxController::appendRow(not_null<PeerData*> peer) {
if (delegate()->peerListFindRow(user->id)) { if (delegate()->peerListFindRow(peer->id)) {
return false; return false;
} }
delegate()->peerListAppendRow(createRow(user)); delegate()->peerListAppendRow(createRow(peer));
return true; return true;
} }
bool BlockedBoxController::prependRow(not_null<UserData*> user) { bool BlockedBoxController::prependRow(not_null<PeerData*> peer) {
if (delegate()->peerListFindRow(user->id)) { if (delegate()->peerListFindRow(peer->id)) {
return false; return false;
} }
delegate()->peerListPrependRow(createRow(user)); delegate()->peerListPrependRow(createRow(peer));
return true; return true;
} }
std::unique_ptr<PeerListRow> BlockedBoxController::createRow( std::unique_ptr<PeerListRow> BlockedBoxController::createRow(
not_null<UserData*> user) const { not_null<PeerData*> peer) const {
auto row = std::make_unique<PeerListRowWithLink>(user); auto row = std::make_unique<PeerListRowWithLink>(peer);
row->setActionLink(tr::lng_blocked_list_unblock(tr::now)); row->setActionLink(tr::lng_blocked_list_unblock(tr::now));
const auto status = [&] { const auto status = [&] {
if (!user->phone().isEmpty()) { const auto user = peer->asUser();
if (!user) {
return tr::lng_group_status(tr::now);
} else if (!user->phone().isEmpty()) {
return App::formatPhone(user->phone()); return App::formatPhone(user->phone());
} else if (!user->username.isEmpty()) { } else if (!user->username.isEmpty()) {
return '@' + user->username; return '@' + user->username;

View file

@ -31,15 +31,15 @@ public:
void rowActionClicked(not_null<PeerListRow*> row) override; void rowActionClicked(not_null<PeerListRow*> row) override;
void loadMoreRows() override; void loadMoreRows() override;
static void BlockNewUser(not_null<Window::SessionController*> window); static void BlockNewPeer(not_null<Window::SessionController*> window);
private: private:
void receivedUsers(const QVector<MTPContactBlocked> &result); void receivedPeers(const QVector<MTPPeerBlocked> &result);
void handleBlockedEvent(not_null<UserData*> user); void handleBlockedEvent(not_null<PeerData*> peer);
bool appendRow(not_null<UserData*> user); bool appendRow(not_null<PeerData*> peer);
bool prependRow(not_null<UserData*> user); bool prependRow(not_null<PeerData*> peer);
std::unique_ptr<PeerListRow> createRow(not_null<UserData*> user) const; std::unique_ptr<PeerListRow> createRow(not_null<PeerData*> peer) const;
const not_null<Window::SessionController*> _window; const not_null<Window::SessionController*> _window;
MTP::Sender _api; MTP::Sender _api;

View file

@ -104,10 +104,10 @@ rpl::producer<QString> PrivacyString(
}); });
} }
rpl::producer<int> BlockedUsersCount(not_null<::Main::Session*> session) { rpl::producer<int> BlockedPeersCount(not_null<::Main::Session*> session) {
session->api().reloadBlockedUsers(); session->api().reloadBlockedPeers();
return session->api().blockedUsersSlice( return session->api().blockedPeersSlice(
) | rpl::map([=](const ApiWrap::BlockedUsersSlice &data) { ) | rpl::map([=](const ApiWrap::BlockedPeersSlice &data) {
return data.total; return data.total;
}); });
} }
@ -120,7 +120,7 @@ void SetupPrivacy(
const auto session = &controller->session(); const auto session = &controller->session();
auto count = rpl::combine( auto count = rpl::combine(
BlockedUsersCount(session), BlockedPeersCount(session),
tr::lng_settings_no_blocked_users() tr::lng_settings_no_blocked_users()
) | rpl::map([](int count, const QString &none) { ) | rpl::map([](int count, const QString &none) {
return count ? QString::number(count) : none; return count ? QString::number(count) : none;
@ -136,7 +136,7 @@ void SetupPrivacy(
box->closeBox(); box->closeBox();
}); });
box->addLeftButton(tr::lng_blocked_list_add(), [=] { box->addLeftButton(tr::lng_blocked_list_add(), [=] {
BlockedBoxController::BlockNewUser(controller); BlockedBoxController::BlockNewPeer(controller);
}); });
}; };
Ui::show(Box<PeerListBox>( Ui::show(Box<PeerListBox>(

View file

@ -204,10 +204,10 @@ PeerData *readPeer(
const auto loaded = (peerId == selfId) const auto loaded = (peerId == selfId)
? session->user().get() ? session->user().get()
: session->data().peerLoaded(peerId); : session->data().peerLoaded(peerId);
const auto apply = !loaded || (loaded->loadedStatus != PeerData::FullLoaded); const auto apply = !loaded || !loaded->isFullLoaded();
const auto result = loaded ? loaded : session->data().peer(peerId).get(); const auto result = loaded ? loaded : session->data().peer(peerId).get();
if (apply) { if (apply) {
result->loadedStatus = PeerData::FullLoaded; result->setLoadedStatus(PeerData::LoadedStatus::Full);
} }
if (const auto user = result->asUser()) { if (const auto user = result->asUser()) {
QString first, last, phone, username, inlinePlaceholder; QString first, last, phone, username, inlinePlaceholder;

View file

@ -2282,15 +2282,14 @@ void Account::readSelf(
int32 streamVersion) { int32 streamVersion) {
QDataStream stream(serialized); QDataStream stream(serialized);
const auto user = session->user(); const auto user = session->user();
const auto wasLoadedStatus = std::exchange( const auto wasLoadedStatus = user->loadedStatus();
user->loadedStatus, user->setLoadedStatus(PeerData::LoadedStatus::Not);
PeerData::NotLoaded);
const auto self = Serialize::readPeer( const auto self = Serialize::readPeer(
session, session,
streamVersion, streamVersion,
stream); stream);
if (!self || !self->isSelf() || self != user) { if (!self || !self->isSelf() || self != user) {
user->loadedStatus = wasLoadedStatus; user->setLoadedStatus(wasLoadedStatus);
return; return;
} }

View file

@ -296,16 +296,14 @@ AdminLog::OwnedItem GenerateContactItem(
using Flag = MTPDmessage::Flag; using Flag = MTPDmessage::Flag;
const auto id = ServerMaxMsgId + (ServerMaxMsgId / 2) + 1; const auto id = ServerMaxMsgId + (ServerMaxMsgId / 2) + 1;
const auto flags = Flag::f_from_id | Flag::f_media | Flag::f_out; const auto flags = Flag::f_from_id | Flag::f_media | Flag::f_out;
const auto replyTo = 0;
const auto viaBotId = 0;
const auto message = MTP_message( const auto message = MTP_message(
MTP_flags(flags), MTP_flags(flags),
MTP_int(id), MTP_int(id),
MTP_int(history->session().userId()), peerToMTP(history->session().userPeerId()),
peerToMTP(history->peer->id), peerToMTP(history->peer->id),
MTPMessageFwdHeader(), MTPMessageFwdHeader(),
MTP_int(viaBotId), MTPint(), // via_bot_id
MTP_int(replyTo), MTPMessageReplyHeader(),
MTP_int(base::unixtime::now()), MTP_int(base::unixtime::now()),
MTP_string(), MTP_string(),
MTP_messageMediaContact( MTP_messageMediaContact(
@ -316,8 +314,10 @@ AdminLog::OwnedItem GenerateContactItem(
MTP_int(0)), MTP_int(0)),
MTPReplyMarkup(), MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(), MTPVector<MTPMessageEntity>(),
MTP_int(0), MTPint(), // views
MTP_int(0), MTPint(), // forwards
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(), MTP_string(),
MTP_long(0), MTP_long(0),
//MTPMessageReactions(), //MTPMessageReactions(),

View file

@ -54,6 +54,25 @@ ImageWithLocation FromPhotoSize(
.bytes = bytes, .bytes = bytes,
.bytesCount = bytes.size(), .bytesCount = bytes.size(),
}; };
}, [&](const MTPDphotoSizeProgressive &data) {
// #TODO layer118
if (data.vsizes().v.isEmpty()) {
return ImageWithLocation();
}
return ImageWithLocation{
.location = ImageLocation(
DownloadLocation{ StorageFileLocation(
photo.vdc_id().v,
session->userId(),
MTP_inputPhotoFileLocation(
photo.vid(),
photo.vaccess_hash(),
photo.vfile_reference(),
data.vtype())) },
data.vw().v,
data.vh().v),
.bytesCount = data.vsizes().v.back().v
};
}, [&](const MTPDphotoStrippedSize &data) { }, [&](const MTPDphotoStrippedSize &data) {
return ImageWithLocation(); return ImageWithLocation();
//const auto bytes = ExpandInlineBytes(qba(data.vbytes())); //const auto bytes = ExpandInlineBytes(qba(data.vbytes()));
@ -113,6 +132,25 @@ ImageWithLocation FromPhotoSize(
.bytes = bytes, .bytes = bytes,
.bytesCount = bytes.size(), .bytesCount = bytes.size(),
}; };
}, [&](const MTPDphotoSizeProgressive &data) {
// #TODO layer118
if (data.vsizes().v.isEmpty()) {
return ImageWithLocation();
}
return ImageWithLocation{
.location = ImageLocation(
DownloadLocation{ StorageFileLocation(
document.vdc_id().v,
session->userId(),
MTP_inputDocumentFileLocation(
document.vid(),
document.vaccess_hash(),
document.vfile_reference(),
data.vtype())) },
data.vw().v,
data.vh().v),
.bytesCount = data.vsizes().v.back().v
};
}, [&](const MTPDphotoStrippedSize &data) { }, [&](const MTPDphotoStrippedSize &data) {
return ImageWithLocation(); return ImageWithLocation();
//const auto bytes = ExpandInlineBytes(qba(data.vbytes())); //const auto bytes = ExpandInlineBytes(qba(data.vbytes()));
@ -175,6 +213,25 @@ ImageWithLocation FromPhotoSize(
.bytes = bytes, .bytes = bytes,
.bytesCount = bytes.size(), .bytesCount = bytes.size(),
}; };
}, [&](const MTPDphotoSizeProgressive &data) {
// #TODO layer118
if (data.vsizes().v.isEmpty()) {
return ImageWithLocation();
}
const auto &location = data.vlocation().c_fileLocationToBeDeprecated();
return ImageWithLocation{
.location = ImageLocation(
DownloadLocation{ StorageFileLocation(
set.vthumb_dc_id()->v,
session->userId(),
MTP_inputStickerSetThumb(
MTP_inputStickerSetID(set.vid(), set.vaccess_hash()),
location.vvolume_id(),
location.vlocal_id())) },
data.vw().v,
data.vh().v),
.bytesCount = data.vsizes().v.back().v
};
}, [&](const MTPDphotoStrippedSize &data) { }, [&](const MTPDphotoStrippedSize &data) {
return ImageWithLocation(); return ImageWithLocation();
//const auto bytes = ExpandInlineBytes(qba(data.vbytes())); //const auto bytes = ExpandInlineBytes(qba(data.vbytes()));

View file

@ -433,7 +433,7 @@ void Filler::addBlockUser(not_null<UserData*> user) {
if (user->isBlocked()) { if (user->isBlocked()) {
PeerMenuUnblockUserWithBotRestart(user); PeerMenuUnblockUserWithBotRestart(user);
} else if (user->isBot()) { } else if (user->isBot()) {
user->session().api().blockUser(user); user->session().api().blockPeer(user);
} else { } else {
window->show(Box(PeerMenuBlockUserBox, window, user, false)); window->show(Box(PeerMenuBlockUserBox, window, user, false));
} }
@ -889,7 +889,7 @@ void PeerMenuBlockUserBox(
box->closeBox(); box->closeBox();
user->session().api().blockUser(user); user->session().api().blockPeer(user);
if (reportChecked) { if (reportChecked) {
user->session().api().request(MTPmessages_ReportSpam( user->session().api().request(MTPmessages_ReportSpam(
user->input user->input
@ -912,7 +912,7 @@ void PeerMenuBlockUserBox(
} }
void PeerMenuUnblockUserWithBotRestart(not_null<UserData*> user) { void PeerMenuUnblockUserWithBotRestart(not_null<UserData*> user) {
user->session().api().unblockUser(user, [=] { user->session().api().unblockPeer(user, [=] {
if (user->isBot() && !user->isSupport()) { if (user->isBot() && !user->isSupport()) {
user->session().api().sendBotStart(user); user->session().api().sendBotStart(user);
} }