Load unknown participants by source.

This commit is contained in:
John Preston 2020-11-29 18:18:51 +03:00
parent cf8e45ab61
commit e66ad89a2a
3 changed files with 105 additions and 25 deletions

View file

@ -465,9 +465,6 @@ void MembersController::updateRow(
// if (const auto row = findRow(user)) { // if (const auto row = findRow(user)) {
// const auto result = row->updateLevel(level); // const auto result = row->updateLevel(level);
// if (result.stateChanged) { // if (result.stateChanged) {
// // #TODO calls reorder.
// }
// if (result.stateChanged) {
// delegate()->peerListUpdateRow(row); // delegate()->peerListUpdateRow(row);
// } // }
// if (result.nextUpdateTime) { // if (result.nextUpdateTime) {

View file

@ -31,8 +31,9 @@ GroupCall::GroupCall(
} }
GroupCall::~GroupCall() { GroupCall::~GroupCall() {
_channel->session().api().request(_participantsRequestId).cancel(); api().request(_unknownSourcesRequestId).cancel();
_channel->session().api().request(_reloadRequestId).cancel(); api().request(_participantsRequestId).cancel();
api().request(_reloadRequestId).cancel();
} }
uint64 GroupCall::id() const { uint64 GroupCall::id() const {
@ -61,8 +62,7 @@ void GroupCall::requestParticipants() {
reload(); reload();
return; return;
} }
auto &api = _channel->session().api(); _participantsRequestId = api().request(MTPphone_GetGroupParticipants(
_participantsRequestId = api.request(MTPphone_GetGroupParticipants(
input(), input(),
MTP_vector<MTPint>(), // ids MTP_vector<MTPint>(), // ids
MTP_vector<MTPint>(), // sources MTP_vector<MTPint>(), // sources
@ -72,7 +72,9 @@ void GroupCall::requestParticipants() {
result.match([&](const MTPDphone_groupParticipants &data) { result.match([&](const MTPDphone_groupParticipants &data) {
_nextOffset = qs(data.vnext_offset()); _nextOffset = qs(data.vnext_offset());
_channel->owner().processUsers(data.vusers()); _channel->owner().processUsers(data.vusers());
applyParticipantsSlice(data.vparticipants().v); applyParticipantsSlice(
data.vparticipants().v,
ApplySliceSource::SliceLoaded);
_fullCount = data.vcount().v; _fullCount = data.vcount().v;
if (!_allReceived if (!_allReceived
&& (data.vparticipants().v.size() < kRequestPerPage)) { && (data.vparticipants().v.size() < kRequestPerPage)) {
@ -152,16 +154,19 @@ void GroupCall::reload() {
if (_reloadRequestId) { if (_reloadRequestId) {
return; return;
} else if (_participantsRequestId) { } else if (_participantsRequestId) {
_channel->session().api().request(_participantsRequestId).cancel(); api().request(_participantsRequestId).cancel();
_participantsRequestId = 0; _participantsRequestId = 0;
} }
_reloadRequestId = _channel->session().api().request( _reloadRequestId = api().request(
MTPphone_GetGroupCall(input()) MTPphone_GetGroupCall(input())
).done([=](const MTPphone_GroupCall &result) { ).done([=](const MTPphone_GroupCall &result) {
result.match([&](const MTPDphone_groupCall &data) { result.match([&](const MTPDphone_groupCall &data) {
_channel->owner().processUsers(data.vusers()); _channel->owner().processUsers(data.vusers());
_participants.clear(); _participants.clear();
applyParticipantsSlice(data.vparticipants().v); _userBySource.clear();
applyParticipantsSlice(
data.vparticipants().v,
ApplySliceSource::SliceLoaded);
applyCall(data.vcall(), true); applyCall(data.vcall(), true);
_allReceived = (_fullCount.current() == _participants.size()); _allReceived = (_fullCount.current() == _participants.size());
_participantsSliceAdded.fire({}); _participantsSliceAdded.fire({});
@ -174,8 +179,11 @@ void GroupCall::reload() {
void GroupCall::applyParticipantsSlice( void GroupCall::applyParticipantsSlice(
const QVector<MTPGroupCallParticipant> &list, const QVector<MTPGroupCallParticipant> &list,
bool sendIndividualUpdates) { ApplySliceSource sliceSource) {
auto fullCount = _fullCount.current(); if (sliceSource != ApplySliceSource::UnknownLoaded) {
return;
}
auto changedCount = _fullCount.current();
for (const auto &participant : list) { for (const auto &participant : list) {
participant.match([&](const MTPDgroupCallParticipant &data) { participant.match([&](const MTPDgroupCallParticipant &data) {
const auto userId = data.vuser_id().v; const auto userId = data.vuser_id().v;
@ -191,12 +199,12 @@ void GroupCall::applyParticipantsSlice(
}; };
_userBySource.erase(i->source); _userBySource.erase(i->source);
_participants.erase(i); _participants.erase(i);
if (sendIndividualUpdates) { if (sliceSource != ApplySliceSource::SliceLoaded) {
_participantUpdates.fire(std::move(update)); _participantUpdates.fire(std::move(update));
} }
} }
if (fullCount > _participants.size()) { if (changedCount > _participants.size()) {
--fullCount; --changedCount;
} }
return; return;
} }
@ -216,7 +224,7 @@ void GroupCall::applyParticipantsSlice(
_userBySource.emplace(value.source, user); _userBySource.emplace(value.source, user);
_participants.push_back(value); _participants.push_back(value);
_channel->owner().unregisterInvitedToCallUser(_id, user); _channel->owner().unregisterInvitedToCallUser(_id, user);
++fullCount; ++changedCount;
} else { } else {
if (i->source != value.source) { if (i->source != value.source) {
_userBySource.erase(i->source); _userBySource.erase(i->source);
@ -224,13 +232,17 @@ void GroupCall::applyParticipantsSlice(
} }
*i = value; *i = value;
} }
_participantUpdates.fire({ if (sliceSource != ApplySliceSource::SliceLoaded) {
.was = was, _participantUpdates.fire({
.now = value, .was = was,
}); .now = value,
});
}
}); });
} }
_fullCount = fullCount; if (sliceSource == ApplySliceSource::UpdateReceived) {
_fullCount = changedCount;
}
} }
void GroupCall::applyParticipantsMutes( void GroupCall::applyParticipantsMutes(
@ -265,7 +277,8 @@ void GroupCall::applyParticipantsMutes(
void GroupCall::applyLastSpoke(uint32 source, crl::time when, crl::time now) { void GroupCall::applyLastSpoke(uint32 source, crl::time when, crl::time now) {
const auto i = _userBySource.find(source); const auto i = _userBySource.find(source);
if (i == end(_userBySource)) { if (i == end(_userBySource)) {
// #TODO calls load participant by source from server. _unknownSpokenSources.emplace(source, when);
requestUnknownSources();
return; return;
} }
const auto j = ranges::find(_participants, i->second, &Participant::user); const auto j = ranges::find(_participants, i->second, &Participant::user);
@ -282,6 +295,57 @@ void GroupCall::applyLastSpoke(uint32 source, crl::time when, crl::time now) {
} }
} }
void GroupCall::requestUnknownSources() {
if (_unknownSourcesRequestId || _unknownSpokenSources.empty()) {
return;
}
const auto sources = [&] {
if (_unknownSpokenSources.size() < kRequestPerPage) {
return base::take(_unknownSpokenSources);
}
auto result = base::flat_map<uint32, crl::time>();
result.reserve(kRequestPerPage);
while (result.size() < kRequestPerPage) {
const auto [source, when] = _unknownSpokenSources.back();
result.emplace(source, when);
_unknownSpokenSources.erase(_unknownSpokenSources.end() - 1);
}
return result;
}();
auto sourceInputs = QVector<MTPint>();
sourceInputs.reserve(sources.size());
for (const auto [source, when] : sources) {
sourceInputs.push_back(MTP_int(source));
}
_unknownSourcesRequestId = api().request(MTPphone_GetGroupParticipants(
input(),
MTP_vector<MTPint>(), // ids
MTP_vector<MTPint>(sourceInputs),
MTP_string(QString()),
MTP_int(kRequestPerPage)
)).done([=](const MTPphone_GroupParticipants &result) {
result.match([&](const MTPDphone_groupParticipants &data) {
_channel->owner().processUsers(data.vusers());
applyParticipantsSlice(
data.vparticipants().v,
ApplySliceSource::UnknownLoaded);
});
_unknownSourcesRequestId = 0;
const auto now = crl::now();
for (const auto [source, when] : sources) {
applyLastSpoke(source, when, now);
_unknownSpokenSources.remove(source);
}
requestUnknownSources();
}).fail([=](const RPCError &error) {
_unknownSourcesRequestId = 0;
for (const auto [source, when] : sources) {
_unknownSpokenSources.remove(source);
}
requestUnknownSources();
}).send();
}
void GroupCall::applyUpdate(const MTPDupdateGroupCallParticipants &update) { void GroupCall::applyUpdate(const MTPDupdateGroupCallParticipants &update) {
const auto version = update.vversion().v; const auto version = update.vversion().v;
if (version < _version) { if (version < _version) {
@ -300,7 +364,9 @@ void GroupCall::applyUpdate(const MTPDupdateGroupCallParticipants &update) {
void GroupCall::applyUpdateChecked( void GroupCall::applyUpdateChecked(
const MTPDupdateGroupCallParticipants &update) { const MTPDupdateGroupCallParticipants &update) {
applyParticipantsSlice(update.vparticipants().v, true); applyParticipantsSlice(
update.vparticipants().v,
ApplySliceSource::UpdateReceived);
} }
void GroupCall::setJoinMutedLocally(bool muted) { void GroupCall::setJoinMutedLocally(bool muted) {
@ -315,4 +381,8 @@ bool GroupCall::canChangeJoinMuted() const {
return _canChangeJoinMuted; return _canChangeJoinMuted;
} }
ApiWrap &GroupCall::api() const {
return _channel->session().api();
}
} // namespace Data } // namespace Data

View file

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class UserData; class UserData;
class ChannelData; class ChannelData;
class ApiWrap;
namespace Data { namespace Data {
class GroupCall final { class GroupCall final {
@ -60,12 +62,20 @@ public:
[[nodiscard]] bool canChangeJoinMuted() const; [[nodiscard]] bool canChangeJoinMuted() const;
private: private:
enum class ApplySliceSource {
SliceLoaded,
UnknownLoaded,
UpdateReceived,
};
[[nodiscard]] ApiWrap &api() const;
void applyCall(const MTPGroupCall &call, bool force); void applyCall(const MTPGroupCall &call, bool force);
void applyParticipantsSlice( void applyParticipantsSlice(
const QVector<MTPGroupCallParticipant> &list, const QVector<MTPGroupCallParticipant> &list,
bool sendIndividualUpdates = false); ApplySliceSource sliceSource);
void applyParticipantsMutes( void applyParticipantsMutes(
const MTPDupdateGroupCallParticipants &update); const MTPDupdateGroupCallParticipants &update);
void requestUnknownSources();
const not_null<ChannelData*> _channel; const not_null<ChannelData*> _channel;
const uint64 _id = 0; const uint64 _id = 0;
@ -80,6 +90,9 @@ private:
QString _nextOffset; QString _nextOffset;
rpl::variable<int> _fullCount = 0; rpl::variable<int> _fullCount = 0;
base::flat_map<uint32, crl::time> _unknownSpokenSources;
mtpRequestId _unknownSourcesRequestId = 0;
rpl::event_stream<ParticipantUpdate> _participantUpdates; rpl::event_stream<ParticipantUpdate> _participantUpdates;
rpl::event_stream<> _participantsSliceAdded; rpl::event_stream<> _participantsSliceAdded;