diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index adbbf4d167..81dc2a4700 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -2455,6 +2455,7 @@ void ApiWrap::forwardMessages( } auto forwardFrom = items.front()->history()->peer; + auto currentGroupId = items.front()->groupId(); auto ids = QVector(); auto randomIds = QVector(); @@ -2462,8 +2463,12 @@ void ApiWrap::forwardMessages( if (shared) { ++shared->requestsLeft; } + const auto finalFlags = sendFlags + | (currentGroupId == MessageGroupId() + ? MTPmessages_ForwardMessages::Flag(0) + : MTPmessages_ForwardMessages::Flag::f_grouped); history->sendRequestId = request(MTPmessages_ForwardMessages( - MTP_flags(sendFlags), + MTP_flags(finalFlags), forwardFrom->input, MTP_vector(ids), MTP_vector(randomIds), @@ -2508,9 +2513,13 @@ void ApiWrap::forwardMessages( App::historyRegRandom(randomId, newId); } } - if (forwardFrom != item->history()->peer) { + const auto newFrom = item->history()->peer; + const auto newGroupId = item->groupId(); + if (forwardFrom != newFrom + || currentGroupId != newGroupId) { sendAccumulated(); - forwardFrom = item->history()->peer; + forwardFrom = newFrom; + currentGroupId = newGroupId; } ids.push_back(MTP_int(item->id)); randomIds.push_back(MTP_long(randomId)); diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp index 6b44166654..643a64d8d6 100644 --- a/Telegram/SourceFiles/auth_session.cpp +++ b/Telegram/SourceFiles/auth_session.cpp @@ -378,6 +378,13 @@ MessageIdsList AuthSessionData::itemsToIds( }) | ranges::to_vector; } +MessageIdsList AuthSessionData::groupToIds( + not_null group) const { + auto result = itemsToIds(group->others); + result.push_back(group->leader->fullId()); + return result; +} + AuthSession &Auth() { auto result = Messenger::Instance().authSession(); Assert(result != nullptr); diff --git a/Telegram/SourceFiles/auth_session.h b/Telegram/SourceFiles/auth_session.h index aa63710822..b7a8669251 100644 --- a/Telegram/SourceFiles/auth_session.h +++ b/Telegram/SourceFiles/auth_session.h @@ -263,6 +263,7 @@ public: HistoryItemsList idsToItems(const MessageIdsList &ids) const; MessageIdsList itemsToIds(const HistoryItemsList &items) const; + MessageIdsList groupToIds(not_null group) const; private: struct Variables { diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 5fd01d4fcf..4d8e5c1693 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -2465,17 +2465,6 @@ void HistoryInner::applyDragSelection() { applyDragSelection(&_selected); } -HistoryMessageGroup *HistoryInner::itemGroup( - not_null item) const { - if (const auto group = item->Get()) { - if (group->leader == item) { - return group; - } - return group->leader->Get(); - } - return nullptr; -} - bool HistoryInner::isSelected( not_null toItems, not_null item) const { @@ -2486,7 +2475,7 @@ bool HistoryInner::isSelected( bool HistoryInner::isSelectedAsGroup( not_null toItems, not_null item) const { - if (const auto group = itemGroup(item)) { + if (const auto group = item->getFullGroup()) { if (!isSelected(toItems, group->leader)) { return false; } @@ -2557,7 +2546,7 @@ void HistoryInner::changeSelectionAsGroup( not_null toItems, not_null item, SelectAction action) const { - const auto group = itemGroup(item); + const auto group = item->getFullGroup(); if (!group) { return changeSelection(toItems, item, action); } @@ -2598,7 +2587,7 @@ void HistoryInner::forwardItem(not_null item) { } void HistoryInner::forwardAsGroup(not_null item) { - if (const auto group = itemGroup(item)) { + if (const auto group = item->getFullGroup()) { auto items = Auth().data().itemsToIds(group->others); items.push_back(group->leader->fullId()); Window::ShowForwardMessagesBox(std::move(items)); @@ -2619,13 +2608,13 @@ void HistoryInner::deleteItem(not_null item) { } void HistoryInner::deleteAsGroup(not_null item) { - const auto group = itemGroup(item); + const auto group = item->getFullGroup(); if (!group || group->others.empty()) { return deleteItem(item); } auto items = Auth().data().itemsToIds(group->others); items.push_back(group->leader->fullId()); - Ui::show(Box(std::move(items))); + Ui::show(Box(Auth().data().groupToIds(group))); } void HistoryInner::addSelectionRange( diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index 0681b0d258..0501c22e51 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -227,7 +227,6 @@ private: using SelectedItems = std::map>; SelectedItems _selected; - HistoryMessageGroup *itemGroup(not_null item) const; void applyDragSelection(); void applyDragSelection(not_null toItems) const; void addSelectionRange( diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index b1ad869925..6fb9d33ee3 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -1198,6 +1198,16 @@ void HistoryItem::makeGroupLeader( Ensures(!isHiddenByGroup()); } +HistoryMessageGroup *HistoryItem::getFullGroup() { + if (const auto group = Get()) { + if (group->leader == this) { + return group; + } + return group->leader->Get(); + } + return nullptr; +} + void HistoryItem::resetGroupMedia( const std::vector> &others) { if (!others.empty()) { diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 02206086fe..815215aacc 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -972,6 +972,7 @@ public: } void makeGroupMember(not_null leader); void makeGroupLeader(std::vector> &&others); + HistoryMessageGroup *getFullGroup(); int width() const { return _width; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index d32f6189b4..d417399890 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -181,27 +181,28 @@ bool HasInlineItems(const HistoryItemsList &items) { void FastShareMessage(not_null item) { struct ShareData { - ShareData(const FullMsgId &msgId) : msgId(msgId) { + ShareData(not_null peer, MessageIdsList &&ids) + : peer(peer) + , msgIds(std::move(ids)) { } - FullMsgId msgId; - OrderedSet requests; + not_null peer; + MessageIdsList msgIds; + base::flat_set requests; }; - auto data = MakeShared(item->fullId()); - auto isGame = item->getMessageBot() + const auto data = MakeShared(item->history()->peer, [&] { + if (const auto group = item->getFullGroup()) { + return Auth().data().groupToIds(group); + } + return MessageIdsList(1, item->fullId()); + }()); + const auto isGame = item->getMessageBot() && item->getMedia() && (item->getMedia()->type() == MediaTypeGame); + const auto canCopyLink = item->hasDirectLink() || isGame; - auto canCopyLink = item->hasDirectLink(); - if (!canCopyLink) { - if (auto bot = item->getMessageBot()) { - if (auto media = item->getMedia()) { - canCopyLink = (media->type() == MediaTypeGame); - } - } - } auto copyCallback = [data]() { if (auto main = App::main()) { - if (auto item = App::histItemById(data->msgId)) { + if (auto item = App::histItemById(data->msgIds[0])) { if (item->hasDirectLink()) { QApplication::clipboard()->setText(item->directLink()); @@ -224,12 +225,11 @@ void FastShareMessage(not_null item) { if (!data->requests.empty()) { return; // Share clicked already. } - auto item = App::histItemById(data->msgId); - if (!item || result.empty()) { + auto items = Auth().data().idsToItems(data->msgIds); + if (items.empty() || result.empty()) { return; } - auto items = HistoryItemsList(1, item); auto restrictedSomewhere = false; auto restrictedEverywhere = true; auto firstError = QString(); @@ -262,16 +262,32 @@ void FastShareMessage(not_null item) { } }; - auto sendFlags = MTPmessages_ForwardMessages::Flag::f_with_my_score; - MTPVector msgIds = MTP_vector(1, MTP_int(data->msgId.msg)); + auto sendFlags = MTPmessages_ForwardMessages::Flag::f_with_my_score + | MTPmessages_ForwardMessages::Flag::f_grouped; + auto msgIds = QVector(); + msgIds.reserve(data->msgIds.size()); + for (const auto fullId : data->msgIds) { + msgIds.push_back(MTP_int(fullId.msg)); + } + auto generateRandom = [&] { + auto result = QVector(data->msgIds.size()); + for (auto &value : result) { + value = rand_value(); + } + return result; + }; if (auto main = App::main()) { for (const auto peer : result) { if (!GetErrorTextForForward(peer, items).isEmpty()) { continue; } - MTPVector random = MTP_vector(1, rand_value()); - auto request = MTPmessages_ForwardMessages(MTP_flags(sendFlags), item->history()->peer->input, msgIds, random, peer->input); + auto request = MTPmessages_ForwardMessages( + MTP_flags(sendFlags), + data->peer->input, + MTP_vector(msgIds), + MTP_vector(generateRandom()), + peer->input); auto callback = doneCallback; auto requestId = MTP::send(request, rpcDone(std::move(callback))); data->requests.insert(requestId); @@ -2361,7 +2377,7 @@ ClickHandlerPtr HistoryMessage::rightActionLink() const { Window::SectionShow::Way::Forward, savedFromMsgId); } else { - FastShareMessage(item->toHistoryMessage()); + FastShareMessage(item); } } }); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index c730f43453..547f07ffbe 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -610,6 +610,11 @@ bool MainWidget::setForwardDraft(PeerId peerId, ForwardWhatMessages what) { item = App::contextItem(); } else if (what == ForwardPressedMessage) { item = App::pressedItem(); + if (const auto group = item ? item->getFullGroup() : nullptr) { + if (item->id > 0) { + return Auth().data().groupToIds(group); + } + } } else if (what == ForwardPressedLinkMessage) { item = App::pressedLinkItem(); }