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;
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;
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;
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#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;
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;
photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int 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;
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;
contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus;
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.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.blocked#ade1591 blocked:Vector<PeerBlocked> chats:Vector<Chat> 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.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;
updateChatParticipantDelete#6e5f8c22 chat_id:int user_id:int version:int = Update;
updateDcOptions#8e5e9873 dc_options:Vector<DcOption> = Update;
updateUserBlocked#80ece81a user_id:int blocked:Bool = 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;
updatePrivacy#ee3b272a key:PrivacyKey rules:Vector<PrivacyRule> = Update;
@ -358,6 +356,9 @@ updateDialogFilterOrder#a5d72105 order:Vector<int> = Update;
updateDialogFilters#3504914f = 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;
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;
@ -367,8 +368,8 @@ updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_mess
updates.differenceTooLong#4afe8f6d pts:int = updates.Difference;
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;
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;
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#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;
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;
@ -601,7 +602,7 @@ channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:
channelParticipant#15ebac1d user_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;
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;
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.codeTypeCall#741cd3e3 = auth.CodeType;
@ -1029,7 +1030,7 @@ chatOnlines#f041e250 onlines:int = ChatOnlines;
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;
@ -1157,6 +1158,20 @@ help.country#c3878e23 flags:# hidden:flags.0?true iso2:string default_name:strin
help.countriesListNotModified#93cc1f32 = 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---
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.deleteContacts#96a0e00 id:Vector<InputUser> = Updates;
contacts.deleteByPhones#1013fd9e phones:Vector<string> = Bool;
contacts.block#332b49fc id:InputUser = Bool;
contacts.unblock#e54100bd id:InputUser = Bool;
contacts.block#68cc1411 id:InputPeer = Bool;
contacts.unblock#bea65d50 id:InputPeer = Bool;
contacts.getBlocked#f57c350f offset:int limit:int = contacts.Blocked;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
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.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.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.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;
@ -1289,7 +1304,7 @@ messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
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.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.getPeerSettings#3672e09c peer:InputPeer = PeerSettings;
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.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
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.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.getDocumentByHash#338e2464 sha256:bytes size:int mime_type:string = Document;
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.updateDialogFiltersOrder#c563c1e4 order:Vector<int> = Bool;
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.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.inviteToChannel#199f3a6c channel:InputChannel users:Vector<InputUser> = 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.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;
@ -1519,5 +1537,7 @@ folders.deleteFolder#1c295881 folder_id:int = Updates;
stats.getBroadcastStats#ab42441a flags:# dark:flags.0?true channel:InputChannel = stats.BroadcastStats;
stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
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 sendFlags = MTPmessages_SendMedia::Flags(0);
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;
}
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
@ -89,7 +89,7 @@ void SendExistingMedia(
if (silentPost) {
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 caption = TextWithEntities{
@ -249,9 +249,10 @@ bool SendDice(Api::MessageToSend &message) {
auto clientFlags = NewMessageClientFlags();
auto sendFlags = MTPmessages_SendMedia::Flags(0);
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;
}
const auto replyHeader = NewMessageReplyHeader(message.action);
const auto channelPost = peer->isChannel() && !peer->isMegagroup();
const auto silentPost = message.action.options.silent
|| (channelPost && session->data().notifySilentPosts(peer));
@ -259,7 +260,7 @@ bool SendDice(Api::MessageToSend &message) {
if (silentPost) {
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();
const auto replyTo = message.action.replyTo;
@ -272,23 +273,27 @@ bool SendDice(Api::MessageToSend &message) {
session->data().registerMessageRandomId(randomId, newId);
const auto views = 1;
const auto forwards = 0;
history->addNewMessage(
MTP_message(
MTP_flags(flags),
MTP_int(newId.msg),
MTP_int(messageFromId),
peerToMTP(messageFromId),
peerToMTP(history->peer->id),
MTPMessageFwdHeader(),
MTP_int(0),
MTP_int(replyTo),
MTPint(), // via_bot_id
replyHeader,
MTP_int(HistoryItem::NewMessageDate(
message.action.options.scheduled)),
MTP_string(),
MTP_messageMediaDice(MTP_int(0), MTP_string(emoji)),
MTPReplyMarkup(),
MTP_vector<MTPMessageEntity>(),
MTP_int(1),
MTPint(),
MTP_int(views),
MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor),
MTPlong(),
//MTPMessageReactions(),
@ -387,8 +392,9 @@ void SendConfirmedFile(
| MTPDmessage::Flag::f_media;
auto clientFlags = NewMessageClientFlags();
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 silentPost = file->to.options.silent;
Api::FillMessagePostFlags(action, peer, flags);
@ -406,11 +412,13 @@ void SendConfirmedFile(
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
? session->user()->name
: QString();
const auto views = 1;
const auto forwards = 0;
if (file->type == SendMediaType::Photo) {
const auto photoFlags = MTPDmessageMediaPhoto::Flag::f_photo | 0;
const auto photo = MTP_messageMediaPhoto(
@ -421,18 +429,20 @@ void SendConfirmedFile(
const auto mtpMessage = MTP_message(
MTP_flags(flags),
MTP_int(newId.msg),
MTP_int(messageFromId),
peerToMTP(messageFromId),
peerToMTP(file->to.peer),
MTPMessageFwdHeader(),
MTPint(),
MTP_int(file->to.replyTo),
replyHeader,
MTP_int(HistoryItem::NewMessageDate(file->to.options.scheduled)),
MTP_string(caption.text),
photo,
MTPReplyMarkup(),
localEntities,
MTP_int(1),
MTPint(),
MTP_int(views),
MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor),
MTP_long(groupId),
//MTPMessageReactions(),
@ -457,18 +467,20 @@ void SendConfirmedFile(
const auto mtpMessage = MTP_message(
MTP_flags(flags),
MTP_int(newId.msg),
MTP_int(messageFromId),
peerToMTP(messageFromId),
peerToMTP(file->to.peer),
MTPMessageFwdHeader(),
MTPint(),
MTP_int(file->to.replyTo),
replyHeader,
MTP_int(HistoryItem::NewMessageDate(file->to.options.scheduled)),
MTP_string(caption.text),
document,
MTPReplyMarkup(),
localEntities,
MTP_int(1),
MTPint(),
MTP_int(views),
MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor),
MTP_long(groupId),
//MTPMessageReactions(),
@ -496,19 +508,21 @@ void SendConfirmedFile(
MTP_message(
MTP_flags(flags),
MTP_int(newId.msg),
MTP_int(messageFromId),
peerToMTP(messageFromId),
peerToMTP(file->to.peer),
MTPMessageFwdHeader(),
MTPint(),
MTP_int(file->to.replyTo),
replyHeader,
MTP_int(
HistoryItem::NewMessageDate(file->to.options.scheduled)),
MTP_string(caption.text),
document,
MTPReplyMarkup(),
localEntities,
MTP_int(1),
MTPint(),
MTP_int(views),
MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor),
MTP_long(groupId),
//MTPMessageReactions(),

View file

@ -97,20 +97,9 @@ bool ForwardedInfoDataLoaded(
not_null<Main::Session*> session,
const MTPMessageFwdHeader &header) {
return header.match([&](const MTPDmessageFwdHeader &data) {
if (const auto channelId = data.vchannel_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()) {
if (const auto fromId = data.vfrom_id()) {
// Fully loaded is required in this case.
if (!session->data().userLoaded(fromId->v)) {
if (!session->data().peerLoaded(peerFromMTP(*fromId))) {
return false;
}
}
@ -145,7 +134,7 @@ DataIsLoadedResult AllDataLoadedForMessage(
return message.match([&](const MTPDmessage &message) {
if (const auto fromId = message.vfrom_id()) {
if (!message.is_post()
&& !session->data().userLoaded(fromId->v)) {
&& !session->data().peerLoaded(peerFromMTP(*fromId))) {
return DataIsLoadedResult::FromNotLoaded;
}
}
@ -168,7 +157,7 @@ DataIsLoadedResult AllDataLoadedForMessage(
}, [&](const MTPDmessageService &message) {
if (const auto fromId = message.vfrom_id()) {
if (!message.is_post()
&& !session->data().userLoaded(fromId->v)) {
&& !session->data().peerLoaded(peerFromMTP(*fromId))) {
return DataIsLoadedResult::FromNotLoaded;
}
}
@ -890,23 +879,26 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
const auto peerUserId = d.is_out()
? d.vuser_id()
: MTP_int(_session->userId());
const auto fwd = d.vfwd_from();
_session->data().addNewMessage(
MTP_message(
MTP_flags(flags),
d.vid(),
d.is_out() ? MTP_int(_session->userId()) : d.vuser_id(),
MTP_peerUser(peerUserId),
fwd ? (*fwd) : MTPMessageFwdHeader(),
(d.is_out()
? peerToMTP(_session->userPeerId())
: 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.vreply_to_msg_id().value_or_empty()),
d.vreply_to() ? *d.vreply_to() : MTPMessageReplyHeader(),
d.vdate(),
d.vmessage(),
MTP_messageMediaEmpty(),
MTPReplyMarkup(),
MTP_vector<MTPMessageEntity>(d.ventities().value_or_empty()),
MTPint(),
MTPint(),
MTPint(), // views
MTPint(), // forwards
MTPMessageReplies(),
MTPint(), // edit_date
MTPstring(),
MTPlong(),
//MTPMessageReactions(),
@ -917,24 +909,26 @@ void Updates::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
case mtpc_updateShortChatMessage: {
const auto &d = updates.c_updateShortChatMessage();
const auto flags = mtpCastFlags(d.vflags().v) | MTPDmessage::Flag::f_from_id;
const auto fwd = d.vfwd_from();
const auto flags = mtpCastFlags(d.vflags().v)
| MTPDmessage::Flag::f_from_id;
_session->data().addNewMessage(
MTP_message(
MTP_flags(flags),
d.vid(),
d.vfrom_id(),
MTP_peerUser(d.vfrom_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.vreply_to_msg_id().value_or_empty()),
d.vreply_to() ? *d.vreply_to() : MTPMessageReplyHeader(),
d.vdate(),
d.vmessage(),
MTP_messageMediaEmpty(),
MTPReplyMarkup(),
MTP_vector<MTPMessageEntity>(d.ventities().value_or_empty()),
MTPint(),
MTPint(),
MTPint(), // views
MTPint(), // forwards
MTPMessageReplies(),
MTPint(), // edit_date
MTPstring(),
MTPlong(),
//MTPMessageReactions(),
@ -1731,10 +1725,10 @@ void Updates::feedUpdate(const MTPUpdate &update) {
Core::App().calls().handleUpdate(&session(), update);
} break;
case mtpc_updateUserBlocked: {
const auto &d = update.c_updateUserBlocked();
if (const auto user = session().data().userLoaded(d.vuser_id().v)) {
user->setIsBlocked(mtpIsTrue(d.vblocked()));
case mtpc_updatePeerBlocked: {
const auto &d = update.c_updatePeerBlocked();
if (const auto peer = session().data().peerLoaded(peerFromMTP(d.vpeer_id()))) {
peer->setIsBlocked(mtpIsTrue(d.vblocked()));
}
} break;
@ -1912,12 +1906,19 @@ void Updates::feedUpdate(const MTPUpdate &update) {
} break;
case mtpc_updateChannelMessageViews: {
auto &d = update.c_updateChannelMessageViews();
if (auto item = session().data().message(d.vchannel_id().v, d.vid().v)) {
const auto &d = update.c_updateChannelMessageViews();
if (const auto item = session().data().message(d.vchannel_id().v, d.vid().v)) {
item->setViewsCount(d.vviews().v);
}
} 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: {
auto &d = update.c_updateChannelAvailableMessages();
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;
}
bool ApiWrap::BlockedUsersSlice::Item::operator==(const Item &other) const {
return (user == other.user) && (date == other.date);
bool ApiWrap::BlockedPeersSlice::Item::operator==(const Item &other) const {
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);
}
bool ApiWrap::BlockedUsersSlice::operator==(const BlockedUsersSlice &other) const {
bool ApiWrap::BlockedPeersSlice::operator==(const BlockedPeersSlice &other) const {
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);
}
@ -709,9 +709,9 @@ QString ApiWrap::exportDirectMessageLink(not_null<HistoryItem*> item) {
? i->second
: fallback();
request(MTPchannels_ExportMessageLink(
MTP_flags(0),
channel->inputChannel,
MTP_int(item->id),
MTP_bool(false)
MTP_int(item->id)
)).done([=](const MTPExportedMessageLink &result) {
const auto link = result.match([&](const auto &data) {
return qs(data.vlink());
@ -2003,64 +2003,66 @@ void ApiWrap::leaveChannel(not_null<ChannelData*> channel) {
}
}
void ApiWrap::blockUser(not_null<UserData*> user) {
if (user->isBlocked()) {
void ApiWrap::blockPeer(not_null<PeerData*> peer) {
if (peer->isBlocked()) {
session().changes().peerUpdated(
user,
peer,
Data::PeerUpdate::Flag::IsBlocked);
} else if (_blockRequests.find(user) == end(_blockRequests)) {
const auto requestId = request(MTPcontacts_Block(user->inputUser)).done([this, user](const MTPBool &result) {
_blockRequests.erase(user);
user->setIsBlocked(true);
if (_blockedUsersSlice) {
_blockedUsersSlice->list.insert(
_blockedUsersSlice->list.begin(),
{ user, base::unixtime::now() });
++_blockedUsersSlice->total;
_blockedUsersChanges.fire_copy(*_blockedUsersSlice);
} else if (_blockRequests.find(peer) == end(_blockRequests)) {
const auto requestId = request(MTPcontacts_Block(
peer->input
)).done([=](const MTPBool &result) {
_blockRequests.erase(peer);
peer->setIsBlocked(true);
if (_blockedPeersSlice) {
_blockedPeersSlice->list.insert(
_blockedPeersSlice->list.begin(),
{ peer, base::unixtime::now() });
++_blockedPeersSlice->total;
_blockedPeersChanges.fire_copy(*_blockedPeersSlice);
}
}).fail([this, user](const RPCError &error) {
_blockRequests.erase(user);
}).fail([=](const RPCError &error) {
_blockRequests.erase(peer);
}).send();
_blockRequests.emplace(user, requestId);
_blockRequests.emplace(peer, requestId);
}
}
void ApiWrap::unblockUser(not_null<UserData*> user, Fn<void()> onDone) {
if (!user->isBlocked()) {
void ApiWrap::unblockPeer(not_null<PeerData*> peer, Fn<void()> onDone) {
if (!peer->isBlocked()) {
session().changes().peerUpdated(
user,
peer,
Data::PeerUpdate::Flag::IsBlocked);
return;
} else if (_blockRequests.find(user) != end(_blockRequests)) {
} else if (_blockRequests.find(peer) != end(_blockRequests)) {
return;
}
const auto requestId = request(MTPcontacts_Unblock(
user->inputUser
peer->input
)).done([=](const MTPBool &result) {
_blockRequests.erase(user);
user->setIsBlocked(false);
if (_blockedUsersSlice) {
auto &list = _blockedUsersSlice->list;
_blockRequests.erase(peer);
peer->setIsBlocked(false);
if (_blockedPeersSlice) {
auto &list = _blockedPeersSlice->list;
for (auto i = list.begin(); i != list.end(); ++i) {
if (i->user == user) {
if (i->peer == peer) {
list.erase(i);
break;
}
}
if (_blockedUsersSlice->total > list.size()) {
--_blockedUsersSlice->total;
if (_blockedPeersSlice->total > list.size()) {
--_blockedPeersSlice->total;
}
_blockedUsersChanges.fire_copy(*_blockedUsersSlice);
_blockedPeersChanges.fire_copy(*_blockedPeersSlice);
}
if (onDone) {
onDone();
}
}).fail([=](const RPCError &error) {
_blockRequests.erase(user);
_blockRequests.erase(peer);
}).send();
_blockRequests.emplace(user, requestId);
_blockRequests.emplace(peer, requestId);
}
void ApiWrap::exportInviteLink(not_null<PeerData*> peer) {
@ -2203,7 +2205,7 @@ void ApiWrap::handlePrivacyChange(
void ApiWrap::updatePrivacyLastSeens(const QVector<MTPPrivacyRule> &rules) {
const auto now = base::unixtime::now();
_session->data().enumerateUsers([&](UserData *user) {
if (user->isSelf() || user->loadedStatus != PeerData::FullLoaded) {
if (user->isSelf() || !user->isFullLoaded()) {
return;
}
if (user->onlineTill <= 0) {
@ -3915,7 +3917,6 @@ void ApiWrap::forwardMessages(
}
auto forwardFrom = items.front()->history()->peer;
auto currentGroupId = items.front()->groupId();
auto ids = QVector<MTPint>();
auto randomIds = QVector<MTPlong>();
auto localIds = std::shared_ptr<base::flat_map<uint64, FullMsgId>>();
@ -3924,14 +3925,10 @@ void ApiWrap::forwardMessages(
if (shared) {
++shared->requestsLeft;
}
const auto finalFlags = sendFlags
| (currentGroupId == MessageGroupId()
? MTPmessages_ForwardMessages::Flag(0)
: MTPmessages_ForwardMessages::Flag::f_grouped);
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_ForwardMessages(
MTP_flags(finalFlags),
MTP_flags(sendFlags),
forwardFrom->input,
MTP_vector<MTPint>(ids),
MTP_vector<MTPlong>(randomIds),
@ -3974,8 +3971,8 @@ void ApiWrap::forwardMessages(
_session->data().nextLocalMessageId());
const auto self = _session->user();
const auto messageFromId = channelPost
? UserId(0)
: peerToUser(self->id);
? PeerId(0)
: self->id;
const auto messagePostAuthor = channelPost
? self->name
: QString();
@ -3996,11 +3993,9 @@ void ApiWrap::forwardMessages(
}
const auto newFrom = item->history()->peer;
const auto newGroupId = item->groupId();
if (forwardFrom != newFrom
|| currentGroupId != newGroupId) {
if (forwardFrom != newFrom) {
sendAccumulated();
forwardFrom = newFrom;
currentGroupId = newGroupId;
}
ids.push_back(MTP_int(item->id));
randomIds.push_back(MTP_long(randomId));
@ -4053,15 +4048,16 @@ void ApiWrap::sendSharedContact(
auto flags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media;
auto clientFlags = NewMessageClientFlags();
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);
if (action.options.scheduled) {
flags |= MTPDmessage::Flag::f_from_scheduled;
} else {
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
? _session->user()->name
: QString();
@ -4072,11 +4068,11 @@ void ApiWrap::sendSharedContact(
MTP_message(
MTP_flags(flags),
MTP_int(newId.msg),
MTP_int(messageFromId),
peerToMTP(messageFromId),
peerToMTP(peer->id),
MTPMessageFwdHeader(),
MTPint(),
MTP_int(action.replyTo),
MTPint(), // via_bot_id
replyHeader,
MTP_int(HistoryItem::NewMessageDate(action.options.scheduled)),
MTP_string(),
MTP_messageMediaContact(
@ -4088,7 +4084,9 @@ void ApiWrap::sendSharedContact(
MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(),
MTP_int(views),
MTPint(),
MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor),
MTPlong(),
//MTPMessageReactions(),
@ -4310,9 +4308,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
auto clientFlags = NewMessageClientFlags();
auto sendFlags = MTPmessages_SendMessage::Flags(0);
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;
}
const auto replyHeader = NewMessageReplyHeader(action);
MTPMessageMedia media = MTP_messageMediaEmpty();
if (message.webPageId == CancelledWebPageId) {
sendFlags |= MTPmessages_SendMessage::Flag::f_no_webpage;
@ -4346,7 +4345,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
history->clearCloudDraft();
history->setSentDraftText(QString());
}
auto messageFromId = channelPost ? 0 : _session->userId();
auto messageFromId = channelPost ? 0 : _session->userPeerId();
auto messagePostAuthor = channelPost
? _session->user()->name
: QString();
@ -4356,23 +4355,27 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
} else {
clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry;
}
const auto views = 1;
const auto forwards = 0;
lastMessage = history->addNewMessage(
MTP_message(
MTP_flags(flags),
MTP_int(newId.msg),
MTP_int(messageFromId),
peerToMTP(messageFromId),
peerToMTP(peer->id),
MTPMessageFwdHeader(),
MTPint(),
MTP_int(action.replyTo),
MTPint(), // via_bot_id
replyHeader,
MTP_int(
HistoryItem::NewMessageDate(action.options.scheduled)),
msgText,
media,
MTPReplyMarkup(),
localEntities,
MTP_int(1),
MTPint(),
MTP_int(views),
MTP_int(forwards),
MTPMessageReplies(),
MTPint(), // edit_date
MTP_string(messagePostAuthor),
MTPlong(),
//MTPMessageReactions(),
@ -4459,7 +4462,7 @@ void ApiWrap::sendInlineResult(
auto clientFlags = NewMessageClientFlags();
auto sendFlags = MTPmessages_SendInlineBotResult::Flag::f_clear_draft | 0;
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;
}
bool channelPost = peer->isChannel() && !peer->isMegagroup();
@ -4479,7 +4482,7 @@ void ApiWrap::sendInlineResult(
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
? _session->user()->name
: QString();
@ -5119,34 +5122,34 @@ auto ApiWrap::privacyValue(Privacy::Key key) -> rpl::producer<Privacy> {
}
}
void ApiWrap::reloadBlockedUsers() {
if (_blockedUsersRequestId) {
void ApiWrap::reloadBlockedPeers() {
if (_blockedPeersRequestId) {
return;
}
_blockedUsersRequestId = request(MTPcontacts_GetBlocked(
_blockedPeersRequestId = request(MTPcontacts_GetBlocked(
MTP_int(0),
MTP_int(kBlockedFirstSlice)
)).done([=](const MTPcontacts_Blocked &result) {
_blockedUsersRequestId = 0;
_blockedPeersRequestId = 0;
const auto push = [&](
int count,
const QVector<MTPContactBlocked> &list) {
auto slice = BlockedUsersSlice();
const QVector<MTPPeerBlocked> &list) {
auto slice = BlockedPeersSlice();
slice.total = std::max(count, list.size());
slice.list.reserve(list.size());
for (const auto &contact : list) {
contact.match([&](const MTPDcontactBlocked &data) {
const auto user = _session->data().userLoaded(
data.vuser_id().v);
if (user) {
user->setIsBlocked(true);
slice.list.push_back({ user, data.vdate().v });
contact.match([&](const MTPDpeerBlocked &data) {
const auto peer = _session->data().peerLoaded(
peerFromMTP(data.vpeer_id()));
if (peer) {
peer->setIsBlocked(true);
slice.list.push_back({ peer, data.vdate().v });
}
});
}
if (!_blockedUsersSlice || *_blockedUsersSlice != slice) {
_blockedUsersSlice = slice;
_blockedUsersChanges.fire(std::move(slice));
if (!_blockedPeersSlice || *_blockedPeersSlice != slice) {
_blockedPeersSlice = slice;
_blockedPeersChanges.fire(std::move(slice));
}
};
result.match([&](const MTPDcontacts_blockedSlice &data) {
@ -5157,17 +5160,17 @@ void ApiWrap::reloadBlockedUsers() {
push(0, data.vblocked().v);
});
}).fail([=](const RPCError &error) {
_blockedUsersRequestId = 0;
_blockedPeersRequestId = 0;
}).send();
}
auto ApiWrap::blockedUsersSlice() -> rpl::producer<BlockedUsersSlice> {
if (!_blockedUsersSlice) {
reloadBlockedUsers();
auto ApiWrap::blockedPeersSlice() -> rpl::producer<BlockedPeersSlice> {
if (!_blockedPeersSlice) {
reloadBlockedPeers();
}
return _blockedUsersSlice
? _blockedUsersChanges.events_starting_with_copy(*_blockedUsersSlice)
: (_blockedUsersChanges.events() | rpl::type_erased());
return _blockedPeersSlice
? _blockedPeersChanges.events_starting_with_copy(*_blockedPeersSlice)
: (_blockedPeersChanges.events() | rpl::type_erased());
}
Api::SelfDestruct &ApiWrap::selfDestruct() {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -815,6 +815,28 @@ bool PeerData::canSendPolls() const {
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 {
std::vector<ChatRestrictions> ListOfRestrictions() {

View file

@ -349,15 +349,37 @@ public:
: (_settings.value() | rpl::type_erased());
}
enum LoadedStatus {
NotLoaded = 0x00,
MinimalLoaded = 0x01,
FullLoaded = 0x02,
enum class BlockStatus : char {
Unknown,
Blocked,
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;
QString name;
LoadedStatus loadedStatus = NotLoaded;
MTPinputPeer input;
int nameVersion = 1;
@ -400,6 +422,8 @@ private:
MsgId _pinnedMessageId = 0;
Settings _settings = { kSettingsUnknown };
BlockStatus _blockStatus = BlockStatus::Unknown;
LoadedStatus _loadedStatus = LoadedStatus::Not;
QString _about;

View file

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

View file

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

View file

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

View file

@ -333,7 +333,7 @@ PeerData *Session::peerLoaded(PeerId id) const {
const auto i = _peers.find(id);
if (i == end(_peers)) {
return nullptr;
} else if (i->second->loadedStatus != PeerData::FullLoaded) {
} else if (!i->second->isFullLoaded()) {
return nullptr;
}
return i->second.get();
@ -507,12 +507,12 @@ not_null<UserData*> Session::processUser(const MTPUser &data) {
});
if (minimal) {
if (result->loadedStatus == PeerData::NotLoaded) {
result->loadedStatus = PeerData::MinimalLoaded;
if (!result->isMinimalLoaded()) {
result->setLoadedStatus(PeerData::LoadedStatus::Minimal);
}
} else if (result->loadedStatus != PeerData::FullLoaded
} else if (!result->isFullLoaded()
&& (!result->isSelf() || !result->phone().isEmpty())) {
result->loadedStatus = PeerData::FullLoaded;
result->setLoadedStatus(PeerData::LoadedStatus::Full);
}
if (status && !minimal) {
@ -618,10 +618,8 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
const auto channel = result->asChannel();
minimal = data.is_min();
if (minimal) {
if (result->loadedStatus != PeerData::FullLoaded) {
LOG(("API Warning: not loaded minimal channel applied."));
}
if (minimal && !result->isFullLoaded()) {
LOG(("API Warning: not loaded minimal channel applied."));
}
const auto wasInChannel = channel->amIn();
@ -728,11 +726,11 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
});
if (minimal) {
if (result->loadedStatus == PeerData::NotLoaded) {
result->loadedStatus = PeerData::MinimalLoaded;
if (!result->isMinimalLoaded()) {
result->setLoadedStatus(PeerData::LoadedStatus::Minimal);
}
} else if (result->loadedStatus != PeerData::FullLoaded) {
result->loadedStatus = PeerData::FullLoaded;
} else if (!result->isFullLoaded()) {
result->setLoadedStatus(PeerData::LoadedStatus::Full);
}
if (flags) {
session().changes().peerUpdated(result, flags);
@ -1052,7 +1050,7 @@ void Session::setupUserIsContactViewer() {
requestViewResize(view);
}
}
if (user->loadedStatus != PeerData::FullLoaded) {
if (!user->isFullLoaded()) {
LOG(("API Error: "
"userIsContactChanged() called for a not loaded user!"));
return;
@ -1650,36 +1648,44 @@ void Session::reorderTwoPinnedChats(
}
bool Session::checkEntitiesAndViewsUpdate(const MTPDmessage &data) {
const auto peer = [&] {
const auto result = peerFromMTP(data.vto_id());
if (const auto fromId = data.vfrom_id()) {
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;
}
const auto peer = peerFromMTP(data.vpeer_id());
const auto existing = message(peerToChannel(peer), data.vid().v);
if (!existing) {
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) {
@ -1687,15 +1693,7 @@ void Session::updateEditedMessage(const MTPMessage &data) {
-> HistoryItem* {
return nullptr;
}, [&](const auto &data) {
const auto peer = [&] {
const auto result = peerFromMTP(data.vto_id());
if (const auto fromId = data.vfrom_id()) {
if (result == session().userPeerId()) {
return peerFromUser(*fromId);
}
}
return result;
}();
const auto peer = peerFromMTP(data.vpeer_id());
return message(peerToChannel(peer), data.vid().v);
});
if (!existing) {
@ -3742,18 +3740,20 @@ void Session::insertCheckedServiceNotification(
MTP_message(
MTP_flags(flags),
MTP_int(nextLocalMessageId()),
MTP_int(peerToUser(PeerData::kServiceNotificationsId)),
MTP_peerUser(MTP_int(_session->userId())),
peerToMTP(PeerData::kServiceNotificationsId),
peerToMTP(PeerData::kServiceNotificationsId),
MTPMessageFwdHeader(),
MTPint(),
MTPint(),
MTPint(), // via_bot_id
MTPMessageReplyHeader(),
MTP_int(date),
MTP_string(sending.text),
media,
MTPReplyMarkup(),
Api::EntitiesToMTP(&session(), sending.entities),
MTPint(),
MTPint(),
MTPint(), // views
MTPint(), // forwards
MTPMessageReplies(),
MTPint(), // edit_date
MTPstring(),
MTPlong(),
//MTPMessageReactions(),

View file

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

View file

@ -180,19 +180,6 @@ public:
}
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 {
Unknown,
Enabled,
@ -225,7 +212,6 @@ private:
std::vector<Data::UnavailableReason> _unavailableReasons;
QString _phone;
ContactStatus _contactStatus = ContactStatus::Unknown;
BlockStatus _blockStatus = BlockStatus::Unknown;
CallsStatus _callsStatus = CallsStatus::Unknown;
int _commonChatsCount = 0;

View file

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

View file

@ -264,6 +264,9 @@ Image ParseMaxImage(
if constexpr (MTPDphotoCachedSize::Is<decltype(data)>()) {
result.file.content = data.vbytes().v;
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 {
result.file.content = QByteArray();
result.file.size = data.vsize().v;
@ -422,6 +425,9 @@ Image ParseDocumentThumb(
if constexpr (MTPDphotoCachedSize::Is<decltype(data)>()) {
result.file.content = data.vbytes().v;
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 {
result.file.content = QByteArray();
result.file.size = data.vsize().v;
@ -1122,24 +1128,27 @@ Message ParseMessage(
data.match([&](const auto &data) {
result.id = data.vid().v;
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.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) {
@ -1149,12 +1158,9 @@ Message ParseMessage(
if (const auto fwdFrom = data.vfwd_from()) {
result.forwardedFromId = fwdFrom->match(
[](const MTPDmessageFwdHeader &data) {
if (const auto channelId = data.vchannel_id()) {
return ChatPeerId(channelId->v);
} else if (const auto fromId = data.vfrom_id()) {
return UserPeerId(fromId->v);
}
return PeerId(0);
return data.vfrom_id()
? ParsePeerId(*data.vfrom_id())
: PeerId(0);
});
result.forwardedFromName = fwdFrom->match(
[](const MTPDmessageFwdHeader &data) {
@ -1180,8 +1186,13 @@ Message ParseMessage(
if (const auto postAuthor = data.vpost_author()) {
result.signature = ParseString(*postAuthor);
}
if (const auto replyToMsgId = data.vreply_to_msg_id()) {
result.replyToMsgId = replyToMsgId->v;
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())
: PeerId(0);
});
}
if (const auto viaBotId = data.vvia_bot_id()) {
result.viaBotId = viaBotId->v;
@ -1219,9 +1230,10 @@ Message ParseMessage(
}
std::map<uint64, Message> ParseMessagesList(
PeerId selfId,
const MTPVector<MTPMessage> &data,
const QString &mediaFolder) {
auto context = ParseMediaContext();
auto context = ParseMediaContext{ .selfPeerId = selfId };
auto result = std::map<uint64, Message>();
for (const auto &message : data.v) {
auto parsed = ParseMessage(context, message, mediaFolder);
@ -1460,7 +1472,10 @@ DialogsInfo ParseDialogsInfo(const MTPmessages_Dialogs &data) {
Unexpected("dialogsNotModified in ParseDialogsInfo.");
}, [&](const auto &data) { // MTPDmessages_dialogs &data) {
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());
for (const auto &dialog : data.vdialogs().v) {
if (dialog.type() != mtpc_dialog) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -54,7 +54,7 @@ namespace {
[[nodiscard]] MTPDmessage::Flags NewForwardedFlags(
not_null<PeerData*> peer,
UserId from,
PeerId from,
not_null<HistoryMessage*> fwd) {
auto result = NewMessageFlags(peer) | MTPDmessage::Flag::f_fwd_from;
if (from) {
@ -210,7 +210,6 @@ void FastShareMessage(not_null<HistoryItem*> item) {
const auto data = std::make_shared<ShareData>(
history->peer,
owner->itemOrItsGroup(item));
const auto isGroup = (owner->groups().find(item) != nullptr);
const auto isGame = item->getMessageBot()
&& item->media()
&& (item->media()->game() != nullptr);
@ -276,9 +275,6 @@ void FastShareMessage(not_null<HistoryItem*> item) {
const auto sendFlags = MTPmessages_ForwardMessages::Flag(0)
| MTPmessages_ForwardMessages::Flag::f_with_my_score
| (isGroup
? MTPmessages_ForwardMessages::Flag::f_grouped
: MTPmessages_ForwardMessages::Flag(0))
| (options.silent
? MTPmessages_ForwardMessages::Flag::f_silent
: MTPmessages_ForwardMessages::Flag(0))
@ -375,6 +371,28 @@ MTPDmessage::Flags NewMessageFlags(not_null<PeerData*> peer) {
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() {
return MTPDmessage_ClientFlag::f_sending;
}
@ -388,8 +406,10 @@ QString GetErrorTextForSending(
struct HistoryMessage::CreateConfig {
MsgId replyTo = 0;
MsgId replyToTop = 0;
UserId viaBotId = 0;
int viewsCount = -1;
int repliesCount = 0;
QString author;
PeerId senderOriginal = 0;
QString senderNameOriginal;
@ -411,10 +431,8 @@ struct HistoryMessage::CreateConfig {
void HistoryMessage::FillForwardedInfo(
CreateConfig &config,
const MTPDmessageFwdHeader &data) {
if (const auto channelId = data.vchannel_id()) {
config.senderOriginal = peerFromChannel(*channelId);
} else if (const auto fromId = data.vfrom_id()) {
config.senderOriginal = peerFromUser(*fromId);
if (const auto fromId = data.vfrom_id()) {
config.senderOriginal = peerFromMTP(*fromId);
}
config.originalDate = data.vdate().v;
config.senderNameOriginal = qs(data.vfrom_name().value_or_empty());
@ -439,16 +457,28 @@ HistoryMessage::HistoryMessage(
data.vflags().v,
clientFlags,
data.vdate().v,
data.vfrom_id().value_or_empty()) {
data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) {
auto config = CreateConfig();
if (const auto forwarded = data.vfwd_from()) {
forwarded->match([&](const MTPDmessageFwdHeader &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.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.editDate = data.vedit_date().value_or_empty();
config.author = qs(data.vpost_author().value_or_empty());
@ -483,10 +513,16 @@ HistoryMessage::HistoryMessage(
mtpCastFlags(data.vflags().v),
clientFlags,
data.vdate().v,
data.vfrom_id().value_or_empty()) {
data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId(0)) {
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);
@ -504,7 +540,7 @@ HistoryMessage::HistoryMessage(
MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
not_null<HistoryMessage*> original)
: HistoryItem(
@ -590,7 +626,7 @@ HistoryMessage::HistoryMessage(
MsgId replyTo,
UserId viaBotId,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
const TextWithEntities &textWithEntities)
: HistoryItem(
@ -618,7 +654,7 @@ HistoryMessage::HistoryMessage(
MsgId replyTo,
UserId viaBotId,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
not_null<DocumentData*> document,
const TextWithEntities &caption,
@ -644,7 +680,7 @@ HistoryMessage::HistoryMessage(
MsgId replyTo,
UserId viaBotId,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
not_null<PhotoData*> photo,
const TextWithEntities &caption,
@ -670,7 +706,7 @@ HistoryMessage::HistoryMessage(
MsgId replyTo,
UserId viaBotId,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
not_null<GameData*> game,
const MTPReplyMarkup &markup)
@ -696,7 +732,9 @@ void HistoryMessage::createComponentsHelper(
auto config = CreateConfig();
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_post_author) config.author = postAuthor;
if (flags & MTPDmessage::Flag::f_views) config.viewsCount = 1;
@ -706,11 +744,18 @@ void HistoryMessage::createComponentsHelper(
int HistoryMessage::viewsCount() const {
if (const auto views = Get<HistoryMessageViews>()) {
return views->_views;
return views->views;
}
return HistoryItem::viewsCount();
}
int HistoryMessage::repliesCount() const {
if (const auto views = Get<HistoryMessageViews>()) {
return views->replies;
}
return HistoryItem::repliesCount();
}
bool HistoryMessage::updateDependencyItem() {
if (const auto reply = Get<HistoryMessageReply>()) {
const auto documentId = reply->replyToDocumentId;
@ -803,7 +848,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
if (config.viaBotId) {
mask |= HistoryMessageVia::Bit();
}
if (config.viewsCount >= 0) {
if (config.viewsCount >= 0 || config.repliesCount > 0) {
mask |= HistoryMessageViews::Bit();
}
if (!config.author.isEmpty()) {
@ -829,6 +874,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
if (const auto reply = Get<HistoryMessageReply>()) {
reply->replyToMsgId = config.replyTo;
reply->replyToMsgTop = isScheduled() ? 0 : config.replyToTop;
if (!reply->updateData(this)) {
history()->session().api().requestMessageData(
history()->peer->asChannel(),
@ -840,7 +886,8 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
via->create(&history()->owner(), config.viaBotId);
}
if (const auto views = Get<HistoryMessageViews>()) {
views->_views = config.viewsCount;
views->views = config.viewsCount;
views->replies = config.repliesCount;
}
if (const auto edited = Get<HistoryMessageEdited>()) {
edited->date = config.editDate;
@ -1088,6 +1135,7 @@ void HistoryMessage::applyEdition(const MTPDmessage &message) {
refreshMedia(message.vmedia());
}
setViewsCount(message.vviews().value_or(-1));
setForwardsCount(message.vforwards().value_or(-1));
setText(_media ? textWithEntities : EnsureNonEmpty(textWithEntities));
finishEdition(keyboardTop);
@ -1099,6 +1147,7 @@ void HistoryMessage::applyEdition(const MTPDmessageService &message) {
refreshMedia(nullptr);
setEmptyText();
setViewsCount(-1);
setForwardsCount(-1);
finishEditionToEmpty();
}
@ -1159,10 +1208,13 @@ void HistoryMessage::addToUnreadMentions(UnreadMentionType type) {
}
}
void HistoryMessage::eraseFromUnreadMentions() {
void HistoryMessage::destroyHistoryEntry() {
if (isUnreadMention()) {
history()->eraseFromUnreadMentions(id);
}
if (const auto reply = Get<HistoryMessageReply>()) {
decrementReplyToTopCounter(reply);
}
}
Storage::SharedMediaTypesMask HistoryMessage::sharedMediaTypes() const {
@ -1345,29 +1397,79 @@ bool HistoryMessage::textHasLinks() const {
return emptyText() ? false : _text.hasLinks();
}
void HistoryMessage::setViewsCount(int32 count) {
void HistoryMessage::setViewsCount(int count) {
const auto views = Get<HistoryMessageViews>();
if (!views
|| views->_views == count
|| (count >= 0 && views->_views > count)) {
|| views->views == count
|| (count >= 0 && views->views > count)) {
return;
}
const auto was = views->_viewsWidth;
views->_views = count;
views->_viewsText = (views->_views > 0)
? Lang::FormatCountToShort(views->_views).string
views->views = count;
views->text = (views->views > 0)
? Lang::FormatCountToShort(views->views).string
: QString("1");
views->_viewsWidth = views->_viewsText.isEmpty()
const auto was = views->textWidth;
views->textWidth = views->text.isEmpty()
? 0
: st::msgDateFont->width(views->_viewsText);
if (was == views->_viewsWidth) {
: st::msgDateFont->width(views->text);
if (was == views->textWidth) {
history()->owner().requestItemRepaint(this);
} else {
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) {
HistoryItem::setRealId(newId);
@ -1377,6 +1479,43 @@ void HistoryMessage::setRealId(MsgId newId) {
if (reply->replyToLink()) {
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"
namespace Api {
struct SendAction;
} // namespace Api
namespace HistoryView {
class Message;
} // namespace HistoryView
struct HistoryMessageEdited;
struct HistoryMessageReply;
Fn<void(ChannelData*, MsgId)> HistoryDependentItemCallback(
not_null<HistoryItem*> item);
MTPDmessage::Flags NewMessageFlags(not_null<PeerData*> peer);
MTPDmessage_ClientFlags NewMessageClientFlags();
MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action);
QString GetErrorTextForSending(
not_null<PeerData*> peer,
const HistoryItemsList &items,
@ -46,7 +52,7 @@ public:
MTPDmessage::Flags flags,
MTPDmessage_ClientFlags clientFlags,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
not_null<HistoryMessage*> original); // local forwarded
HistoryMessage(
@ -57,7 +63,7 @@ public:
MsgId replyTo,
UserId viaBotId,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
const TextWithEntities &textWithEntities); // local message
HistoryMessage(
@ -68,7 +74,7 @@ public:
MsgId replyTo,
UserId viaBotId,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
not_null<DocumentData*> document,
const TextWithEntities &caption,
@ -81,7 +87,7 @@ public:
MsgId replyTo,
UserId viaBotId,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
not_null<PhotoData*> photo,
const TextWithEntities &caption,
@ -94,7 +100,7 @@ public:
MsgId replyTo,
UserId viaBotId,
TimeId date,
UserId from,
PeerId from,
const QString &postAuthor,
not_null<GameData*> game,
const MTPReplyMarkup &markup); // local game
@ -125,8 +131,12 @@ public:
void applyGroupAdminChanges(
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 incrementReplyToTopCounter() override;
void dependencyItemRemoved(HistoryItem *dependency) override;
@ -144,7 +154,7 @@ public:
void contributeToSlowmode(TimeId realDate = 0) override;
void addToUnreadMentions(UnreadMentionType type) override;
void eraseFromUnreadMentions() override;
void destroyHistoryEntry() override;
[[nodiscard]] Storage::SharedMediaTypesMask sharedMediaTypes() const override;
void setText(const TextWithEntities &textWithEntities) override;
@ -154,6 +164,7 @@ public:
[[nodiscard]] bool textHasLinks() const override;
[[nodiscard]] int viewsCount() const override;
[[nodiscard]] int repliesCount() const override;
bool updateDependencyItem() override;
[[nodiscard]] MsgId dependencyMsgId() const override {
return replyToId();
@ -193,6 +204,8 @@ private:
void createComponentsHelper(MTPDmessage::Flags flags, MsgId replyTo, UserId viaBotId, const QString &postAuthor, const MTPReplyMarkup &markup);
void createComponents(const CreateConfig &config);
void setupForwardedComponent(const CreateConfig &config);
void incrementReplyToTopCounter(not_null<HistoryMessageReply*> reply);
void decrementReplyToTopCounter(not_null<HistoryMessageReply*> reply);
static void FillForwardedInfo(
CreateConfig &config,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1276,7 +1276,7 @@ void MainWidget::viewsIncrement() {
i->first->input,
MTP_vector<MTPint>(ids),
MTP_bool(true)
)).done([=](const MTPVector<MTPint> &result, mtpRequestId requestId) {
)).done([=](const MTPmessages_MessageViews &result, mtpRequestId requestId) {
viewsIncrementDone(ids, result, requestId);
}).fail([=](const RPCError &error, mtpRequestId requestId) {
viewsIncrementFail(error, requestId);
@ -1287,8 +1287,14 @@ void MainWidget::viewsIncrement() {
}
}
void MainWidget::viewsIncrementDone(QVector<MTPint> ids, const MTPVector<MTPint> &result, mtpRequestId requestId) {
auto &v = result.v;
void MainWidget::viewsIncrementDone(
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()) {
for (auto i = _viewsIncrementRequests.begin(); i != _viewsIncrementRequests.cend(); ++i) {
if (i->second == requestId) {
@ -1296,7 +1302,23 @@ void MainWidget::viewsIncrementDone(QVector<MTPint> ids, const MTPVector<MTPint>
const auto channel = peerToChannel(peer->id);
for (int32 j = 0, l = ids.size(); j < l; ++j) {
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);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -54,6 +54,25 @@ ImageWithLocation FromPhotoSize(
.bytes = bytes,
.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) {
return ImageWithLocation();
//const auto bytes = ExpandInlineBytes(qba(data.vbytes()));
@ -113,6 +132,25 @@ ImageWithLocation FromPhotoSize(
.bytes = bytes,
.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) {
return ImageWithLocation();
//const auto bytes = ExpandInlineBytes(qba(data.vbytes()));
@ -175,6 +213,25 @@ ImageWithLocation FromPhotoSize(
.bytes = bytes,
.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) {
return ImageWithLocation();
//const auto bytes = ExpandInlineBytes(qba(data.vbytes()));

View file

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