mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Apply group call updates.
This commit is contained in:
parent
33941ad1b9
commit
25f3c14780
9 changed files with 357 additions and 61 deletions
|
@ -191,6 +191,7 @@ private:
|
|||
Ended,
|
||||
Failed,
|
||||
};
|
||||
|
||||
void handleRequestError(const RPCError &error);
|
||||
void handleControllerError(const QString &error);
|
||||
void finish(
|
||||
|
|
|
@ -25,7 +25,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
//#include "calls/calls_panel.h"
|
||||
//#include "webrtc/webrtc_video_track.h"
|
||||
//#include "webrtc/webrtc_media_devices.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_group_call.h"
|
||||
//#include "data/data_session.h"
|
||||
//#include "facades.h"
|
||||
|
||||
|
@ -49,6 +51,7 @@ GroupCall::GroupCall(
|
|||
, _channel(channel)
|
||||
, _api(&_channel->session().mtp()) {
|
||||
if (inputCall.c_inputGroupCall().vid().v) {
|
||||
_state = State::Joining;
|
||||
join(inputCall);
|
||||
} else {
|
||||
start();
|
||||
|
@ -59,19 +62,51 @@ GroupCall::~GroupCall() {
|
|||
destroyController();
|
||||
}
|
||||
|
||||
void GroupCall::setState(State state) {
|
||||
if (_state.current() == State::Failed) {
|
||||
return;
|
||||
} else if (_state.current() == State::FailedHangingUp
|
||||
&& state != State::Failed) {
|
||||
return;
|
||||
}
|
||||
if (_state.current() == state) {
|
||||
return;
|
||||
}
|
||||
_state = state;
|
||||
|
||||
if (false
|
||||
|| state == State::Ended
|
||||
|| state == State::Failed) {
|
||||
// Destroy controller before destroying Call Panel,
|
||||
// so that the panel hide animation is smooth.
|
||||
destroyController();
|
||||
}
|
||||
switch (state) {
|
||||
case State::Ended:
|
||||
_delegate->groupCallFinished(this);
|
||||
break;
|
||||
case State::Failed:
|
||||
_delegate->groupCallFailed(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GroupCall::start() {
|
||||
const auto randomId = rand_value<int32>();
|
||||
_api.request(MTPphone_CreateGroupCall(
|
||||
_channel->inputChannel,
|
||||
MTP_int(randomId)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
_acceptFields = true;
|
||||
_channel->session().api().applyUpdates(result);
|
||||
_acceptFields = false;
|
||||
}).fail([=](const RPCError &error) {
|
||||
int a = error.code();
|
||||
}).send();
|
||||
}
|
||||
|
||||
void GroupCall::join(const MTPInputGroupCall &inputCall) {
|
||||
setState(State::Joining);
|
||||
inputCall.match([&](const MTPDinputGroupCall &data) {
|
||||
_id = data.vid().v;
|
||||
_accessHash = data.vaccess_hash().v;
|
||||
|
@ -91,10 +126,11 @@ void GroupCall::join(const MTPInputGroupCall &inputCall) {
|
|||
}
|
||||
|
||||
auto root = QJsonObject();
|
||||
const auto ssrc = payload.ssrc;
|
||||
root.insert("ufrag", QString::fromStdString(payload.ufrag));
|
||||
root.insert("pwd", QString::fromStdString(payload.pwd));
|
||||
root.insert("fingerprints", fingerprints);
|
||||
root.insert("ssrc", int(payload.ssrc));
|
||||
root.insert("ssrc", double(payload.ssrc));
|
||||
|
||||
const auto json = QJsonDocument(root).toJson(
|
||||
QJsonDocument::Compact);
|
||||
|
@ -105,6 +141,9 @@ void GroupCall::join(const MTPInputGroupCall &inputCall) {
|
|||
inputCall,
|
||||
MTP_dataJSON(MTP_bytes(json))
|
||||
)).done([=](const MTPUpdates &updates) {
|
||||
_mySsrc = ssrc;
|
||||
setState(State::Joined);
|
||||
|
||||
_channel->session().api().applyUpdates(updates);
|
||||
}).fail([=](const RPCError &error) {
|
||||
int a = error.code();
|
||||
|
@ -112,6 +151,77 @@ void GroupCall::join(const MTPInputGroupCall &inputCall) {
|
|||
});
|
||||
});
|
||||
});
|
||||
_channel->setCall(inputCall);
|
||||
|
||||
_channel->session().changes().peerFlagsValue(
|
||||
_channel,
|
||||
Data::PeerUpdate::Flag::GroupCall
|
||||
) | rpl::start_with_next([=] {
|
||||
checkParticipants();
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
void GroupCall::checkParticipants() {
|
||||
if (!joined()) {
|
||||
return;
|
||||
}
|
||||
const auto call = _channel->call();
|
||||
if (!call || call->id() != _id) {
|
||||
finish(FinishType::Ended);
|
||||
return;
|
||||
}
|
||||
const auto &sources = call->sources();
|
||||
if (sources.size() != call->fullCount() || sources.empty()) {
|
||||
call->reload();
|
||||
return;
|
||||
}
|
||||
auto ssrcs = std::vector<uint32_t>();
|
||||
ssrcs.reserve(sources.size());
|
||||
for (const auto source : sources) {
|
||||
if (source != _mySsrc) {
|
||||
ssrcs.push_back(source);
|
||||
}
|
||||
}
|
||||
_instance->setSsrcs(std::move(ssrcs));
|
||||
_instance->setIsMuted(false);
|
||||
}
|
||||
|
||||
void GroupCall::hangup() {
|
||||
finish(FinishType::Ended);
|
||||
}
|
||||
|
||||
void GroupCall::finish(FinishType type) {
|
||||
Expects(type != FinishType::None);
|
||||
|
||||
const auto finalState = (type == FinishType::Ended)
|
||||
? State::Ended
|
||||
: State::Failed;
|
||||
const auto hangupState = (type == FinishType::Ended)
|
||||
? State::HangingUp
|
||||
: State::FailedHangingUp;
|
||||
const auto state = _state.current();
|
||||
if (state == State::HangingUp
|
||||
|| state == State::FailedHangingUp
|
||||
|| state == State::Ended
|
||||
|| state == State::Failed) {
|
||||
return;
|
||||
}
|
||||
if (!joined()) {
|
||||
setState(finalState);
|
||||
return;
|
||||
}
|
||||
|
||||
setState(hangupState);
|
||||
_api.request(MTPphone_LeaveGroupCall(
|
||||
inputCall()
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
// Here 'this' could be destroyed by updates, so we set Ended after
|
||||
// updates being handled, but in a guarded way.
|
||||
crl::on_main(this, [=] { setState(finalState); });
|
||||
_channel->session().api().applyUpdates(result);
|
||||
}).fail([=](const RPCError &error) {
|
||||
setState(finalState);
|
||||
}).send();
|
||||
}
|
||||
|
||||
void GroupCall::setMuted(bool mute) {
|
||||
|
@ -123,7 +233,13 @@ void GroupCall::setMuted(bool mute) {
|
|||
|
||||
bool GroupCall::handleUpdate(const MTPGroupCall &call) {
|
||||
return call.match([&](const MTPDgroupCall &data) {
|
||||
if (_id != data.vid().v
|
||||
if (_acceptFields) {
|
||||
if (_instance || _id) {
|
||||
return false;
|
||||
}
|
||||
join(MTP_inputGroupCall(data.vid(), data.vaccess_hash()));
|
||||
return true;
|
||||
} else if (_id != data.vid().v
|
||||
|| _accessHash != data.vaccess_hash().v
|
||||
|| !_instance) {
|
||||
return false;
|
||||
|
@ -182,35 +298,10 @@ bool GroupCall::handleUpdate(const MTPGroupCall &call) {
|
|||
});
|
||||
}
|
||||
_instance->setJoinResponsePayload(payload);
|
||||
_api.request(MTPphone_GetGroupParticipants(
|
||||
inputCall(),
|
||||
MTP_int(0),
|
||||
MTP_int(10)
|
||||
)).done([=](const MTPphone_GroupParticipants &result) {
|
||||
auto sources = std::vector<uint32_t>();
|
||||
result.match([&](const MTPDphone_groupParticipants &data) {
|
||||
for (const auto &p : data.vparticipants().v) {
|
||||
p.match([&](const MTPDgroupCallParticipant &data) {
|
||||
if (data.vuser_id().v != _channel->session().userId()) {
|
||||
sources.push_back(data.vsource().v);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
_instance->setSsrcs(std::move(sources));
|
||||
_instance->setIsMuted(false);
|
||||
}).fail([=](const RPCError &error) {
|
||||
int a = error.code();
|
||||
}).send();
|
||||
checkParticipants();
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}, [&](const MTPDgroupCallPrivate &data) {
|
||||
if (_instance || _id) {
|
||||
return false;
|
||||
}
|
||||
join(MTP_inputGroupCall(data.vid(), data.vaccess_hash()));
|
||||
return true;
|
||||
}, [&](const MTPDgroupCallDiscarded &data) {
|
||||
if (data.vid().v != _id) {
|
||||
return false;
|
||||
|
|
|
@ -25,6 +25,9 @@ public:
|
|||
public:
|
||||
virtual ~Delegate() = default;
|
||||
|
||||
virtual void groupCallFinished(not_null<GroupCall*> call) = 0;
|
||||
virtual void groupCallFailed(not_null<GroupCall*> call) = 0;
|
||||
|
||||
};
|
||||
|
||||
GroupCall(
|
||||
|
@ -38,6 +41,7 @@ public:
|
|||
}
|
||||
|
||||
void start();
|
||||
void hangup();
|
||||
void join(const MTPInputGroupCall &inputCall);
|
||||
bool handleUpdate(const MTPGroupCall &call);
|
||||
|
||||
|
@ -48,6 +52,25 @@ public:
|
|||
[[nodiscard]] rpl::producer<bool> mutedValue() const {
|
||||
return _muted.value();
|
||||
}
|
||||
[[nodiscard]] bool joined() const {
|
||||
return _mySsrc != 0;
|
||||
}
|
||||
|
||||
enum State {
|
||||
Creating,
|
||||
Joining,
|
||||
Joined,
|
||||
FailedHangingUp,
|
||||
Failed,
|
||||
HangingUp,
|
||||
Ended,
|
||||
};
|
||||
[[nodiscard]] State state() const {
|
||||
return _state.current();
|
||||
}
|
||||
[[nodiscard]] rpl::producer<State> stateValue() const {
|
||||
return _state.value();
|
||||
}
|
||||
|
||||
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
||||
void setAudioVolume(bool input, float level);
|
||||
|
@ -58,22 +81,34 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
enum class FinishType {
|
||||
None,
|
||||
Ended,
|
||||
Failed,
|
||||
};
|
||||
|
||||
void handleRequestError(const RPCError &error);
|
||||
void handleControllerError(const QString &error);
|
||||
void createAndStartController();
|
||||
void destroyController();
|
||||
void checkParticipants();
|
||||
|
||||
void setState(State state);
|
||||
void finish(FinishType type);
|
||||
|
||||
[[nodiscard]] MTPInputGroupCall inputCall() const;
|
||||
|
||||
const not_null<Delegate*> _delegate;
|
||||
const not_null<ChannelData*> _channel;
|
||||
MTP::Sender _api;
|
||||
crl::time _startTime = 0;
|
||||
rpl::variable<State> _state = State::Creating;
|
||||
|
||||
rpl::variable<bool> _muted = false;
|
||||
bool _acceptFields = false;
|
||||
|
||||
uint64 _id = 0;
|
||||
uint64 _accessHash = 0;
|
||||
uint32 _mySsrc = 0;
|
||||
|
||||
std::unique_ptr<tgcalls::GroupInstanceImpl> _instance;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "calls/calls_call.h"
|
||||
#include "calls/calls_panel.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_group_call.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_session.h"
|
||||
#include "media/audio/media_audio_track.h"
|
||||
|
@ -93,6 +94,18 @@ void Instance::callRedial(not_null<Call*> call) {
|
|||
}
|
||||
}
|
||||
|
||||
void Instance::groupCallFinished(not_null<GroupCall*> call) {
|
||||
crl::on_main(call, [=] {
|
||||
destroyGroupCall(call);
|
||||
});
|
||||
}
|
||||
|
||||
void Instance::groupCallFailed(not_null<GroupCall*> call) {
|
||||
crl::on_main(call, [=] {
|
||||
destroyGroupCall(call);
|
||||
});
|
||||
}
|
||||
|
||||
void Instance::playSound(Sound sound) {
|
||||
switch (sound) {
|
||||
case Sound::Busy: {
|
||||
|
@ -351,6 +364,12 @@ void Instance::handleCallUpdate(
|
|||
void Instance::handleGroupCallUpdate(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPGroupCall &call) {
|
||||
const auto callId = call.match([](const auto &data) {
|
||||
return data.vid().v;
|
||||
});
|
||||
if (const auto existing = session->data().groupCall(callId)) {
|
||||
existing->applyUpdate(call);
|
||||
}
|
||||
if (_currentGroupCall) {
|
||||
_currentGroupCall->handleUpdate(call);
|
||||
}
|
||||
|
@ -359,6 +378,12 @@ void Instance::handleGroupCallUpdate(
|
|||
void Instance::handleGroupCallUpdate(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPDupdateGroupCallParticipants &update) {
|
||||
const auto callId = update.vcall().match([](const auto &data) {
|
||||
return data.vid().v;
|
||||
});
|
||||
if (const auto existing = session->data().groupCall(callId)) {
|
||||
existing->applyUpdate(update);
|
||||
}
|
||||
}
|
||||
|
||||
void Instance::handleSignalingData(
|
||||
|
@ -424,7 +449,7 @@ void Instance::requestPermissionOrFail(Platform::PermissionType type, Fn<void()>
|
|||
_currentCall->hangup();
|
||||
}
|
||||
if (inGroupCall()) {
|
||||
//_currentGroupCall->hangup(); // #TODO calls
|
||||
_currentGroupCall->hangup();
|
||||
}
|
||||
Ui::show(Box<ConfirmBox>(tr::lng_no_mic_permission(tr::now), tr::lng_menu_settings(tr::now), crl::guard(this, [=] {
|
||||
Platform::OpenSystemSettingsForPermission(type);
|
||||
|
|
|
@ -70,6 +70,9 @@ private:
|
|||
requestPermissionsOrFail(std::move(onSuccess));
|
||||
}
|
||||
|
||||
void groupCallFinished(not_null<GroupCall*> call) override;
|
||||
void groupCallFailed(not_null<GroupCall*> call) override;
|
||||
|
||||
using Sound = Call::Delegate::Sound;
|
||||
void playSound(Sound sound) override;
|
||||
void createCall(not_null<UserData*> user, Call::Type type, bool video);
|
||||
|
|
|
@ -29,10 +29,19 @@ GroupCall::GroupCall(
|
|||
, _accessHash(accessHash) {
|
||||
}
|
||||
|
||||
GroupCall::~GroupCall() {
|
||||
_channel->session().api().request(_participantsRequestId).cancel();
|
||||
_channel->session().api().request(_reloadRequestId).cancel();
|
||||
}
|
||||
|
||||
uint64 GroupCall::id() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
not_null<ChannelData*> GroupCall::channel() const {
|
||||
return _channel;
|
||||
}
|
||||
|
||||
MTPInputGroupCall GroupCall::input() const {
|
||||
return MTP_inputGroupCall(MTP_long(_id), MTP_long(_accessHash));
|
||||
}
|
||||
|
@ -42,8 +51,12 @@ auto GroupCall::participants() const
|
|||
return _participants;
|
||||
}
|
||||
|
||||
const base::flat_set<uint32> &GroupCall::sources() const {
|
||||
return _sources;
|
||||
}
|
||||
|
||||
void GroupCall::requestParticipants() {
|
||||
if (_participantsRequestId) {
|
||||
if (_participantsRequestId || _reloadRequestId) {
|
||||
return;
|
||||
} else if (_participants.size() >= _fullCount && _allReceived) {
|
||||
return;
|
||||
|
@ -58,31 +71,9 @@ void GroupCall::requestParticipants() {
|
|||
MTP_int(kRequestPerPage)
|
||||
)).done([=](const MTPphone_GroupParticipants &result) {
|
||||
result.match([&](const MTPDphone_groupParticipants &data) {
|
||||
_fullCount = data.vcount().v;
|
||||
_channel->owner().processUsers(data.vusers());
|
||||
for (const auto &p : data.vparticipants().v) {
|
||||
p.match([&](const MTPDgroupCallParticipant &data) {
|
||||
const auto userId = data.vuser_id().v;
|
||||
const auto user = _channel->owner().user(userId);
|
||||
const auto value = Participant{
|
||||
.user = user,
|
||||
.date = data.vdate().v,
|
||||
.source = data.vsource().v,
|
||||
.muted = data.is_muted(),
|
||||
.canSelfUnmute = data.is_can_self_unmute(),
|
||||
.left = data.is_left()
|
||||
};
|
||||
const auto i = ranges::find(
|
||||
_participants,
|
||||
user,
|
||||
&Participant::user);
|
||||
if (i == end(_participants)) {
|
||||
_participants.push_back(value);
|
||||
} else {
|
||||
*i = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
applyParticipantsSlice(data.vparticipants().v);
|
||||
_fullCount = data.vcount().v;
|
||||
if (!_allReceived
|
||||
&& (data.vparticipants().v.size() < kRequestPerPage)) {
|
||||
_allReceived = true;
|
||||
|
@ -91,16 +82,17 @@ void GroupCall::requestParticipants() {
|
|||
_fullCount = _participants.size();
|
||||
}
|
||||
});
|
||||
ranges::sort(_participants, std::greater<>(), &Participant::date);
|
||||
_channel->session().changes().peerUpdated(
|
||||
_channel,
|
||||
PeerUpdate::Flag::GroupCall);
|
||||
_participantsRequestId = 0;
|
||||
}).fail([=](const RPCError &error) {
|
||||
_allReceived = true;
|
||||
_fullCount = _participants.size();
|
||||
_allReceived = true;
|
||||
_channel->session().changes().peerUpdated(
|
||||
_channel,
|
||||
PeerUpdate::Flag::GroupCall);
|
||||
_participantsRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
|
@ -112,4 +104,118 @@ bool GroupCall::participantsLoaded() const {
|
|||
return _allReceived;
|
||||
}
|
||||
|
||||
void GroupCall::applyUpdate(const MTPGroupCall &update) {
|
||||
applyCall(update, false);
|
||||
}
|
||||
|
||||
void GroupCall::applyCall(const MTPGroupCall &call, bool force) {
|
||||
call.match([&](const MTPDgroupCall &data) {
|
||||
const auto changed = (_version != data.vversion().v)
|
||||
|| (_fullCount != data.vparticipants_count().v);
|
||||
if (!force && !changed) {
|
||||
return;
|
||||
} else if (!force && _version > data.vversion().v) {
|
||||
reload();
|
||||
return;
|
||||
}
|
||||
_version = data.vversion().v;
|
||||
_fullCount = data.vparticipants_count().v;
|
||||
}, [&](const MTPDgroupCallDiscarded &data) {
|
||||
const auto changed = (_duration != data.vduration().v)
|
||||
|| !_finished;
|
||||
if (!force && !changed) {
|
||||
return;
|
||||
}
|
||||
_finished = true;
|
||||
_duration = data.vduration().v;
|
||||
});
|
||||
_channel->session().changes().peerUpdated(
|
||||
_channel,
|
||||
PeerUpdate::Flag::GroupCall);
|
||||
}
|
||||
|
||||
void GroupCall::reload() {
|
||||
if (_reloadRequestId) {
|
||||
return;
|
||||
} else if (_participantsRequestId) {
|
||||
_channel->session().api().request(_participantsRequestId).cancel();
|
||||
_participantsRequestId = 0;
|
||||
}
|
||||
_reloadRequestId = _channel->session().api().request(
|
||||
MTPphone_GetGroupCall(input())
|
||||
).done([=](const MTPphone_GroupCall &result) {
|
||||
result.match([&](const MTPDphone_groupCall &data) {
|
||||
_channel->owner().processUsers(data.vusers());
|
||||
_participants.clear();
|
||||
_sources.clear();
|
||||
applyParticipantsSlice(data.vparticipants().v);
|
||||
for (const auto &source : data.vsources().v) {
|
||||
_sources.emplace(source.v);
|
||||
}
|
||||
_fullCount = _sources.size();
|
||||
if (_participants.size() > _fullCount) {
|
||||
_fullCount = _participants.size();
|
||||
}
|
||||
_allReceived = (_fullCount == _participants.size());
|
||||
applyCall(data.vcall(), true);
|
||||
});
|
||||
_reloadRequestId = 0;
|
||||
}).fail([=](const RPCError &error) {
|
||||
_reloadRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
void GroupCall::applyParticipantsSlice(
|
||||
const QVector<MTPGroupCallParticipant> &list) {
|
||||
for (const auto &participant : list) {
|
||||
participant.match([&](const MTPDgroupCallParticipant &data) {
|
||||
const auto userId = data.vuser_id().v;
|
||||
const auto user = _channel->owner().user(userId);
|
||||
const auto i = ranges::find(
|
||||
_participants,
|
||||
user,
|
||||
&Participant::user);
|
||||
if (data.is_left()) {
|
||||
if (i != end(_participants)) {
|
||||
_sources.remove(i->source);
|
||||
_participants.erase(i);
|
||||
}
|
||||
if (_fullCount > _participants.size()) {
|
||||
--_fullCount;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const auto value = Participant{
|
||||
.user = user,
|
||||
.date = data.vdate().v,
|
||||
.source = uint32(data.vsource().v),
|
||||
.muted = data.is_muted(),
|
||||
.canSelfUnmute = data.is_can_self_unmute(),
|
||||
};
|
||||
if (i == end(_participants)) {
|
||||
_participants.push_back(value);
|
||||
++_fullCount;
|
||||
} else {
|
||||
*i = value;
|
||||
}
|
||||
_sources.emplace(uint32(data.vsource().v));
|
||||
});
|
||||
}
|
||||
ranges::sort(_participants, std::greater<>(), &Participant::date);
|
||||
}
|
||||
|
||||
void GroupCall::applyUpdate(const MTPDupdateGroupCallParticipants &update) {
|
||||
if (update.vversion().v <= _version) {
|
||||
return;
|
||||
} else if (update.vversion().v != _version + 1) {
|
||||
reload();
|
||||
return;
|
||||
}
|
||||
_version = update.vversion().v;
|
||||
applyParticipantsSlice(update.vparticipants().v);
|
||||
_channel->session().changes().peerUpdated(
|
||||
_channel,
|
||||
PeerUpdate::Flag::GroupCall);
|
||||
}
|
||||
|
||||
} // namespace Data
|
||||
|
|
|
@ -15,38 +15,52 @@ namespace Data {
|
|||
class GroupCall final {
|
||||
public:
|
||||
GroupCall(not_null<ChannelData*> channel, uint64 id, uint64 accessHash);
|
||||
~GroupCall();
|
||||
|
||||
[[nodiscard]] uint64 id() const;
|
||||
[[nodiscard]] not_null<ChannelData*> channel() const;
|
||||
[[nodiscard]] MTPInputGroupCall input() const;
|
||||
|
||||
struct Participant {
|
||||
not_null<UserData*> user;
|
||||
TimeId date = 0;
|
||||
int source = 0;
|
||||
uint32 source = 0;
|
||||
bool muted = false;
|
||||
bool canSelfUnmute = false;
|
||||
bool left = false;
|
||||
};
|
||||
|
||||
[[nodiscard]] auto participants() const
|
||||
-> const std::vector<Participant> &;
|
||||
[[nodiscard]] const base::flat_set<uint32> &sources() const;
|
||||
void requestParticipants();
|
||||
[[nodiscard]] bool participantsLoaded() const;
|
||||
|
||||
void applyUpdate(const MTPGroupCall &update);
|
||||
void applyUpdate(const MTPDupdateGroupCallParticipants &update);
|
||||
|
||||
[[nodiscard]] int fullCount() const;
|
||||
|
||||
void reload();
|
||||
[[nodiscard]] bool finished() const;
|
||||
[[nodiscard]] int duration() const;
|
||||
|
||||
private:
|
||||
void applyCall(const MTPGroupCall &call, bool force);
|
||||
void applyParticipantsSlice(const QVector<MTPGroupCallParticipant> &list);
|
||||
|
||||
const not_null<ChannelData*> _channel;
|
||||
const uint64 _id = 0;
|
||||
const uint64 _accessHash = 0;
|
||||
|
||||
int _version = 0;
|
||||
UserId _adminId = 0;
|
||||
uint64 _reflectorId = 0;
|
||||
mtpRequestId _participantsRequestId = 0;
|
||||
mtpRequestId _reloadRequestId = 0;
|
||||
|
||||
std::vector<Participant> _participants;
|
||||
base::flat_set<uint32> _sources;
|
||||
int _fullCount = 0;
|
||||
int _duration = 0;
|
||||
bool _finished = false;
|
||||
bool _allReceived = false;
|
||||
|
||||
};
|
||||
|
|
|
@ -38,6 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "lang/lang_keys.h" // tr::lng_deleted(tr::now) in user name
|
||||
#include "data/stickers/data_stickers.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_group_call.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_channel.h"
|
||||
|
@ -791,6 +792,19 @@ void Session::applyMaximumChatVersions(const MTPVector<MTPChat> &data) {
|
|||
}
|
||||
}
|
||||
|
||||
void Session::registerGroupCall(not_null<GroupCall*> call) {
|
||||
_groupCalls.emplace(call->id(), call);
|
||||
}
|
||||
|
||||
void Session::unregisterGroupCall(not_null<GroupCall*> call) {
|
||||
_groupCalls.remove(call->id());
|
||||
}
|
||||
|
||||
GroupCall *Session::groupCall(uint64 callId) const {
|
||||
const auto i = _groupCalls.find(callId);
|
||||
return (i != end(_groupCalls)) ? i->second.get() : nullptr;
|
||||
}
|
||||
|
||||
PeerData *Session::peerByUsername(const QString &username) const {
|
||||
const auto uname = username.trimmed();
|
||||
for (const auto &[peerId, peer] : _peers) {
|
||||
|
|
|
@ -60,6 +60,7 @@ class Histories;
|
|||
class DocumentMedia;
|
||||
class PhotoMedia;
|
||||
class Stickers;
|
||||
class GroupCall;
|
||||
|
||||
class Session final {
|
||||
public:
|
||||
|
@ -153,6 +154,10 @@ public:
|
|||
|
||||
void applyMaximumChatVersions(const MTPVector<MTPChat> &data);
|
||||
|
||||
void registerGroupCall(not_null<GroupCall*> call);
|
||||
void unregisterGroupCall(not_null<GroupCall*> call);
|
||||
GroupCall *groupCall(uint64 callId) const;
|
||||
|
||||
void enumerateUsers(Fn<void(not_null<UserData*>)> action) const;
|
||||
void enumerateGroups(Fn<void(not_null<PeerData*>)> action) const;
|
||||
void enumerateChannels(Fn<void(not_null<ChannelData*>)> action) const;
|
||||
|
@ -906,6 +911,8 @@ private:
|
|||
|
||||
base::flat_set<not_null<ViewElement*>> _heavyViewParts;
|
||||
|
||||
base::flat_map<uint64, not_null<GroupCall*>> _groupCalls;
|
||||
|
||||
History *_topPromoted = nullptr;
|
||||
|
||||
NotifySettings _defaultUserNotifySettings;
|
||||
|
|
Loading…
Add table
Reference in a new issue