From 00d65fa9786a81aee4e6d80ef2b8dd5ad5ef7f8d Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 18 Mar 2021 16:58:05 +0400 Subject: [PATCH] Request one participants slice on voice chat reload. --- Telegram/SourceFiles/data/data_group_call.cpp | 99 ++++++++++++++----- Telegram/SourceFiles/data/data_group_call.h | 8 ++ .../window/window_session_controller.cpp | 48 +++++---- 3 files changed, 110 insertions(+), 45 deletions(-) diff --git a/Telegram/SourceFiles/data/data_group_call.cpp b/Telegram/SourceFiles/data/data_group_call.cpp index d4e0b6c70f..e7bf02d0b8 100644 --- a/Telegram/SourceFiles/data/data_group_call.cpp +++ b/Telegram/SourceFiles/data/data_group_call.cpp @@ -27,6 +27,12 @@ constexpr auto kSpeakingAfterActive = crl::time(6000); constexpr auto kActiveAfterJoined = crl::time(1000); constexpr auto kWaitForUpdatesTimeout = 3 * crl::time(1000); +[[nodiscard]] QString ExtractNextOffset(const MTPphone_GroupCall &call) { + return call.match([&](const MTPDphone_groupCall &data) { + return qs(data.vparticipants_next_offset()); + }); +} + } // namespace GroupCall::GroupCall( @@ -50,6 +56,10 @@ uint64 GroupCall::id() const { return _id; } +bool GroupCall::loaded() const { + return _version > 0; +} + not_null GroupCall::peer() const { return _peer; } @@ -71,18 +81,24 @@ auto GroupCall::participants() const } void GroupCall::requestParticipants() { - if (_participantsRequestId || _reloadRequestId) { - return; - } else if (_allParticipantsLoaded) { - return; + if (!_savedFull) { + if (_participantsRequestId || _reloadRequestId) { + return; + } else if (_allParticipantsLoaded) { + return; + } } _participantsRequestId = api().request(MTPphone_GetGroupParticipants( input(), MTP_vector(), // ids MTP_vector(), // ssrcs - MTP_string(_nextOffset), + MTP_string(_savedFull + ? ExtractNextOffset(*_savedFull) + : _nextOffset), MTP_int(kRequestPerPage) )).done([=](const MTPphone_GroupParticipants &result) { + _participantsRequestId = 0; + processSavedFullCall(); result.match([&](const MTPDphone_groupParticipants &data) { _nextOffset = qs(data.vnext_offset()); _peer->owner().processUsers(data.vusers()); @@ -94,20 +110,31 @@ void GroupCall::requestParticipants() { if (data.vparticipants().v.isEmpty()) { _allParticipantsLoaded = true; } - computeParticipantsCount(); - _participantsSliceAdded.fire({}); - _participantsRequestId = 0; - processQueuedUpdates(); + finishParticipantsSliceRequest(); }); }).fail([=](const MTP::Error &error) { + _participantsRequestId = 0; + processSavedFullCall(); setServerParticipantsCount(_participants.size()); _allParticipantsLoaded = true; - computeParticipantsCount(); - _participantsRequestId = 0; - processQueuedUpdates(); + finishParticipantsSliceRequest(); }).send(); } +void GroupCall::processSavedFullCall() { + if (!_savedFull) { + return; + } + _reloadRequestId = 0; + processFullCallFields(*base::take(_savedFull)); +} + +void GroupCall::finishParticipantsSliceRequest() { + computeParticipantsCount(); + processQueuedUpdates(); + _participantsSliceAdded.fire({}); +} + void GroupCall::setServerParticipantsCount(int count) { _serverParticipantsCount = count; changePeerEmptyCallFlag(); @@ -237,20 +264,18 @@ void GroupCall::discard() { }); } -void GroupCall::processFullCall(const MTPphone_GroupCall &call) { +void GroupCall::processFullCallUsersChats(const MTPphone_GroupCall &call) { call.match([&](const MTPDphone_groupCall &data) { _peer->owner().processUsers(data.vusers()); _peer->owner().processChats(data.vchats()); + }); +} + +void GroupCall::processFullCallFields(const MTPphone_GroupCall &call) { + call.match([&](const MTPDphone_groupCall &data) { const auto &participants = data.vparticipants().v; const auto nextOffset = qs(data.vparticipants_next_offset()); data.vcall().match([&](const MTPDgroupCall &data) { - if (data.vversion().v == _version - && data.vparticipants_count().v == _serverParticipantsCount - && (_serverParticipantsCount >= _participants.size()) - && (!_allParticipantsLoaded - || _serverParticipantsCount == _participants.size())) { - return; - } _participants.clear(); _speakingByActiveFinishes.clear(); _participantPeerBySsrc.clear(); @@ -262,15 +287,18 @@ void GroupCall::processFullCall(const MTPphone_GroupCall &call) { _nextOffset = nextOffset; applyCallFields(data); - - _participantsSliceAdded.fire({}); }, [&](const MTPDgroupCallDiscarded &data) { discard(); }); - processQueuedUpdates(); }); } +void GroupCall::processFullCall(const MTPphone_GroupCall &call) { + processFullCallUsersChats(call); + processFullCallFields(call); + finishParticipantsSliceRequest(); +} + void GroupCall::applyCallFields(const MTPDgroupCall &data) { DEBUG_LOG(("Group Call Participants: " "Set from groupCall %1 -> %2" @@ -290,8 +318,6 @@ void GroupCall::applyCallFields(const MTPDgroupCall &data) { _recordStartDate = data.vrecord_start_date().value_or_empty(); _allParticipantsLoaded = (_serverParticipantsCount == _participants.size()); - computeParticipantsCount(); - processQueuedUpdates(); } void GroupCall::applyLocalUpdate( @@ -305,6 +331,8 @@ void GroupCall::applyUpdate(const MTPUpdate &update) { update.match([&](const MTPDupdateGroupCall &data) { data.vcall().match([&](const MTPDgroupCall &data) { applyCallFields(data); + computeParticipantsCount(); + processQueuedUpdates(); }, [&](const MTPDgroupCallDiscarded &data) { discard(); }); @@ -389,13 +417,32 @@ void GroupCall::reload() { _reloadRequestId = api().request( MTPphone_GetGroupCall(input()) ).done([=](const MTPphone_GroupCall &result) { - processFullCall(result); + if (requestParticipantsAfterReload(result)) { + _savedFull = result; + processFullCallUsersChats(result); + requestParticipants(); + return; + } _reloadRequestId = 0; + processFullCall(result); }).fail([=](const MTP::Error &error) { _reloadRequestId = 0; }).send(); } +bool GroupCall::requestParticipantsAfterReload( + const MTPphone_GroupCall &call) const { + return call.match([&](const MTPDphone_groupCall &data) { + const auto received = data.vparticipants().v.size(); + const auto size = data.vcall().match([&](const MTPDgroupCall &data) { + return data.vparticipants_count().v; + }, [](const auto &) { + return 0; + }); + return (received < size) && (received < _participants.size()); + }); +} + void GroupCall::applyParticipantsSlice( const QVector &list, ApplySliceSource sliceSource) { diff --git a/Telegram/SourceFiles/data/data_group_call.h b/Telegram/SourceFiles/data/data_group_call.h index 666fad4628..8d1974a2b1 100644 --- a/Telegram/SourceFiles/data/data_group_call.h +++ b/Telegram/SourceFiles/data/data_group_call.h @@ -42,6 +42,7 @@ public: ~GroupCall(); [[nodiscard]] uint64 id() const; + [[nodiscard]] bool loaded() const; [[nodiscard]] not_null peer() const; [[nodiscard]] MTPInputGroupCall input() const; [[nodiscard]] QString title() const { @@ -127,6 +128,12 @@ private: void setServerParticipantsCount(int count); void computeParticipantsCount(); void processQueuedUpdates(); + void processFullCallUsersChats(const MTPphone_GroupCall &call); + void processFullCallFields(const MTPphone_GroupCall &call); + [[nodiscard]] bool requestParticipantsAfterReload( + const MTPphone_GroupCall &call) const; + void processSavedFullCall(); + void finishParticipantsSliceRequest(); const uint64 _id = 0; const uint64 _accessHash = 0; @@ -139,6 +146,7 @@ private: base::flat_multi_map, MTPUpdate> _queuedUpdates; base::Timer _reloadByQueuedUpdatesTimer; + std::optional _savedFull; std::vector _participants; base::flat_map> _participantPeerBySsrc; diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index d6a2cdd61b..0d3de47edc 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -190,27 +190,37 @@ void SessionNavigation::showPeerByLinkResolved( MTPchannels_GetFullChannel(peer->asChannel()->inputChannel) ).done([=](const MTPmessages_ChatFull &result) { _session->api().processFullPeer(peer, result); - if (const auto call = peer->groupCall()) { - const auto id = call->id(); - _resolveRequestId = _session->api().request( - MTPphone_GetGroupCall(call->input()) - ).done([=](const MTPphone_GroupCall &result) { - if (const auto now = peer->groupCall() - ; now && now->id() == id) { - now->processFullCall(result); - parentController()->startOrJoinGroupCall( - peer, - hash, - SessionController::GroupCallJoinConfirm::Always); - } else { - bad(); - } - }).fail([=](const MTP::Error &error) { - bad(); - }).send(); - } else { + const auto call = peer->groupCall(); + if (!call) { bad(); + return; } + const auto join = [=] { + parentController()->startOrJoinGroupCall( + peer, + hash, + SessionController::GroupCallJoinConfirm::Always); + }; + if (call->loaded()) { + join(); + return; + } + const auto id = call->id(); + _resolveRequestId = _session->api().request( + MTPphone_GetGroupCall(call->input()) + ).done([=](const MTPphone_GroupCall &result) { + if (const auto now = peer->groupCall() + ; now && now->id() == id) { + if (!now->loaded()) { + now->processFullCall(result); + } + join(); + } else { + bad(); + } + }).fail([=](const MTP::Error &error) { + bad(); + }).send(); }).send(); return; }