diff --git a/Telegram/SourceFiles/main/session/send_as_peers.cpp b/Telegram/SourceFiles/main/session/send_as_peers.cpp index 3614cbcfd..e8bdaf0a2 100644 --- a/Telegram/SourceFiles/main/session/send_as_peers.cpp +++ b/Telegram/SourceFiles/main/session/send_as_peers.cpp @@ -23,7 +23,8 @@ constexpr auto kRequestEach = 30 * crl::time(1000); SendAsPeers::SendAsPeers(not_null session) : _session(session) -, _onlyMe({ { .peer = session->user(), .premiumRequired = false } }) { +, _onlyMe({ { .peer = session->user(), .premiumRequired = false } }) +, _onlyMePaid({ session->user() }) { _session->changes().peerUpdates( Data::PeerUpdate::Flag::Rights ) | rpl::map([=](const Data::PeerUpdate &update) { @@ -65,6 +66,7 @@ void SendAsPeers::refresh(not_null peer, bool force) { } _lastRequestTime[peer] = now; request(peer); + request(peer, true); } const std::vector &SendAsPeers::list( @@ -73,15 +75,10 @@ const std::vector &SendAsPeers::list( return (i != end(_lists)) ? i->second : _onlyMe; } -std::vector> SendAsPeers::paidReactionList() const { - auto result = std::vector>(); - const auto owner = &_session->data(); - owner->enumerateBroadcasts([&](not_null channel) { - if (channel->amCreator() && !ranges::contains(result, channel)) { - result.push_back(channel); - } - }); - return result; +const std::vector> &SendAsPeers::paidReactionList( + not_null peer) const { + const auto i = _paidReactionLists.find(peer); + return (i != end(_paidReactionLists)) ? i->second : _onlyMePaid; } rpl::producer> SendAsPeers::updated() const { @@ -144,8 +141,10 @@ not_null SendAsPeers::ResolveChosen( : fallback; } -void SendAsPeers::request(not_null peer) { +void SendAsPeers::request(not_null peer, bool forPaidReactions) { + using Flag = MTPchannels_GetSendAs::Flag; peer->session().api().request(MTPchannels_GetSendAs( + MTP_flags(forPaidReactions ? Flag::f_for_paid_reactions : Flag()), peer->input )).done([=](const MTPchannels_SendAsPeers &result) { auto parsed = std::vector(); @@ -166,15 +165,26 @@ void SendAsPeers::request(not_null peer) { } } }); - if (parsed.size() > 1) { - auto &now = _lists[peer]; - if (now != parsed) { - now = std::move(parsed); + if (forPaidReactions) { + auto peers = parsed | ranges::views::transform( + &SendAsPeer::peer + ) | ranges::to_vector; + if (!peers.empty()) { + _paidReactionLists[peer] = std::move(peers); + } else { + _paidReactionLists.remove(peer); + } + } else { + if (parsed.size() > 1) { + auto &now = _lists[peer]; + if (now != parsed) { + now = std::move(parsed); + _updates.fire_copy(peer); + } + } else if (const auto i = _lists.find(peer); i != end(_lists)) { + _lists.erase(i); _updates.fire_copy(peer); } - } else if (const auto i = _lists.find(peer); i != end(_lists)) { - _lists.erase(i); - _updates.fire_copy(peer); } }).send(); } diff --git a/Telegram/SourceFiles/main/session/send_as_peers.h b/Telegram/SourceFiles/main/session/send_as_peers.h index 54de4522b..9f831955e 100644 --- a/Telegram/SourceFiles/main/session/send_as_peers.h +++ b/Telegram/SourceFiles/main/session/send_as_peers.h @@ -34,7 +34,8 @@ public: void setChosen(not_null peer, PeerId chosenId); [[nodiscard]] PeerId chosen(not_null peer) const; - [[nodiscard]] std::vector> paidReactionList() const; + [[nodiscard]] const std::vector> &paidReactionList( + not_null peer) const; // If !list(peer).empty() then the result will be from that list. [[nodiscard]] not_null resolveChosen( @@ -46,14 +47,18 @@ public: PeerId chosen); private: - void request(not_null peer); + void request(not_null peer, bool forPaidReactions = false); const not_null _session; const std::vector _onlyMe; + const std::vector> _onlyMePaid; base::flat_map, std::vector> _lists; base::flat_map, crl::time> _lastRequestTime; base::flat_map, PeerId> _chosen; + base::flat_map< + not_null, + std::vector>> _paidReactionLists; rpl::event_stream> _updates; diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 560bf29ad..b2d27fd06 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -2428,7 +2428,7 @@ channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint addr channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates; channels.getInactiveChannels#11e831ee = messages.InactiveChats; channels.convertToGigagroup#b290c69 channel:InputChannel = Updates; -channels.getSendAs#dc770ee peer:InputPeer = channels.SendAsPeers; +channels.getSendAs#e785a43f flags:# for_paid_reactions:flags.0?true peer:InputPeer = channels.SendAsPeers; channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory; channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates; channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates; diff --git a/Telegram/SourceFiles/payments/payments_reaction_process.cpp b/Telegram/SourceFiles/payments/payments_reaction_process.cpp index 783e135d8..94d527471 100644 --- a/Telegram/SourceFiles/payments/payments_reaction_process.cpp +++ b/Telegram/SourceFiles/payments/payments_reaction_process.cpp @@ -213,7 +213,9 @@ void ShowPaidReactionDetails( .my = (entry.my == 1), }); }; - const auto channels = session->sendAsPeers().paidReactionList(); + const auto linked = item->discussionPostOriginalSender(); + const auto channel = (linked ? linked : item->history()->peer.get()); + const auto channels = session->sendAsPeers().paidReactionList(channel); const auto topPaid = item->topPaidReactionsWithLocal(); top.reserve(topPaid.size() + 2 + channels.size()); for (const auto &entry : topPaid) { @@ -248,8 +250,6 @@ void ShowPaidReactionDetails( } ranges::stable_sort(top, ranges::greater(), &Ui::PaidReactionTop::count); - const auto linked = item->discussionPostOriginalSender(); - const auto channel = (linked ? linked : item->history()->peer.get()); state->selectBox = show->show(Ui::MakePaidReactionBox({ .chosen = chosen, .max = max,