Request one participants slice on voice chat reload.

This commit is contained in:
John Preston 2021-03-18 16:58:05 +04:00
parent 3fea9cca08
commit 00d65fa978
3 changed files with 110 additions and 45 deletions

View File

@ -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<PeerData*> 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<MTPInputPeer>(), // ids
MTP_vector<MTPint>(), // 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<MTPGroupCallParticipant> &list,
ApplySliceSource sliceSource) {

View File

@ -42,6 +42,7 @@ public:
~GroupCall();
[[nodiscard]] uint64 id() const;
[[nodiscard]] bool loaded() const;
[[nodiscard]] not_null<PeerData*> 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<std::pair<int,bool>, MTPUpdate> _queuedUpdates;
base::Timer _reloadByQueuedUpdatesTimer;
std::optional<MTPphone_GroupCall> _savedFull;
std::vector<Participant> _participants;
base::flat_map<uint32, not_null<PeerData*>> _participantPeerBySsrc;

View File

@ -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;
}