diff --git a/Telegram/Resources/tl/api.tl b/Telegram/Resources/tl/api.tl index 4d682710b..d5b1f3652 100644 --- a/Telegram/Resources/tl/api.tl +++ b/Telegram/Resources/tl/api.tl @@ -412,6 +412,7 @@ updateAutoSaveSettings#ec05b097 = Update; updateGroupInvitePrivacyForbidden#ccf08ad6 user_id:long = Update; updateStories#66fad7b5 stories:UserStories = Update; updateReadStories#feb5345a user_id:long max_id:int = Update; +updateStoryID#1bf335b9 id:int random_id:long = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -1280,6 +1281,7 @@ messages.messageViews#b6c4f543 views:Vector chats:Vector use messages.discussionMessage#a6341782 flags:# messages:Vector max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector users:Vector = messages.DiscussionMessage; messageReplyHeader#a6d57763 flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true reply_to_msg_id:int reply_to_peer_id:flags.0?Peer reply_to_top_id:flags.1?int = MessageReplyHeader; +messageReplyStoryHeader#9c98bfc1 user_id:long story_id:int = MessageReplyHeader; messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies; @@ -1551,25 +1553,30 @@ messagePeerVoteMultiple#4628f6e6 peer:Peer options:Vector date:int = Mess sponsoredWebPage#3db8ec63 flags:# url:string site_name:string photo:flags.0?Photo = SponsoredWebPage; -storyViews#518b47d8 recent_viewers:Vector views_count:int = StoryViews; +storyViews#d36760cf flags:# views_count:int recent_viewers:flags.0?Vector = StoryViews; storyItemDeleted#51e6ee4f id:int = StoryItem; storyItemSkipped#a1d8cf8f id:int date:int = StoryItem; -storyItem#8fcd96ac flags:# pinned:flags.5?true expired:flags.6?true id:int date:int caption:flags.0?string entities:flags.1?Vector media:MessageMedia privacy:flags.2?Vector views:flags.3?StoryViews = StoryItem; +storyItem#8fcd96ac flags:# pinned:flags.5?true expired:flags.6?true public:flags.7?true id:int date:int caption:flags.0?string entities:flags.1?Vector media:MessageMedia privacy:flags.2?Vector views:flags.3?StoryViews = StoryItem; userStories#8611a200 flags:# user_id:long max_read_id:flags.0?int stories:Vector = UserStories; stories.allStoriesNotModified#47e0a07e state:string = stories.AllStories; -stories.allStories#5b1aa68c flags:# has_more:flags.0?true state:string user_stories:Vector users:Vector = stories.AllStories; +stories.allStories#839e0428 flags:# has_more:flags.0?true count:int state:string user_stories:Vector users:Vector = stories.AllStories; stories.stories#4fe57df1 count:int stories:Vector users:Vector = stories.Stories; +stories.userStories#37a6ff5f stories:UserStories users:Vector = stories.UserStories; + storyView#a71aacc2 user_id:long date:int = StoryView; stories.storyViewsList#fb3f77ac count:int views:Vector users:Vector = stories.StoryViewsList; stories.storyViews#de9eed1d views:Vector users:Vector = stories.StoryViews; +inputReplyToMessage#9c5386e4 flags:# reply_to_msg_id:int top_msg_id:flags.0?int = InputReplyTo; +inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -1730,8 +1737,8 @@ messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?t messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector = messages.AffectedMessages; messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool; -messages.sendMessage#1cc20387 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; -messages.sendMedia#7547c966 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendMessage#280d096f flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendMedia#72ccc23d flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; messages.forwardMessages#c661bbc4 flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer top_msg_id:flags.9?int schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings; @@ -1775,7 +1782,7 @@ messages.getSavedGifs#5cf09635 hash:long = messages.SavedGifs; messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool; messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults; messages.setInlineBotResults#bb12a419 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM switch_webview:flags.4?InlineBotWebView = Bool; -messages.sendInlineBotResult#d3fbdccb flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int random_id:long query_id:long id:string schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendInlineBotResult#f7bc68ba flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to:flags.0?InputReplyTo random_id:long query_id:long id:string schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData; messages.editMessage#48f71778 flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.15?int = Updates; messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector = Bool; @@ -1804,13 +1811,13 @@ messages.getPinnedDialogs#d6b94df2 folder_id:int = messages.PeerDialogs; messages.setBotShippingResults#e5f672fa flags:# query_id:long error:flags.0?string shipping_options:flags.1?Vector = Bool; messages.setBotPrecheckoutResults#9c2dd95 flags:# success:flags.1?true query_id:long error:flags.0?string = Bool; messages.uploadMedia#519bc2b1 peer:InputPeer media:InputMedia = MessageMedia; -messages.sendScreenshotNotification#c97df020 peer:InputPeer reply_to_msg_id:int random_id:long = Updates; +messages.sendScreenshotNotification#a1405817 peer:InputPeer reply_to:InputReplyTo random_id:long = Updates; messages.getFavedStickers#4f1aaa9 hash:long = messages.FavedStickers; messages.faveSticker#b9ffc55b id:InputDocument unfave:Bool = Bool; messages.getUnreadMentions#f107e790 flags:# peer:InputPeer top_msg_id:flags.0?int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages; messages.readMentions#36e5bf4d flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory; messages.getRecentLocations#702a40e0 peer:InputPeer limit:int hash:long = messages.Messages; -messages.sendMultiMedia#b6f11a1c flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to_msg_id:flags.0?int top_msg_id:flags.9?int multi_media:Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; +messages.sendMultiMedia#456e8987 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true peer:InputPeer reply_to:flags.0?InputReplyTo multi_media:Vector schedule_date:flags.10?int send_as:flags.13?InputPeer = Updates; messages.uploadEncryptedFile#5057c497 peer:InputEncryptedChat file:InputEncryptedFile = EncryptedFile; messages.searchStickerSets#35705b8a flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets; messages.getSplitRanges#1cff7e08 = Vector; @@ -1882,8 +1889,8 @@ messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = mes messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots; messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot; messages.toggleBotInAttachMenu#69f59d69 flags:# write_allowed:flags.0?true bot:InputUser enabled:Bool = Bool; -messages.requestWebView#178b480b flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = WebViewResult; -messages.prolongWebView#7ff34309 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = Bool; +messages.requestWebView#269dc2c1 flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = WebViewResult; +messages.prolongWebView#b0d81a83 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = Bool; messages.requestSimpleWebView#299bec8e flags:# from_switch_webview:flags.1?true bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult; messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent; messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates; @@ -2104,15 +2111,17 @@ chatlists.hideChatlistUpdates#66e486fb chatlist:InputChatlist = Bool; chatlists.getLeaveChatlistSuggestions#fdbcd714 chatlist:InputChatlist = Vector; chatlists.leaveChatlist#74fae13a chatlist:InputChatlist peers:Vector = Updates; -stories.sendStory#8e826f5d flags:# pinned:flags.2?true media:InputMedia caption:flags.0?string entities:flags.1?Vector privacy_rules:Vector = Updates; +stories.sendStory#8b5c6986 flags:# pinned:flags.2?true media:InputMedia caption:flags.0?string entities:flags.1?Vector privacy_rules:Vector random_id:long = Updates; +stories.editStory#2aae7a41 flags:# id:int media:flags.0?InputMedia caption:flags.1?string entities:flags.1?Vector privacy_rules:flags.2?Vector = Updates; stories.deleteStories#b5d501d7 id:Vector = Vector; -stories.editStoryPrivacy#78981875 id:int privacy_rules:Vector = Updates; stories.togglePinned#51602944 id:Vector pinned:Bool = Vector; stories.getAllStories#eeb0d625 flags:# next:flags.1?true state:flags.0?string = stories.AllStories; -stories.getUserStories#c946f3c0 flags:# pinned:flags.0?true user_id:InputUser offset_id:int limit:int = stories.Stories; -stories.getStoriesByID#6a15cf46 user_id:InputUser id:Vector = stories.Stories; +stories.getUserStories#96d528e0 user_id:InputUser = stories.UserStories; +stories.getPinnedStories#b471137 user_id:InputUser offset_id:int limit:int = stories.Stories; stories.getExpiredStories#8f792f2 offset_id:int limit:int = stories.Stories; +stories.getStoriesByID#6a15cf46 user_id:InputUser id:Vector = stories.Stories; stories.readStories#edc5105b user_id:InputUser max_id:int = Vector; +stories.incrementStoryViews#22126127 user_id:InputUser id:Vector = Bool; stories.getStoryViewsList#4b3b5e97 id:int offset_date:int offset_id:long limit:int = stories.StoryViewsList; stories.getStoriesViews#9a75d6a6 id:Vector = stories.StoryViews; diff --git a/Telegram/SourceFiles/api/api_bot.cpp b/Telegram/SourceFiles/api/api_bot.cpp index 165402d7e..65826aa2f 100644 --- a/Telegram/SourceFiles/api/api_bot.cpp +++ b/Telegram/SourceFiles/api/api_bot.cpp @@ -375,8 +375,10 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) { ShowAtTheEndMsgId); auto action = Api::SendAction(history); action.clearDraft = false; - action.replyTo = itemId; - action.topicRootId = topicRootId; + action.replyTo = { + .msgId = itemId, + .topicRootId = topicRootId, + }; history->session().api().shareContact( history->session().user(), action); diff --git a/Telegram/SourceFiles/api/api_common.cpp b/Telegram/SourceFiles/api/api_common.cpp index f4afa97f6..0a44a916f 100644 --- a/Telegram/SourceFiles/api/api_common.cpp +++ b/Telegram/SourceFiles/api/api_common.cpp @@ -8,7 +8,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_common.h" #include "base/qt/qt_key_modifiers.h" +#include "data/data_histories.h" #include "data/data_thread.h" +#include "history/history.h" namespace Api { @@ -17,8 +19,8 @@ SendAction::SendAction( SendOptions options) : history(thread->owningHistory()) , options(options) -, replyTo(thread->topicRootId()) -, topicRootId(replyTo) { +, replyTo({ .msgId = thread->topicRootId() }) { + replyTo.topicRootId = replyTo.msgId; } SendOptions DefaultSendWhenOnlineOptions() { @@ -28,4 +30,8 @@ SendOptions DefaultSendWhenOnlineOptions() { }; } +MTPInputReplyTo SendAction::mtpReplyTo() const { + return Data::ReplyToForMTP(&history->owner(), replyTo); +} + } // namespace Api diff --git a/Telegram/SourceFiles/api/api_common.h b/Telegram/SourceFiles/api/api_common.h index 1bdb97ee5..08ee59ca1 100644 --- a/Telegram/SourceFiles/api/api_common.h +++ b/Telegram/SourceFiles/api/api_common.h @@ -40,11 +40,12 @@ struct SendAction { not_null history; SendOptions options; - MsgId replyTo = 0; - MsgId topicRootId = 0; + FullReplyTo replyTo; bool clearDraft = true; bool generateLocal = true; MsgId replaceMediaOf = 0; + + [[nodiscard]] MTPInputReplyTo mtpReplyTo() const; }; struct MessageToSend { diff --git a/Telegram/SourceFiles/api/api_peer_photo.cpp b/Telegram/SourceFiles/api/api_peer_photo.cpp index a449b2200..71512172b 100644 --- a/Telegram/SourceFiles/api/api_peer_photo.cpp +++ b/Telegram/SourceFiles/api/api_peer_photo.cpp @@ -97,8 +97,7 @@ constexpr auto kSharedMediaLimit = 100; photo, photoThumbs, MTP_documentEmpty(MTP_long(0)), - jpeg, - 0); + jpeg); } [[nodiscard]] std::optional PrepareMtpMarkup( diff --git a/Telegram/SourceFiles/api/api_polls.cpp b/Telegram/SourceFiles/api/api_polls.cpp index d18c947c1..227b6e9db 100644 --- a/Telegram/SourceFiles/api/api_polls.cpp +++ b/Telegram/SourceFiles/api/api_polls.cpp @@ -43,13 +43,12 @@ void Polls::create( const auto history = action.history; const auto peer = history->peer; - const auto topicRootId = action.replyTo ? action.topicRootId : 0; + const auto topicRootId = action.replyTo.msgId + ? action.replyTo.topicRootId + : 0; auto sendFlags = MTPmessages_SendMedia::Flags(0); if (action.replyTo) { - sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; - if (topicRootId) { - sendFlags |= MTPmessages_SendMedia::Flag::f_top_msg_id; - } + sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to; } const auto clearCloudDraft = action.clearDraft; if (clearCloudDraft) { @@ -74,13 +73,11 @@ void Polls::create( histories.sendPreparedMessage( history, action.replyTo, - topicRootId, randomId, Data::Histories::PrepareMessage( MTP_flags(sendFlags), peer->input, Data::Histories::ReplyToPlaceholder(), - Data::Histories::TopicRootPlaceholder(), PollDataToInputMedia(&data), MTP_string(), MTP_long(randomId), diff --git a/Telegram/SourceFiles/api/api_ringtones.cpp b/Telegram/SourceFiles/api/api_ringtones.cpp index 40b07e3f3..d9ad40176 100644 --- a/Telegram/SourceFiles/api/api_ringtones.cpp +++ b/Telegram/SourceFiles/api/api_ringtones.cpp @@ -60,8 +60,7 @@ SendMediaReady PrepareRingtoneDocument( MTP_photoEmpty(MTP_long(0)), PreparedPhotoThumbs(), document, - QByteArray(), - 0); + QByteArray()); } } // namespace diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index e8d18c03c..9cfe272f8 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -86,10 +86,7 @@ void SendExistingMedia( auto sendFlags = MTPmessages_SendMedia::Flags(0); if (message.action.replyTo) { flags |= MessageFlag::HasReplyInfo; - sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; - if (message.action.topicRootId) { - sendFlags |= MTPmessages_SendMedia::Flag::f_top_msg_id; - } + sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to; } const auto anonymousPost = peer->amAnonymous(); const auto silentPost = ShouldSendSilent(peer, message.action.options); @@ -150,13 +147,11 @@ void SendExistingMedia( histories.sendPreparedMessage( history, message.action.replyTo, - message.action.topicRootId, randomId, Data::Histories::PrepareMessage( MTP_flags(sendFlags), peer->input, Data::Histories::ReplyToPlaceholder(), - Data::Histories::TopicRootPlaceholder(), inputMedia(), MTP_string(captionText), MTP_long(randomId), @@ -273,10 +268,7 @@ bool SendDice(MessageToSend &message) { auto sendFlags = MTPmessages_SendMedia::Flags(0); if (message.action.replyTo) { flags |= MessageFlag::HasReplyInfo; - sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; - if (message.action.topicRootId) { - sendFlags |= MTPmessages_SendMedia::Flag::f_top_msg_id; - } + sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to; } const auto replyHeader = NewMessageReplyHeader(message.action); const auto anonymousPost = peer->amAnonymous(); @@ -320,13 +312,11 @@ bool SendDice(MessageToSend &message) { histories.sendPreparedMessage( history, message.action.replyTo, - message.action.topicRootId, randomId, Data::Histories::PrepareMessage( MTP_flags(sendFlags), peer->input, Data::Histories::ReplyToPlaceholder(), - Data::Histories::TopicRootPlaceholder(), MTP_inputMediaDice(MTP_string(emoji)), MTP_string(), MTP_long(randomId), @@ -378,12 +368,12 @@ void SendConfirmedFile( if (!isEditing) { const auto histories = &session->data().histories(); - file->to.replyTo = histories->convertTopicReplyTo( + file->to.replyTo.msgId = histories->convertTopicReplyToId( history, - file->to.replyTo); - file->to.topicRootId = histories->convertTopicReplyTo( + file->to.replyTo.msgId); + file->to.replyTo.topicRootId = histories->convertTopicReplyToId( history, - file->to.topicRootId); + file->to.replyTo.topicRootId); } session->uploader().upload(newId, file); @@ -391,7 +381,6 @@ void SendConfirmedFile( auto action = SendAction(history, file->to.options); action.clearDraft = false; action.replyTo = file->to.replyTo; - action.topicRootId = file->to.topicRootId; action.generateLocal = true; action.replaceMediaOf = file->to.replaceMediaOf; session->api().sendAction(action); diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index c60f96862..304c609d4 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -3091,8 +3091,9 @@ void ApiWrap::sharedMediaDone( void ApiWrap::sendAction(const SendAction &action) { if (!action.options.scheduled && !action.replaceMediaOf) { - const auto topic = action.topicRootId - ? action.history->peer->forumTopicFor(action.topicRootId) + const auto topicRootId = action.replyTo.topicRootId; + const auto topic = topicRootId + ? action.history->peer->forumTopicFor(topicRootId) : nullptr; if (topic) { topic->readTillEnd(); @@ -3106,12 +3107,13 @@ void ApiWrap::sendAction(const SendAction &action) { void ApiWrap::finishForwarding(const SendAction &action) { const auto history = action.history; - auto toForward = history->resolveForwardDraft(action.topicRootId); + const auto topicRootId = action.replyTo.topicRootId; + auto toForward = history->resolveForwardDraft(topicRootId); if (!toForward.items.empty()) { const auto error = GetErrorTextForSending( history->peer, { - .topicRootId = action.topicRootId, + .topicRootId = topicRootId, .forward = &toForward.items, }); if (!error.isEmpty()) { @@ -3119,7 +3121,7 @@ void ApiWrap::finishForwarding(const SendAction &action) { } forwardMessages(std::move(toForward), action); - history->setForwardDraft(action.topicRootId, {}); + history->setForwardDraft(topicRootId, {}); } _session->data().sendHistoryChangeNotifications(); @@ -3163,31 +3165,33 @@ void ApiWrap::forwardMessages( const auto silentPost = ShouldSendSilent(peer, action.options); const auto sendAs = action.options.sendAs; + using SendFlag = MTPmessages_ForwardMessages::Flag; auto flags = MessageFlags(); - auto sendFlags = MTPmessages_ForwardMessages::Flags(0); + auto sendFlags = SendFlag() | SendFlag(); FillMessagePostFlags(action, peer, flags); if (silentPost) { - sendFlags |= MTPmessages_ForwardMessages::Flag::f_silent; + sendFlags |= SendFlag::f_silent; } if (action.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; - sendFlags |= MTPmessages_ForwardMessages::Flag::f_schedule_date; + sendFlags |= SendFlag::f_schedule_date; } if (draft.options != Data::ForwardOptions::PreserveInfo) { - sendFlags |= MTPmessages_ForwardMessages::Flag::f_drop_author; + sendFlags |= SendFlag::f_drop_author; } if (draft.options == Data::ForwardOptions::NoNamesAndCaptions) { - sendFlags |= MTPmessages_ForwardMessages::Flag::f_drop_media_captions; + sendFlags |= SendFlag::f_drop_media_captions; } if (sendAs) { - sendFlags |= MTPmessages_ForwardMessages::Flag::f_send_as; + sendFlags |= SendFlag::f_send_as; } const auto kGeneralId = Data::ForumTopic::kGeneralId; - const auto topMsgId = (action.topicRootId == kGeneralId) + const auto topicRootId = action.replyTo.topicRootId; + const auto topMsgId = (topicRootId == kGeneralId) ? MsgId(0) - : action.topicRootId; + : topicRootId; if (topMsgId) { - sendFlags |= MTPmessages_ForwardMessages::Flag::f_top_msg_id; + sendFlags |= SendFlag::f_top_msg_id; } auto forwardFrom = draft.items.front()->history()->peer; @@ -3529,14 +3533,14 @@ void ApiWrap::sendMessage(MessageToSend &&message) { action.generateLocal = true; sendAction(action); - const auto replyToId = action.replyTo; + const auto replyToId = action.replyTo.msgId; const auto replyTo = replyToId ? peer->owner().message(peer, replyToId) : nullptr; const auto topicRootId = replyTo ? replyTo->topicRootId() - : action.topicRootId - ? action.topicRootId + : action.replyTo.topicRootId + ? action.replyTo.topicRootId : Data::ForumTopic::kGeneralId; const auto topic = peer->forumTopicFor(topicRootId); if (!(topic ? Data::CanSendTexts(topic) : Data::CanSendTexts(peer)) @@ -3575,10 +3579,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) { auto sendFlags = MTPmessages_SendMessage::Flags(0); if (action.replyTo) { flags |= MessageFlag::HasReplyInfo; - sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to_msg_id; - if (action.topicRootId) { - sendFlags |= MTPmessages_SendMessage::Flag::f_top_msg_id; - } + sendFlags |= MTPmessages_SendMessage::Flag::f_reply_to; } const auto replyHeader = NewMessageReplyHeader(action); MTPMessageMedia media = MTP_messageMediaEmpty(); @@ -3605,7 +3606,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) { sendFlags |= MTPmessages_SendMessage::Flag::f_entities; } const auto clearCloudDraft = action.clearDraft; - const auto topicRootId = action.topicRootId; + const auto topicRootId = action.replyTo.topicRootId; if (clearCloudDraft) { sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft; history->clearCloudDraft(topicRootId); @@ -3642,13 +3643,11 @@ void ApiWrap::sendMessage(MessageToSend &&message) { histories.sendPreparedMessage( history, action.replyTo, - topicRootId, randomId, Data::Histories::PrepareMessage( MTP_flags(sendFlags), peer->input, Data::Histories::ReplyToPlaceholder(), - Data::Histories::TopicRootPlaceholder(), msgText, MTP_long(randomId), MTPReplyMarkup(), @@ -3737,29 +3736,29 @@ void ApiWrap::sendInlineResult( ? (*localMessageId) : _session->data().nextLocalMessageId()); const auto randomId = base::RandomValue(); - const auto topicRootId = action.replyTo ? action.topicRootId : 0; + const auto topicRootId = action.replyTo.msgId + ? action.replyTo.topicRootId + : 0; + using SendFlag = MTPmessages_SendInlineBotResult::Flag; auto flags = NewMessageFlags(peer); - auto sendFlags = MTPmessages_SendInlineBotResult::Flag::f_clear_draft | 0; + auto sendFlags = SendFlag::f_clear_draft | SendFlag(); if (action.replyTo) { flags |= MessageFlag::HasReplyInfo; - sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_reply_to_msg_id; - if (topicRootId) { - sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_top_msg_id; - } + sendFlags |= SendFlag::f_reply_to; } const auto anonymousPost = peer->amAnonymous(); const auto silentPost = ShouldSendSilent(peer, action.options); FillMessagePostFlags(action, peer, flags); if (silentPost) { - sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_silent; + sendFlags |= SendFlag::f_silent; } if (action.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; - sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_schedule_date; + sendFlags |= SendFlag::f_schedule_date; } if (action.options.hideViaBot) { - sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_hide_via; + sendFlags |= SendFlag::f_hide_via; } const auto sendAs = action.options.sendAs; @@ -3793,13 +3792,11 @@ void ApiWrap::sendInlineResult( histories.sendPreparedMessage( history, action.replyTo, - topicRootId, randomId, Data::Histories::PrepareMessage( MTP_flags(sendFlags), peer->input, Data::Histories::ReplyToPlaceholder(), - Data::Histories::TopicRootPlaceholder(), MTP_long(randomId), MTP_long(data->getQueryId()), MTP_string(data->getId()), @@ -3912,8 +3909,7 @@ void ApiWrap::sendMediaWithRandomId( Api::SendOptions options, uint64 randomId) { const auto history = item->history(); - const auto replyTo = item->replyToId(); - const auto topicRootId = item->topicRootId(); + const auto replyTo = item->replyTo(); auto caption = item->originalText(); TextUtilities::Trim(caption); @@ -3926,8 +3922,7 @@ void ApiWrap::sendMediaWithRandomId( using Flag = MTPmessages_SendMedia::Flag; const auto flags = Flag(0) - | (replyTo ? Flag::f_reply_to_msg_id : Flag(0)) - | (topicRootId ? Flag::f_top_msg_id : Flag(0)) + | (replyTo ? Flag::f_reply_to : Flag(0)) | (ShouldSendSilent(history->peer, options) ? Flag::f_silent : Flag(0)) @@ -3941,13 +3936,11 @@ void ApiWrap::sendMediaWithRandomId( histories.sendPreparedMessage( history, replyTo, - topicRootId, randomId, Data::Histories::PrepareMessage( MTP_flags(flags), peer->input, Data::Histories::ReplyToPlaceholder(), - Data::Histories::TopicRootPlaceholder(), media, MTP_string(caption.text), MTP_long(randomId), @@ -4028,13 +4021,11 @@ void ApiWrap::sendAlbumIfReady(not_null album) { return; } const auto history = sample->history(); - const auto replyTo = sample->replyToId(); - const auto topicRootId = sample->topicRootId(); + const auto replyTo = sample->replyTo(); const auto sendAs = album->options.sendAs; using Flag = MTPmessages_SendMultiMedia::Flag; const auto flags = Flag(0) - | (replyTo ? Flag::f_reply_to_msg_id : Flag(0)) - | (topicRootId ? Flag::f_top_msg_id : Flag(0)) + | (replyTo ? Flag::f_reply_to : Flag(0)) | (ShouldSendSilent(history->peer, album->options) ? Flag::f_silent : Flag(0)) @@ -4045,13 +4036,11 @@ void ApiWrap::sendAlbumIfReady(not_null album) { histories.sendPreparedMessage( history, replyTo, - topicRootId, uint64(0), // randomId Data::Histories::PrepareMessage( MTP_flags(flags), peer->input, Data::Histories::ReplyToPlaceholder(), - Data::Histories::TopicRootPlaceholder(), MTP_vector(medias), MTP_int(album->options.scheduled), (sendAs ? sendAs->input : MTP_inputPeerEmpty()) @@ -4074,7 +4063,6 @@ FileLoadTo ApiWrap::fileLoadTaskOptions(const SendAction &action) const { peer->id, action.options, action.replyTo, - action.topicRootId, action.replaceMediaOf); } diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp index 738a88165..c83af953d 100644 --- a/Telegram/SourceFiles/boxes/background_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp @@ -95,7 +95,7 @@ constexpr auto kDefaultDimming = 50; const auto flags = MessageFlag::FakeHistoryItem | MessageFlag::HasFromId | (out ? MessageFlag::Outgoing : MessageFlag(0)); - const auto replyTo = MsgId(); + const auto replyTo = FullReplyTo(); const auto viaBotId = UserId(); const auto groupedId = uint64(); const auto item = history->makeMessage( diff --git a/Telegram/SourceFiles/boxes/reactions_settings_box.cpp b/Telegram/SourceFiles/boxes/reactions_settings_box.cpp index 8c3845efe..7ddcd57ab 100644 --- a/Telegram/SourceFiles/boxes/reactions_settings_box.cpp +++ b/Telegram/SourceFiles/boxes/reactions_settings_box.cpp @@ -76,11 +76,11 @@ AdminLog::OwnedItem GenerateItem( const auto item = history->addNewLocalMessage( history->nextNonHistoryEntryId(), - MessageFlag::FakeHistoryItem + (MessageFlag::FakeHistoryItem | MessageFlag::HasFromId - | MessageFlag::HasReplyInfo, + | MessageFlag::HasReplyInfo), UserId(), // via - replyTo, + FullReplyTo{ .msgId = replyTo }, base::unixtime::now(), // date from, QString(), // postAuthor diff --git a/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp b/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp index fed572b75..dcebbfdc4 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_dice_pack.cpp @@ -128,7 +128,7 @@ void DicePack::generateLocal(int index, const QString &name) { QByteArray(), nullptr, SendMediaType::File, - FileLoadTo(0, {}, 0, 0, 0), + FileLoadTo(0, {}, {}, 0), {}, false); task.process({ .generateGoodThumbnail = false }); diff --git a/Telegram/SourceFiles/data/data_download_manager.cpp b/Telegram/SourceFiles/data/data_download_manager.cpp index 05080dfcb..088dc0b92 100644 --- a/Telegram/SourceFiles/data/data_download_manager.cpp +++ b/Telegram/SourceFiles/data/data_download_manager.cpp @@ -865,7 +865,7 @@ not_null DownloadManager::generateItem( ? previousItem->history() : session->data().history(session->user()); const auto flags = MessageFlag::FakeHistoryItem; - const auto replyTo = MsgId(); + const auto replyTo = FullReplyTo(); const auto viaBotId = UserId(); const auto date = base::unixtime::now(); const auto postAuthor = QString(); diff --git a/Telegram/SourceFiles/data/data_histories.cpp b/Telegram/SourceFiles/data/data_histories.cpp index 7c80d75ac..d69b11ce4 100644 --- a/Telegram/SourceFiles/data/data_histories.cpp +++ b/Telegram/SourceFiles/data/data_histories.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_forum.h" #include "data/data_forum_topic.h" #include "data/data_scheduled_messages.h" +#include "data/data_user.h" #include "base/unixtime.h" #include "base/random.h" #include "main/main_session.h" @@ -31,6 +32,29 @@ constexpr auto kReadRequestTimeout = 3 * crl::time(1000); } // namespace +MTPInputReplyTo ReplyToForMTP( + not_null owner, + FullReplyTo replyTo) { + if (replyTo.msgId || replyTo.topicRootId) { + using Flag = MTPDinputReplyToMessage::Flag; + return MTP_inputReplyToMessage( + (replyTo.topicRootId + ? MTP_flags(Flag::f_top_msg_id) + : MTP_flags(0)), + MTP_int(replyTo.msgId ? replyTo.msgId : replyTo.topicRootId), + MTP_int(replyTo.topicRootId)); + } else if (replyTo.storyId) { + if (const auto peer = owner->peerLoaded(replyTo.storyId.peer)) { + if (const auto user = peer->asUser()) { + return MTP_inputReplyToStory( + user->inputUser, + MTP_int(replyTo.storyId.story)); + } + } + } + return MTPInputReplyTo(); +} + Histories::Histories(not_null owner) : _owner(owner) , _readRequestsTimer([=] { sendReadRequests(); }) { @@ -885,23 +909,24 @@ bool Histories::isCreatingTopic( int Histories::sendPreparedMessage( not_null history, - MsgId replyTo, - MsgId topicRootId, + FullReplyTo replyTo, uint64 randomId, - Fn message, + Fn, FullReplyTo)> message, Fn done, Fn fail) { - if (isCreatingTopic(history, topicRootId)) { + if (isCreatingTopic(history, replyTo.topicRootId)) { const auto id = ++_requestAutoincrement; - const auto creatingId = FullMsgId(history->peer->id, topicRootId); + const auto creatingId = FullMsgId( + history->peer->id, + replyTo.topicRootId); auto i = _creatingTopics.find(creatingId); if (i == end(_creatingTopics)) { - sendCreateTopicRequest(history, topicRootId); + sendCreateTopicRequest(history, replyTo.topicRootId); i = _creatingTopics.emplace(creatingId).first; } i->second.push_back({ .randomId = randomId, - .replyTo = replyTo, + .replyTo = replyTo.msgId, .message = std::move(message), .done = std::move(done), .fail = std::move(fail), @@ -910,9 +935,12 @@ int Histories::sendPreparedMessage( _creatingTopicRequests.emplace(id); return id; } - const auto realReply = convertTopicReplyTo(history, replyTo); - const auto realRoot = convertTopicReplyTo(history, topicRootId); - return v::match(message(realReply, realRoot), [&](const auto &request) { + const auto realReplyTo = FullReplyTo{ + .msgId = convertTopicReplyToId(history, replyTo.msgId), + .topicRootId = convertTopicReplyToId(history, replyTo.topicRootId), + .storyId = replyTo.storyId, + }; + return v::match(message(_owner, realReplyTo), [&](const auto &request) { const auto type = RequestType::Send; return sendRequest(history, type, [=](Fn finish) { const auto session = &_owner->session(); @@ -955,8 +983,10 @@ void Histories::checkTopicCreated(FullMsgId rootId, MsgId realRoot) { _creatingTopicRequests.erase(entry.requestId); sendPreparedMessage( history, - entry.replyTo, - realRoot, + FullReplyTo{ + .msgId = entry.replyTo, + .topicRootId = realRoot, + }, entry.randomId, std::move(entry.message), std::move(entry.done), @@ -976,14 +1006,14 @@ void Histories::checkTopicCreated(FullMsgId rootId, MsgId realRoot) { } } -MsgId Histories::convertTopicReplyTo( +MsgId Histories::convertTopicReplyToId( not_null history, - MsgId replyTo) const { - if (!replyTo) { + MsgId replyToId) const { + if (!replyToId) { return {}; } - const auto i = _createdTopicIds.find({ history->peer->id, replyTo }); - return (i != end(_createdTopicIds)) ? i->second : replyTo; + const auto i = _createdTopicIds.find({ history->peer->id, replyToId }); + return (i != end(_createdTopicIds)) ? i->second : replyToId; } void Histories::checkPostponed(not_null history, int id) { diff --git a/Telegram/SourceFiles/data/data_histories.h b/Telegram/SourceFiles/data/data_histories.h index 05f7534f4..c98dc352c 100644 --- a/Telegram/SourceFiles/data/data_histories.h +++ b/Telegram/SourceFiles/data/data_histories.h @@ -26,6 +26,10 @@ namespace Data { class Session; class Folder; +[[nodiscard]] MTPInputReplyTo ReplyToForMTP( + not_null owner, + FullReplyTo replyTo); + class Histories final { public: enum class RequestType : uchar { @@ -102,29 +106,27 @@ public: MTPmessages_SendMultiMedia>; int sendPreparedMessage( not_null history, - MsgId replyTo, - MsgId topicRootId, + FullReplyTo replyTo, uint64 randomId, - Fn message, + Fn, FullReplyTo)> message, Fn done, Fn fail); struct ReplyToPlaceholder { }; - struct TopicRootPlaceholder { - }; template - static Fn PrepareMessage( - const Args &...args) { - return [=](MsgId replyTo, MsgId topicRootId) -> RequestType { - return { ReplaceReplyIds(args, replyTo, topicRootId)... }; + static auto PrepareMessage(const Args &...args) + -> Fn, FullReplyTo)> { + return [=](not_null owner, FullReplyTo replyTo) + -> RequestType { + return { ReplaceReplyIds(owner, args, replyTo)... }; }; } void checkTopicCreated(FullMsgId rootId, MsgId realRoot); - [[nodiscard]] MsgId convertTopicReplyTo( + [[nodiscard]] MsgId convertTopicReplyToId( not_null history, - MsgId replyTo) const; + MsgId replyToId) const; private: struct PostponedHistoryRequest { @@ -151,7 +153,7 @@ private: struct DelayedByTopicMessage { uint64 randomId = 0; MsgId replyTo = 0; - Fn message; + Fn, FullReplyTo)> message; Fn done; Fn fail; int requestId = 0; @@ -166,11 +168,12 @@ private: }; template - static auto ReplaceReplyIds(Arg arg, MsgId replyTo, MsgId topicRootId) { + static auto ReplaceReplyIds( + not_null owner, + Arg arg, + FullReplyTo replyTo) { if constexpr (std::is_same_v) { - return MTP_int(replyTo); - } else if constexpr (std::is_same_v) { - return MTP_int(topicRootId); + return ReplyToForMTP(owner, replyTo); } else { return arg; } diff --git a/Telegram/SourceFiles/data/data_msg_id.h b/Telegram/SourceFiles/data/data_msg_id.h index ac39eddfb..af6b73fcc 100644 --- a/Telegram/SourceFiles/data/data_msg_id.h +++ b/Telegram/SourceFiles/data/data_msg_id.h @@ -136,6 +136,37 @@ struct GlobalMsgId { } }; +using StoryId = int32; + +struct FullStoryId { + PeerId peer = 0; + StoryId story = 0; + + [[nodiscard]] bool valid() const { + return peer != 0 && story != 0; + } + explicit operator bool() const { + return valid(); + } + friend inline auto operator<=>(FullStoryId, FullStoryId) = default; + friend inline bool operator==(FullStoryId, FullStoryId) = default; +}; + +struct FullReplyTo { + MsgId msgId = 0; + MsgId topicRootId = 0; + FullStoryId storyId; + + [[nodiscard]] bool valid() const { + return msgId || storyId; + } + explicit operator bool() const { + return valid(); + } + friend inline auto operator<=>(FullReplyTo, FullReplyTo) = default; + friend inline bool operator==(FullReplyTo, FullReplyTo) = default; +}; + namespace std { template <> diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp index 21e0c48b3..820b7c0d2 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp @@ -192,13 +192,13 @@ void ScheduledMessages::sendNowSimpleMessage( const auto history = local->history(); auto action = Api::SendAction(history); - action.replyTo = local->replyToId(); + action.replyTo = local->replyTo(); const auto replyHeader = NewMessageReplyHeader(action); const auto localFlags = NewMessageFlags(history->peer) & ~MessageFlag::BeingSent; const auto flags = MTPDmessage::Flag::f_entities | MTPDmessage::Flag::f_from_id - | (local->replyToId() + | (action.replyTo ? MTPDmessage::Flag::f_reply_to : MTPDmessage::Flag(0)) | (update.vttl_period() diff --git a/Telegram/SourceFiles/data/data_stories.h b/Telegram/SourceFiles/data/data_stories.h index ce8ca4d60..6c3aaa56d 100644 --- a/Telegram/SourceFiles/data/data_stories.h +++ b/Telegram/SourceFiles/data/data_stories.h @@ -46,20 +46,6 @@ struct StoriesList { friend inline bool operator==(StoriesList, StoriesList) = default; }; -struct FullStoryId { - UserData *user = nullptr; - StoryId id = 0; - - [[nodiscard]] bool valid() const { - return user != nullptr && id != 0; - } - explicit operator bool() const { - return valid(); - } - friend inline auto operator<=>(FullStoryId, FullStoryId) = default; - friend inline bool operator==(FullStoryId, FullStoryId) = default; -}; - class Stories final { public: explicit Stories(not_null owner); diff --git a/Telegram/SourceFiles/data/data_types.h b/Telegram/SourceFiles/data/data_types.h index 8f6ee551b..710cc4e1f 100644 --- a/Telegram/SourceFiles/data/data_types.h +++ b/Telegram/SourceFiles/data/data_types.h @@ -135,7 +135,6 @@ using PollId = uint64; using WallPaperId = uint64; using CallId = uint64; using BotAppId = uint64; -using StoryId = int32; constexpr auto CancelledWebPageId = WebPageId(0xFFFFFFFFFFFFFFFFULL); diff --git a/Telegram/SourceFiles/export/data/export_data_types.cpp b/Telegram/SourceFiles/export/data/export_data_types.cpp index b0bd24268..1b66a550f 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.cpp +++ b/Telegram/SourceFiles/export/data/export_data_types.cpp @@ -1260,6 +1260,8 @@ Message ParseMessage( if (result.replyToPeerId == result.peerId) { result.replyToPeerId = 0; } + }, [&](const MTPDmessageReplyStoryHeader &data) { + // #TODO stories export }); } } @@ -1307,6 +1309,8 @@ Message ParseMessage( result.replyToPeerId = data.vreply_to_peer_id() ? ParsePeerId(*data.vreply_to_peer_id()) : PeerId(0); + }, [&](const MTPDmessageReplyStoryHeader &data) { + // #TODO stories export }); } if (const auto viaBotId = data.vvia_bot_id()) { diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp index ba2442308..4e2e3cd41 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_item.cpp @@ -820,7 +820,7 @@ void GenerateItems( const auto makeSimpleTextMessage = [&](TextWithEntities &&text) { const auto bodyFlags = MessageFlag::HasFromId | MessageFlag::AdminLogEntry; - const auto bodyReplyTo = MsgId(); + const auto bodyReplyTo = FullReplyTo(); const auto bodyViaBotId = UserId(); const auto bodyGroupedId = uint64(); return history->makeMessage( diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 262af2bec..5617a0991 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -631,7 +631,7 @@ not_null History::addNewLocalMessage( MsgId id, MessageFlags flags, UserId viaBotId, - MsgId replyTo, + FullReplyTo replyTo, TimeId date, PeerId from, const QString &postAuthor, @@ -679,7 +679,7 @@ not_null History::addNewLocalMessage( MsgId id, MessageFlags flags, UserId viaBotId, - MsgId replyTo, + FullReplyTo replyTo, TimeId date, PeerId from, const QString &postAuthor, @@ -705,7 +705,7 @@ not_null History::addNewLocalMessage( MsgId id, MessageFlags flags, UserId viaBotId, - MsgId replyTo, + FullReplyTo replyTo, TimeId date, PeerId from, const QString &postAuthor, @@ -731,7 +731,7 @@ not_null History::addNewLocalMessage( MsgId id, MessageFlags flags, UserId viaBotId, - MsgId replyTo, + FullReplyTo replyTo, TimeId date, PeerId from, const QString &postAuthor, @@ -1144,6 +1144,8 @@ void History::applyServiceChanges( topic->setHasPinnedMessages(true); } } + }, [&](const MTPDmessageReplyStoryHeader &data) { + LOG(("API Error: story reply in messageActionPinMessage.")); }); } }, [&](const MTPDmessageActionGroupCall &data) { diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index d2b80be10..933832d79 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -148,7 +148,7 @@ public: MsgId id, MessageFlags flags, UserId viaBotId, - MsgId replyTo, + FullReplyTo replyTo, TimeId date, PeerId from, const QString &postAuthor, @@ -168,7 +168,7 @@ public: MsgId id, MessageFlags flags, UserId viaBotId, - MsgId replyTo, + FullReplyTo replyTo, TimeId date, PeerId from, const QString &postAuthor, @@ -179,7 +179,7 @@ public: MsgId id, MessageFlags flags, UserId viaBotId, - MsgId replyTo, + FullReplyTo replyTo, TimeId date, PeerId from, const QString &postAuthor, @@ -190,7 +190,7 @@ public: MsgId id, MessageFlags flags, UserId viaBotId, - MsgId replyTo, + FullReplyTo replyTo, TimeId date, PeerId from, const QString &postAuthor, diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index e719d9716..8d0d8b980 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -390,7 +390,7 @@ bool HistoryInner::BotAbout::refresh() { | MessageFlag::Local; const auto postAuthor = QString(); const auto date = TimeId(0); - const auto replyTo = MsgId(0); + const auto replyTo = FullReplyTo(); const auto viaBotId = UserId(0); const auto groupedId = uint64(0); const auto textWithEntities = TextUtilities::ParseEntities( diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index b0c2e55f0..cab562735 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -131,6 +131,7 @@ struct HistoryItem::CreateConfig { PeerId replyToPeer = 0; MsgId replyTo = 0; MsgId replyToTop = 0; + StoryId replyToStory = 0; bool replyIsTopicPost = false; UserId viaBotId = 0; int viewsCount = -1; @@ -506,7 +507,7 @@ HistoryItem::HistoryItem( not_null history, MsgId id, MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, TimeId date, PeerId from, @@ -541,7 +542,7 @@ HistoryItem::HistoryItem( not_null history, MsgId id, MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, TimeId date, PeerId from, @@ -576,7 +577,7 @@ HistoryItem::HistoryItem( not_null history, MsgId id, MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, TimeId date, PeerId from, @@ -606,7 +607,7 @@ HistoryItem::HistoryItem( not_null history, MsgId id, MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, TimeId date, PeerId from, @@ -648,7 +649,7 @@ HistoryItem::HistoryItem( /*from.peer ? from.peer->id : */PeerId(0)) { createComponentsHelper( _flags, - MsgId(0), // replyTo + FullReplyTo(), UserId(0), // viaBotId QString(), // postAuthor HistoryMessageMarkupData()); @@ -1542,6 +1543,7 @@ void HistoryItem::applySentMessage(const MTPDmessage &data) { data.vreply_to_top_id().value_or( data.vreply_to_msg_id().v), data.is_forum_topic()); + }, [](const MTPDmessageReplyStoryHeader &data) { }); } setPostAuthor(data.vpost_author().value_or_empty()); @@ -2742,6 +2744,26 @@ MsgId HistoryItem::topicRootId() const { return Data::ForumTopic::kGeneralId; } +FullStoryId HistoryItem::replyToStory() const { + if (const auto reply = Get()) { + if (reply->replyToStoryId) { + const auto peerId = reply->replyToPeerId + ? reply->replyToPeerId + : _history->peer->id; + return { .peer = peerId, .story = reply->replyToStoryId }; + } + } + return {}; +} + +FullReplyTo HistoryItem::replyTo() const { + return { + .msgId = replyToId(), + .topicRootId = topicRootId(), + .storyId = replyToStory(), + }; +} + void HistoryItem::setText(const TextWithEntities &textWithEntities) { for (const auto &entity : textWithEntities.entities) { auto type = entity.type(); @@ -2903,7 +2925,7 @@ const std::vector &HistoryItem::customTextLinks() const { void HistoryItem::createComponents(CreateConfig &&config) { uint64 mask = 0; - if (config.replyTo) { + if (config.replyTo || config.replyToStory) { mask |= HistoryMessageReply::Bit(); } if (config.viaBotId) { @@ -3125,17 +3147,19 @@ void HistoryItem::setSponsoredFrom(const Data::SponsoredFrom &from) { void HistoryItem::createComponentsHelper( MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, const QString &postAuthor, HistoryMessageMarkupData &&markup) { auto config = CreateConfig(); config.viaBotId = viaBotId; if (flags & MessageFlag::HasReplyInfo) { - config.replyTo = replyTo; - const auto to = LookupReplyTo(_history, replyTo); + config.replyTo = replyTo.msgId; + config.replyToStory = replyTo.storyId.story; + config.replyToPeer = replyTo.storyId ? replyTo.storyId.peer : 0; + const auto to = LookupReplyTo(_history, replyTo.msgId); const auto replyToTop = LookupReplyToTop(to); - config.replyToTop = replyToTop ? replyToTop : replyTo; + config.replyToTop = replyToTop ? replyToTop : replyTo.msgId; const auto forum = _history->asForum(); config.replyIsTopicPost = LookupReplyIsTopicPost(to) || (to && to->Has()) @@ -3245,6 +3269,9 @@ void HistoryItem::createComponents(const MTPDmessage &data) { : id; config.replyToTop = data.vreply_to_top_id().value_or(id); config.replyIsTopicPost = data.is_forum_topic(); + }, [&](const MTPDmessageReplyStoryHeader &data) { + config.replyToPeer = peerFromUser(data.vuser_id()); + config.replyToStory = data.vstory_id().v; }); } config.viaBotId = data.vvia_bot_id().value_or_empty(); @@ -3499,6 +3526,7 @@ void HistoryItem::createServiceFromMtp(const MTPDmessageService &message) { dependent->msgId); } } + }, [](const MTPDmessageReplyStoryHeader &data) { }); } setServiceMessageByAction(action); diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index b26793963..7ef66d7d6 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -117,7 +117,7 @@ public: not_null history, MsgId id, MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, TimeId date, PeerId from, @@ -147,7 +147,7 @@ public: not_null history, MsgId id, MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, TimeId date, PeerId from, @@ -159,7 +159,7 @@ public: not_null history, MsgId id, MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, TimeId date, PeerId from, @@ -171,7 +171,7 @@ public: not_null history, MsgId id, MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, TimeId date, PeerId from, @@ -458,6 +458,8 @@ public: [[nodiscard]] MsgId replyToId() const; [[nodiscard]] MsgId replyToTop() const; [[nodiscard]] MsgId topicRootId() const; + [[nodiscard]] FullStoryId replyToStory() const; + [[nodiscard]] FullReplyTo replyTo() const; [[nodiscard]] bool inThread(MsgId rootId) const; [[nodiscard]] not_null author() const; @@ -518,7 +520,7 @@ private: void createComponentsHelper( MessageFlags flags, - MsgId replyTo, + FullReplyTo replyTo, UserId viaBotId, const QString &postAuthor, HistoryMessageMarkupData &&markup); diff --git a/Telegram/SourceFiles/history/history_item_components.h b/Telegram/SourceFiles/history/history_item_components.h index 5b92c6cfc..0545a9760 100644 --- a/Telegram/SourceFiles/history/history_item_components.h +++ b/Telegram/SourceFiles/history/history_item_components.h @@ -243,6 +243,7 @@ struct HistoryMessageReply PeerId replyToPeerId = 0; MsgId replyToMsgId = 0; MsgId replyToMsgTop = 0; + StoryId replyToStoryId = 0; using ColorKey = PeerId; ColorKey replyToColorKey = 0; DocumentId replyToDocumentId = 0; diff --git a/Telegram/SourceFiles/history/history_item_helpers.cpp b/Telegram/SourceFiles/history/history_item_helpers.cpp index 7042cb557..a7def067b 100644 --- a/Telegram/SourceFiles/history/history_item_helpers.cpp +++ b/Telegram/SourceFiles/history/history_item_helpers.cpp @@ -309,8 +309,13 @@ MessageFlags FlagsFromMTP( } MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action) { - if (const auto id = action.replyTo) { - const auto to = LookupReplyTo(action.history, id); + if (const auto replyTo = action.replyTo) { + if (replyTo.storyId) { + return MTP_messageReplyStoryHeader( + MTP_long(peerToUser(replyTo.storyId.peer).bare), + MTP_int(replyTo.storyId.story)); + } + const auto to = LookupReplyTo(action.history, replyTo.msgId); if (const auto replyToTop = LookupReplyToTop(to)) { using Flag = MTPDmessageReplyHeader::Flag; return MTP_messageReplyHeader( @@ -318,13 +323,13 @@ MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action) { | (LookupReplyIsTopicPost(to) ? Flag::f_forum_topic : Flag(0))), - MTP_int(id), + MTP_int(replyTo.msgId), MTPPeer(), MTP_int(replyToTop)); } return MTP_messageReplyHeader( MTP_flags(0), - MTP_int(id), + MTP_int(replyTo.msgId), MTPPeer(), MTPint()); } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 99db1769a..106dce71e 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -853,7 +853,7 @@ HistoryWidget::HistoryWidget( }) | rpl::start_with_next([=](const Api::SendAction &action) { const auto lastKeyboardUsed = lastForceReplyReplied(FullMsgId( action.history->peer->id, - action.replyTo)); + action.replyTo.msgId)); if (action.replaceMediaOf) { } else if (action.options.scheduled) { cancelReply(lastKeyboardUsed); @@ -3841,8 +3841,7 @@ void HistoryWidget::hideSelectorControlsAnimated() { Api::SendAction HistoryWidget::prepareSendAction( Api::SendOptions options) const { auto result = Api::SendAction(_history, options); - result.replyTo = replyToId(); - result.topicRootId = 0; + result.replyTo = { .msgId = replyToId() }; result.options.sendAs = _sendAs ? _history->session().sendAsPeers().resolveChosen( _history->peer).get() @@ -4348,7 +4347,7 @@ void HistoryWidget::sendBotCommand(const Bot::SendCommandRequest &request) { auto message = Api::MessageToSend(prepareSendAction({})); message.textWithTags = { toSend, TextWithTags::Tags() }; - message.action.replyTo = request.replyTo + message.action.replyTo.msgId = request.replyTo ? ((!_peer->isUser()/* && (botStatus == 0 || botStatus == 2)*/) ? request.replyTo : replyToId()) diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index f8ddd36e2..aeacfd251 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -1012,7 +1012,7 @@ void RepliesWidget::sendingFilesConfirmed( album, action); } - if (_composeControls->replyingToMessage().msg == action.replyTo) { + if (_composeControls->replyingToMessage().msg == action.replyTo.msgId) { _composeControls->cancelReplyMessage(); refreshTopBarActiveChat(); } @@ -1135,8 +1135,7 @@ bool RepliesWidget::showSendingFilesError( Api::SendAction RepliesWidget::prepareSendAction( Api::SendOptions options) const { auto result = Api::SendAction(_history, options); - result.replyTo = replyToId(); - result.topicRootId = _rootId; + result.replyTo = { .msgId = replyToId(), .topicRootId = _rootId }; result.options.sendAs = _composeControls->sendAsPeer(); return result; } diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index 5b4398c9f..e00e50d43 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -481,7 +481,6 @@ bool AttachWebView::IsSame( && (a->fromSwitch == b.fromSwitch) && (a->action.history == b.action.history) && (a->action.replyTo == b.action.replyTo) - && (a->action.topicRootId == b.action.topicRootId) && (a->action.options.sendAs == b.action.options.sendAs) && (a->action.options.silent == b.action.options.silent); } @@ -533,8 +532,7 @@ void AttachWebView::request(const WebViewButton &button) { const auto flags = Flag::f_theme_params | (button.url.isEmpty() ? Flag(0) : Flag::f_url) | (_startCommand.isEmpty() ? Flag(0) : Flag::f_start_param) - | (action.replyTo ? Flag::f_reply_to_msg_id : Flag(0)) - | (action.topicRootId ? Flag::f_top_msg_id : Flag(0)) + | (action.replyTo ? Flag::f_reply_to : Flag(0)) | (action.options.sendAs ? Flag::f_send_as : Flag(0)) | (action.options.silent ? Flag::f_silent : Flag(0)); _requestId = _session->api().request(MTPmessages_RequestWebView( @@ -545,8 +543,7 @@ void AttachWebView::request(const WebViewButton &button) { MTP_string(_startCommand), MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)), MTP_string("tdesktop"), - MTP_int(action.replyTo.bare), - MTP_int(action.topicRootId.bare), + action.mtpReplyTo(), (action.options.sendAs ? action.options.sendAs->input : MTP_inputPeerEmpty()) @@ -810,8 +807,7 @@ void AttachWebView::requestMenu( MTP_flags(Flag::f_theme_params | Flag::f_url | Flag::f_from_bot_menu - | (action.replyTo? Flag::f_reply_to_msg_id : Flag(0)) - | (action.topicRootId ? Flag::f_top_msg_id : Flag(0)) + | (action.replyTo? Flag::f_reply_to : Flag(0)) | (action.options.sendAs ? Flag::f_send_as : Flag(0)) | (action.options.silent ? Flag::f_silent : Flag(0))), action.history->peer->input, @@ -820,8 +816,7 @@ void AttachWebView::requestMenu( MTPstring(), // start_param MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)), MTP_string("tdesktop"), - MTP_int(action.replyTo.bare), - MTP_int(action.topicRootId.bare), + action.mtpReplyTo(), (action.options.sendAs ? action.options.sendAs->input : MTP_inputPeerEmpty()) @@ -1189,15 +1184,13 @@ void AttachWebView::started(uint64 queryId) { _session->api().request(base::take(_prolongId)).cancel(); _prolongId = _session->api().request(MTPmessages_ProlongWebView( MTP_flags(Flag(0) - | (action.replyTo ? Flag::f_reply_to_msg_id : Flag(0)) - | (action.topicRootId ? Flag::f_top_msg_id : Flag(0)) + | (action.replyTo ? Flag::f_reply_to : Flag(0)) | (action.options.sendAs ? Flag::f_send_as : Flag(0)) | (action.options.silent ? Flag::f_silent : Flag(0))), action.history->peer->input, _bot->inputUser, MTP_long(queryId), - MTP_int(action.replyTo.bare), - MTP_int(action.topicRootId.bare), + action.mtpReplyTo(), (action.options.sendAs ? action.options.sendAs->input : MTP_inputPeerEmpty()) diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp index 02de341e6..2c10d887c 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp @@ -374,7 +374,7 @@ void Result::addToHistory( PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor) const { flags |= MessageFlag::FromInlineBot; @@ -390,7 +390,7 @@ void Result::addToHistory( fromId, date, viaBotId, - replyToId, + replyTo, postAuthor, std::move(markup)); } diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.h b/Telegram/SourceFiles/inline_bots/inline_bot_result.h index 45c8f6b39..296deb613 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_result.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.h @@ -69,7 +69,7 @@ public: PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor) const; QString getErrorOnSend(not_null history) const; diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp index c1ec877e8..a2f342d28 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp @@ -36,18 +36,18 @@ void SendDataCommon::addToHistory( PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor, HistoryMessageMarkupData &&markup) const { auto fields = getSentMessageFields(); - if (replyToId) { + if (replyTo) { flags |= MessageFlag::HasReplyInfo; } history->addNewLocalMessage( msgId, flags, viaBotId, - replyToId, + replyTo, date, fromId, postAuthor, @@ -119,14 +119,14 @@ void SendPhoto::addToHistory( PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor, HistoryMessageMarkupData &&markup) const { history->addNewLocalMessage( msgId, flags, viaBotId, - replyToId, + replyTo, date, fromId, postAuthor, @@ -150,14 +150,14 @@ void SendFile::addToHistory( PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor, HistoryMessageMarkupData &&markup) const { history->addNewLocalMessage( msgId, flags, viaBotId, - replyToId, + replyTo, date, fromId, postAuthor, @@ -181,14 +181,14 @@ void SendGame::addToHistory( PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor, HistoryMessageMarkupData &&markup) const { history->addNewLocalMessage( msgId, flags, viaBotId, - replyToId, + replyTo, date, fromId, postAuthor, diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h index bab720f11..84c25624f 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h @@ -48,7 +48,7 @@ public: PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor, HistoryMessageMarkupData &&markup) const = 0; virtual QString getErrorOnSend( @@ -90,7 +90,7 @@ public: PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor, HistoryMessageMarkupData &&markup) const override; @@ -258,7 +258,7 @@ public: PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor, HistoryMessageMarkupData &&markup) const override; @@ -299,7 +299,7 @@ public: PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor, HistoryMessageMarkupData &&markup) const override; @@ -334,7 +334,7 @@ public: PeerId fromId, TimeId date, UserId viaBotId, - MsgId replyToId, + FullReplyTo replyTo, const QString &postAuthor, HistoryMessageMarkupData &&markup) const override; diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp index f46f37304..3f1a2871c 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.cpp @@ -363,9 +363,9 @@ void Controller::show( } _index = subindex; - const auto id = Data::FullStoryId{ - .user = list.user, - .id = item.id, + const auto id = FullStoryId{ + .peer = list.user->id, + .story = item.id, }; if (_shown == id) { return; @@ -425,7 +425,7 @@ void Controller::updatePlayback(const Player::TrackState &state) { updatePowerSaveBlocker(state); if (Player::IsStoppedAtEnd(state.state)) { if (!subjumpFor(1)) { - _delegate->storiesJumpTo({}); + _delegate->storiesClose(); } } } @@ -448,9 +448,9 @@ bool Controller::subjumpFor(int delta) { } else if (!_list || _list->items.empty()) { return false; } - _delegate->storiesJumpTo({ - .user = _list->user, - .id = _list->items.front().id + _delegate->storiesJumpTo(&_list->user->session(), { + .peer = _list->user->id, + .story = _list->items.front().id }); return true; } else if (index >= _list->total) { @@ -459,9 +459,9 @@ bool Controller::subjumpFor(int delta) { && jumpFor(1); } else if (index < _list->items.size()) { // #TODO stories load more - _delegate->storiesJumpTo({ - .user = _list->user, - .id = _list->items[index].id + _delegate->storiesJumpTo(&_list->user->session(), { + .peer = _list->user->id, + .story = _list->items[index].id }); } return true; @@ -471,12 +471,16 @@ bool Controller::subjumpFor(int delta) { bool Controller::jumpFor(int delta) { if (delta == -1) { if (const auto left = _siblingLeft.get()) { - _delegate->storiesJumpTo(left->shownId()); + _delegate->storiesJumpTo( + &left->peer()->session(), + left->shownId()); return true; } } else if (delta == 1) { if (const auto right = _siblingRight.get()) { - _delegate->storiesJumpTo(right->shownId()); + _delegate->storiesJumpTo( + &right->peer()->session(), + right->shownId()); return true; } } diff --git a/Telegram/SourceFiles/media/stories/media_stories_controller.h b/Telegram/SourceFiles/media/stories/media_stories_controller.h index 2715ce8f5..f553f895e 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_controller.h +++ b/Telegram/SourceFiles/media/stories/media_stories_controller.h @@ -139,7 +139,7 @@ private: Ui::Animations::Simple _contentFadeAnimation; bool _contentFaded = false; - Data::FullStoryId _shown; + FullStoryId _shown; TextWithEntities _captionText; std::optional _list; int _index = 0; diff --git a/Telegram/SourceFiles/media/stories/media_stories_delegate.h b/Telegram/SourceFiles/media/stories/media_stories_delegate.h index 8a34c47bd..a9c3b0a35 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_delegate.h +++ b/Telegram/SourceFiles/media/stories/media_stories_delegate.h @@ -12,9 +12,9 @@ class Show; struct FileChosen; } // namespace ChatHelpers -namespace Data { -struct FullStoryId; -} // namespace Data +namespace Main { +class Session; +} // namespace Main namespace Ui { class RpWidget; @@ -39,7 +39,10 @@ public: -> std::shared_ptr = 0; [[nodiscard]] virtual auto storiesStickerOrEmojiChosen() -> rpl::producer = 0; - virtual void storiesJumpTo(Data::FullStoryId id) = 0; + virtual void storiesJumpTo( + not_null session, + FullStoryId id) = 0; + virtual void storiesClose() = 0; [[nodiscard]] virtual bool storiesPaused() = 0; [[nodiscard]] virtual float64 storiesSiblingOver(SiblingType type) = 0; virtual void storiesTogglePaused(bool paused) = 0; diff --git a/Telegram/SourceFiles/media/stories/media_stories_sibling.cpp b/Telegram/SourceFiles/media/stories/media_stories_sibling.cpp index a37b4a472..4b5e09bde 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_sibling.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_sibling.cpp @@ -217,7 +217,8 @@ Sibling::Sibling( not_null controller, const Data::StoriesList &list) : _controller(controller) -, _id{ list.user, list.items.front().id } { +, _id{ list.user->id, list.items.front().id } +, _peer(list.user) { const auto &item = list.items.front(); const auto &data = item.media.data; const auto origin = Data::FileOrigin(); @@ -239,14 +240,18 @@ Sibling::Sibling( Sibling::~Sibling() = default; -Data::FullStoryId Sibling::shownId() const { +FullStoryId Sibling::shownId() const { return _id; } +not_null Sibling::peer() const { + return _peer; +} + bool Sibling::shows(const Data::StoriesList &list) const { Expects(!list.items.empty()); - return _id == Data::FullStoryId{ list.user, list.items.front().id }; + return _id == FullStoryId{ list.user->id, list.items.front().id }; } SiblingView Sibling::view(const SiblingLayout &layout, float64 over) { @@ -268,22 +273,18 @@ SiblingView Sibling::view(const SiblingLayout &layout, float64 over) { } QImage Sibling::userpicImage(const SiblingLayout &layout) { - Expects(_id.user != nullptr); - const auto ratio = style::DevicePixelRatio(); const auto size = layout.userpic.width() * ratio; - const auto key = _id.user->userpicUniqueKey(_userpicView); + const auto key = _peer->userpicUniqueKey(_userpicView); if (_userpicImage.width() != size || _userpicKey != key) { _userpicKey = key; - _userpicImage = _id.user->generateUserpicImage(_userpicView, size); + _userpicImage = _peer->generateUserpicImage(_userpicView, size); _userpicImage.setDevicePixelRatio(ratio); } return _userpicImage; } QImage Sibling::nameImage(const SiblingLayout &layout) { - Expects(_id.user != nullptr); - if (_nameFontSize != layout.nameFontSize) { _nameFontSize = layout.nameFontSize; @@ -299,7 +300,7 @@ QImage Sibling::nameImage(const SiblingLayout &layout) { .linkFontOver = font, }); }; - const auto text = _id.user->shortName(); + const auto text = _peer->shortName(); if (_nameText != text) { _name.reset(); _nameText = text; diff --git a/Telegram/SourceFiles/media/stories/media_stories_sibling.h b/Telegram/SourceFiles/media/stories/media_stories_sibling.h index ecbd89de7..dc355fec6 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_sibling.h +++ b/Telegram/SourceFiles/media/stories/media_stories_sibling.h @@ -29,7 +29,8 @@ public: const Data::StoriesList &list); ~Sibling(); - [[nodiscard]] Data::FullStoryId shownId() const; + [[nodiscard]] FullStoryId shownId() const; + [[nodiscard]] not_null peer() const; [[nodiscard]] bool shows(const Data::StoriesList &list) const; [[nodiscard]] SiblingView view( @@ -51,7 +52,8 @@ private: const not_null _controller; - Data::FullStoryId _id; + FullStoryId _id; + not_null _peer; QImage _blurred; QImage _good; Ui::Animations::Simple _goodShown; diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 733c61851..1bd915558 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -4028,28 +4028,27 @@ auto OverlayWidget::storiesStickerOrEmojiChosen() return _storiesStickerOrEmojiChosen.events(); } -void OverlayWidget::storiesJumpTo(Data::FullStoryId id) { +void OverlayWidget::storiesJumpTo( + not_null session, + FullStoryId id) { Expects(_stories != nullptr); + Expects(id.valid()); - if (!id) { - close(); - return; - } - const auto &all = id.user->owner().stories().all(); + const auto &all = session->data().stories().all(); const auto i = ranges::find( all, - not_null(id.user), - &Data::StoriesList::user); + id.peer, + [](const Data::StoriesList &list) { return list.user->id; }); if (i == end(all)) { close(); return; } - const auto j = ranges::find(i->items, id.id, &Data::StoryItem::id); + const auto j = ranges::find(i->items, id.story, &Data::StoryItem::id); if (j == end(i->items)) { close(); return; } - setContext(StoriesContext{ i->user, id.id }); + setContext(StoriesContext{ i->user, id.story }); clearStreaming(); _streamingStartPaused = false; const auto &data = j->media.data; @@ -4061,6 +4060,10 @@ void OverlayWidget::storiesJumpTo(Data::FullStoryId id) { } } +void OverlayWidget::storiesClose() { + close(); +} + bool OverlayWidget::storiesPaused() { return _streamed && !_streamed->instance.player().failed() diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index 43551bf41..a82aa1f3c 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -30,7 +30,6 @@ enum class activation : uchar; namespace Data { class PhotoMedia; class DocumentMedia; -struct FullStoryId; } // namespace Data namespace Ui { @@ -243,7 +242,10 @@ private: std::shared_ptr storiesShow() override; auto storiesStickerOrEmojiChosen() -> rpl::producer override; - void storiesJumpTo(Data::FullStoryId id) override; + void storiesJumpTo( + not_null session, + FullStoryId id) override; + void storiesClose() override; bool storiesPaused() override; void storiesTogglePaused(bool paused) override; float64 storiesSiblingOver(Stories::SiblingType type) override; diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp index f1961f042..cf9f4c775 100644 --- a/Telegram/SourceFiles/passport/passport_form_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp @@ -1584,7 +1584,7 @@ void FormController::uploadEncryptedFile( auto prepared = std::make_shared( TaskId(), file.uploadData->fileId, - FileLoadTo(PeerId(), Api::SendOptions(), MsgId(), MsgId(), MsgId()), + FileLoadTo(PeerId(), Api::SendOptions(), FullReplyTo(), MsgId()), TextWithTags(), false, std::shared_ptr(nullptr)); diff --git a/Telegram/SourceFiles/storage/localimageloader.cpp b/Telegram/SourceFiles/storage/localimageloader.cpp index 1386b2a74..1516594a9 100644 --- a/Telegram/SourceFiles/storage/localimageloader.cpp +++ b/Telegram/SourceFiles/storage/localimageloader.cpp @@ -221,56 +221,6 @@ int PhotoSideLimit() { return PhotoSideLimit(SendLargePhotos.value()); } -SendMediaPrepare::SendMediaPrepare( - const QString &file, - const PeerId &peer, - SendMediaType type, - MsgId replyTo) -: id(base::RandomValue()) -, file(file) -, peer(peer) -, type(type) -, replyTo(replyTo) { -} - -SendMediaPrepare::SendMediaPrepare( - const QImage &img, - const PeerId &peer, - SendMediaType type, - MsgId replyTo) -: id(base::RandomValue()) -, img(img) -, peer(peer) -, type(type) -, replyTo(replyTo) { -} - -SendMediaPrepare::SendMediaPrepare( - const QByteArray &data, - const PeerId &peer, - SendMediaType type, - MsgId replyTo) -: id(base::RandomValue()) -, data(data) -, peer(peer) -, type(type) -, replyTo(replyTo) { -} - -SendMediaPrepare::SendMediaPrepare( - const QByteArray &data, - int duration, - const PeerId &peer, - SendMediaType type, - MsgId replyTo) -: id(base::RandomValue()) -, data(data) -, peer(peer) -, type(type) -, duration(duration) -, replyTo(replyTo) { -} - SendMediaReady::SendMediaReady( SendMediaType type, const QString &file, @@ -284,10 +234,8 @@ SendMediaReady::SendMediaReady( const MTPPhoto &photo, const PreparedPhotoThumbs &photoThumbs, const MTPDocument &document, - const QByteArray &jpeg, - MsgId replyTo) -: replyTo(replyTo) -, type(type) + const QByteArray &jpeg) +: type(type) , file(file) , filename(filename) , filesize(filesize) diff --git a/Telegram/SourceFiles/storage/localimageloader.h b/Telegram/SourceFiles/storage/localimageloader.h index 59e3c1325..3d4354623 100644 --- a/Telegram/SourceFiles/storage/localimageloader.h +++ b/Telegram/SourceFiles/storage/localimageloader.h @@ -36,41 +36,6 @@ enum class SendMediaType { Secure, }; -struct SendMediaPrepare { - SendMediaPrepare( - const QString &file, - const PeerId &peer, - SendMediaType type, - MsgId replyTo); - SendMediaPrepare( - const QImage &img, - const PeerId &peer, - SendMediaType type, - MsgId replyTo); - SendMediaPrepare( - const QByteArray &data, - const PeerId &peer, - SendMediaType type, - MsgId replyTo); - SendMediaPrepare( - const QByteArray &data, - int duration, - const PeerId &peer, - SendMediaType type, - MsgId replyTo); - - PhotoId id; - QString file; - QImage img; - QByteArray data; - PeerId peer; - SendMediaType type; - int duration = 0; - MsgId replyTo; - -}; -using SendMediaPrepareList = QList; - using UploadFileParts = QMap; struct SendMediaReady { SendMediaReady() = default; // temp @@ -87,10 +52,8 @@ struct SendMediaReady { const MTPPhoto &photo, const PreparedPhotoThumbs &photoThumbs, const MTPDocument &document, - const QByteArray &jpeg, - MsgId replyTo); + const QByteArray &jpeg); - MsgId replyTo; SendMediaType type; QString file, filename; int64 filesize = 0; @@ -206,19 +169,16 @@ struct FileLoadTo { FileLoadTo( PeerId peer, Api::SendOptions options, - MsgId replyTo, - MsgId topicRootId, + FullReplyTo replyTo, MsgId replaceMediaOf) : peer(peer) , options(options) , replyTo(replyTo) - , topicRootId(topicRootId) , replaceMediaOf(replaceMediaOf) { } PeerId peer; Api::SendOptions options; - MsgId replyTo; - MsgId topicRootId; + FullReplyTo replyTo; MsgId replaceMediaOf; }; diff --git a/Telegram/SourceFiles/support/support_autocomplete.cpp b/Telegram/SourceFiles/support/support_autocomplete.cpp index 3ebec4074..aba4ee89a 100644 --- a/Telegram/SourceFiles/support/support_autocomplete.cpp +++ b/Telegram/SourceFiles/support/support_autocomplete.cpp @@ -276,7 +276,7 @@ AdminLog::OwnedItem GenerateCommentItem( const auto flags = MessageFlag::HasFromId | MessageFlag::Outgoing | MessageFlag::FakeHistoryItem; - const auto replyTo = MsgId(); + const auto replyTo = FullReplyTo(); const auto viaBotId = UserId(); const auto groupedId = uint64(); const auto item = history->makeMessage( @@ -298,7 +298,7 @@ AdminLog::OwnedItem GenerateContactItem( not_null delegate, not_null history, const Contact &data) { - const auto replyTo = MsgId(); + const auto replyTo = FullReplyTo(); const auto viaBotId = UserId(); const auto postAuthor = QString(); const auto groupedId = uint64(); diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index da8bc9a1f..2049d28d1 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -1113,13 +1113,16 @@ void Manager::notificationReplied( auto message = Api::MessageToSend(Api::SendAction(history)); message.textWithTags = reply; - message.action.replyTo = (id.msgId > 0 && !history->peer->isUser() + const auto replyToId = (id.msgId > 0 && !history->peer->isUser() && id.msgId != topicRootId) ? id.msgId : history->peer->isForum() ? topicRootId : MsgId(0); - message.action.topicRootId = topic ? topic->rootId() : 0; + message.action.replyTo = { + .msgId = replyToId, + .topicRootId = topic ? topic->rootId() : 0, + }; message.action.clearDraft = false; history->session().api().sendMessage(std::move(message)); diff --git a/Telegram/SourceFiles/window/themes/window_theme.cpp b/Telegram/SourceFiles/window/themes/window_theme.cpp index 64850eaef..c43996e6a 100644 --- a/Telegram/SourceFiles/window/themes/window_theme.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme.cpp @@ -1581,8 +1581,7 @@ SendMediaReady PrepareWallPaper(MTP::DcId dcId, const QImage &image) { MTP_photoEmpty(MTP_long(0)), thumbnails, document, - QByteArray(), - 0); + QByteArray()); } } // namespace Theme diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp index b045fb2de..46b5cf5fb 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_editor_box.cpp @@ -451,8 +451,7 @@ SendMediaReady PrepareThemeMedia( MTP_photoEmpty(MTP_long(0)), thumbnails, document, - thumbnailBytes, - 0); + thumbnailBytes); } Fn SavePreparedTheme( diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 3921a21cb..7b908dc47 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -108,21 +108,16 @@ void ShareBotGame( const auto topicRootId = replyTo; auto flags = MTPmessages_SendMedia::Flags(0); if (replyTo) { - flags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id; - if (topicRootId) { - flags |= MTPmessages_SendMedia::Flag::f_top_msg_id; - } + flags |= MTPmessages_SendMedia::Flag::f_reply_to; } histories.sendPreparedMessage( history, - replyTo, - topicRootId, + FullReplyTo{ .msgId = replyTo, .topicRootId = topicRootId }, randomId, Data::Histories::PrepareMessage( MTP_flags(flags), history->peer->input, Data::Histories::ReplyToPlaceholder(), - Data::Histories::TopicRootPlaceholder(), MTP_inputMediaGame( MTP_inputGameShortName( bot->inputUser, @@ -1447,8 +1442,7 @@ void PeerMenuCreatePoll( peer->owner().history(peer), result.options); action.clearDraft = false; - action.replyTo = replyToId; - action.topicRootId = topicRootId; + action.replyTo = { .msgId = replyToId, .topicRootId = topicRootId }; if (const auto local = action.history->localDraft(topicRootId)) { action.clearDraft = local->textWithTags.text.isEmpty(); }