From 1c17432f70f9a163e2a1e239f8cbe18b14ea9d08 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 23 Oct 2025 11:58:38 +0400 Subject: [PATCH] Request and store top donors in video streams. --- .../calls/group/calls_group_messages.cpp | 40 +++++++++++++++++++ .../calls/group/calls_group_messages.h | 26 ++++++++++++ 2 files changed, 66 insertions(+) diff --git a/Telegram/SourceFiles/calls/group/calls_group_messages.cpp b/Telegram/SourceFiles/calls/group/calls_group_messages.cpp index 8d155dc521..10a34f8c26 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_messages.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_messages.cpp @@ -25,6 +25,29 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/ui_utility.h" namespace Calls::Group { +namespace { + +[[nodiscard]] StarsTop ParseStarsTop( + not_null owner, + const MTPphone_GroupCallStars &stars) { + const auto &data = stars.data(); + const auto &list = data.vtop_donors().v; + auto result = StarsTop{ .total = int(data.vtotal_stars().v) }; + result.topDonors.reserve(list.size()); + for (const auto &entry : list) { + const auto &fields = entry.data(); + result.topDonors.push_back({ + .peer = (fields.vpeer_id() + ? owner->peer(peerFromMTP(*fields.vpeer_id())).get() + : nullptr), + .stars = int(fields.vstars().v), + .my = fields.is_my(), + }); + } + return result; +} + +} // namespace Messages::Messages(not_null call, not_null api) : _call(call) @@ -41,6 +64,23 @@ Messages::Messages(not_null call, not_null api) Unexpected("Not ready call."); } }, _lifetime); + + _call->stateValue() | rpl::filter([=](GroupCall::State state) { + return (state == GroupCall::State::Joined); + }) | rpl::start_with_next([=] { + _api->request(base::take(_starsTopRequestId)).cancel(); + _starsTopRequestId = _api->request(MTPphone_GetGroupCallStars( + _call->inputCall() + )).done([=](const MTPphone_GroupCallStars &result) { + const auto &data = result.data(); + + const auto owner = &_call->peer()->owner(); + owner->processUsers(data.vusers()); + owner->processChats(data.vchats()); + + _starsTop = ParseStarsTop(owner, result); + }).send(); + }, _lifetime); }); } diff --git a/Telegram/SourceFiles/calls/group/calls_group_messages.h b/Telegram/SourceFiles/calls/group/calls_group_messages.h index dd48546c81..15eb7dd441 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_messages.h +++ b/Telegram/SourceFiles/calls/group/calls_group_messages.h @@ -39,6 +39,25 @@ struct MessageIdUpdate { MsgId realId = 0; }; +struct StarsTopDonor { + PeerData *peer = nullptr; + int stars = 0; + bool my = false; + + friend inline bool operator==( + const StarsTopDonor &, + const StarsTopDonor &) = default; +}; + +struct StarsTop { + std::vector topDonors; + int total = 0; + + friend inline bool operator==( + const StarsTop &, + const StarsTop &) = default; +}; + class Messages final : public base::has_weak_ptr { public: Messages(not_null call, not_null api); @@ -53,6 +72,10 @@ public: [[nodiscard]] rpl::producer> listValue() const; [[nodiscard]] rpl::producer idUpdates() const; + [[nodiscard]] rpl::producer starsTopValue() const { + return _starsTop.value(); + } + private: struct Pending { TextWithTags text; @@ -91,6 +114,9 @@ private: rpl::event_stream> _changes; rpl::event_stream _idUpdates; + mtpRequestId _starsTopRequestId = 0; + rpl::variable _starsTop; + TimeId _ttl = 0; bool _changesScheduled = false;