mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Send mute state updates in group calls.
This commit is contained in:
parent
ec5aeb32f1
commit
2ac0a2a10b
4 changed files with 123 additions and 60 deletions
|
@ -111,45 +111,7 @@ void GroupCall::join(const MTPInputGroupCall &inputCall) {
|
||||||
_id = data.vid().v;
|
_id = data.vid().v;
|
||||||
_accessHash = data.vaccess_hash().v;
|
_accessHash = data.vaccess_hash().v;
|
||||||
createAndStartController();
|
createAndStartController();
|
||||||
const auto weak = base::make_weak(this);
|
rejoin();
|
||||||
_instance->emitJoinPayload([=](tgcalls::GroupJoinPayload payload) {
|
|
||||||
crl::on_main(weak, [=, payload = std::move(payload)]{
|
|
||||||
auto fingerprints = QJsonArray();
|
|
||||||
for (const auto print : payload.fingerprints) {
|
|
||||||
auto object = QJsonObject();
|
|
||||||
object.insert("hash", QString::fromStdString(print.hash));
|
|
||||||
object.insert("setup", QString::fromStdString(print.setup));
|
|
||||||
object.insert(
|
|
||||||
"fingerprint",
|
|
||||||
QString::fromStdString(print.fingerprint));
|
|
||||||
fingerprints.push_back(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
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", double(payload.ssrc));
|
|
||||||
|
|
||||||
const auto json = QJsonDocument(root).toJson(
|
|
||||||
QJsonDocument::Compact);
|
|
||||||
_api.request(MTPphone_JoinGroupCall(
|
|
||||||
MTP_flags(_muted.current()
|
|
||||||
? MTPphone_JoinGroupCall::Flag::f_muted
|
|
||||||
: MTPphone_JoinGroupCall::Flag(0)),
|
|
||||||
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();
|
|
||||||
}).send();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
_channel->setCall(inputCall);
|
_channel->setCall(inputCall);
|
||||||
|
|
||||||
|
@ -161,6 +123,56 @@ void GroupCall::join(const MTPInputGroupCall &inputCall) {
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GroupCall::rejoin() {
|
||||||
|
Expects(_state.current() == State::Joining);
|
||||||
|
|
||||||
|
_mySsrc = 0;
|
||||||
|
const auto weak = base::make_weak(this);
|
||||||
|
_instance->emitJoinPayload([=](tgcalls::GroupJoinPayload payload) {
|
||||||
|
crl::on_main(weak, [=, payload = std::move(payload)]{
|
||||||
|
auto fingerprints = QJsonArray();
|
||||||
|
for (const auto print : payload.fingerprints) {
|
||||||
|
auto object = QJsonObject();
|
||||||
|
object.insert("hash", QString::fromStdString(print.hash));
|
||||||
|
object.insert("setup", QString::fromStdString(print.setup));
|
||||||
|
object.insert(
|
||||||
|
"fingerprint",
|
||||||
|
QString::fromStdString(print.fingerprint));
|
||||||
|
fingerprints.push_back(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
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", double(payload.ssrc));
|
||||||
|
|
||||||
|
const auto json = QJsonDocument(root).toJson(
|
||||||
|
QJsonDocument::Compact);
|
||||||
|
const auto muted = _muted.current();
|
||||||
|
_api.request(MTPphone_JoinGroupCall(
|
||||||
|
MTP_flags(muted
|
||||||
|
? MTPphone_JoinGroupCall::Flag::f_muted
|
||||||
|
: MTPphone_JoinGroupCall::Flag(0)),
|
||||||
|
inputCall(),
|
||||||
|
MTP_dataJSON(MTP_bytes(json))
|
||||||
|
)).done([=](const MTPUpdates &updates) {
|
||||||
|
_mySsrc = ssrc;
|
||||||
|
setState(State::Joined);
|
||||||
|
|
||||||
|
if (_muted.current() != muted) {
|
||||||
|
sendMutedUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
_channel->session().api().applyUpdates(updates);
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
int a = error.code();
|
||||||
|
}).send();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void GroupCall::checkParticipants() {
|
void GroupCall::checkParticipants() {
|
||||||
if (!joined()) {
|
if (!joined()) {
|
||||||
return;
|
return;
|
||||||
|
@ -226,23 +238,19 @@ void GroupCall::finish(FinishType type) {
|
||||||
|
|
||||||
void GroupCall::setMuted(bool mute) {
|
void GroupCall::setMuted(bool mute) {
|
||||||
_muted = mute;
|
_muted = mute;
|
||||||
if (_instance) {
|
|
||||||
_instance->setIsMuted(mute);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GroupCall::handleUpdate(const MTPGroupCall &call) {
|
void GroupCall::handleUpdate(const MTPGroupCall &call) {
|
||||||
return call.match([&](const MTPDgroupCall &data) {
|
return call.match([&](const MTPDgroupCall &data) {
|
||||||
if (_acceptFields) {
|
if (_acceptFields) {
|
||||||
if (_instance || _id) {
|
if (!_instance && !_id) {
|
||||||
return false;
|
join(MTP_inputGroupCall(data.vid(), data.vaccess_hash()));
|
||||||
}
|
}
|
||||||
join(MTP_inputGroupCall(data.vid(), data.vaccess_hash()));
|
return;
|
||||||
return true;
|
|
||||||
} else if (_id != data.vid().v
|
} else if (_id != data.vid().v
|
||||||
|| _accessHash != data.vaccess_hash().v
|
|| _accessHash != data.vaccess_hash().v
|
||||||
|| !_instance) {
|
|| !_instance) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
if (const auto params = data.vparams()) {
|
if (const auto params = data.vparams()) {
|
||||||
params->match([&](const MTPDdataJSON &data) {
|
params->match([&](const MTPDdataJSON &data) {
|
||||||
|
@ -301,15 +309,39 @@ bool GroupCall::handleUpdate(const MTPGroupCall &call) {
|
||||||
checkParticipants();
|
checkParticipants();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}, [&](const MTPDgroupCallDiscarded &data) {
|
}, [&](const MTPDgroupCallDiscarded &data) {
|
||||||
if (data.vid().v != _id) {
|
if (data.vid().v == _id) {
|
||||||
return false;
|
_mySsrc = 0;
|
||||||
|
hangup();
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) {
|
||||||
|
const auto state = _state.current();
|
||||||
|
if (state != State::Joined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto self = _channel->session().userId();
|
||||||
|
for (const auto &participant : data.vparticipants().v) {
|
||||||
|
participant.match([&](const MTPDgroupCallParticipant &data) {
|
||||||
|
if (data.vuser_id().v != self) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (data.is_left() && data.vsource().v == _mySsrc) {
|
||||||
|
// I was removed from the call, rejoin.
|
||||||
|
setState(State::Joining);
|
||||||
|
rejoin();
|
||||||
|
} else if (!data.is_left() && data.vsource().v != _mySsrc) {
|
||||||
|
// I joined from another device, hangup.
|
||||||
|
_mySsrc = 0;
|
||||||
|
hangup();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GroupCall::createAndStartController() {
|
void GroupCall::createAndStartController() {
|
||||||
using AudioLevels = std::vector<std::pair<uint32_t, float>>;
|
using AudioLevels = std::vector<std::pair<uint32_t, float>>;
|
||||||
|
|
||||||
|
@ -341,11 +373,37 @@ void GroupCall::createAndStartController() {
|
||||||
_instance = std::make_unique<tgcalls::GroupInstanceImpl>(
|
_instance = std::make_unique<tgcalls::GroupInstanceImpl>(
|
||||||
std::move(descriptor));
|
std::move(descriptor));
|
||||||
|
|
||||||
const auto raw = _instance.get();
|
_muted.value(
|
||||||
raw->setIsMuted(_muted.current());
|
) | rpl::start_with_next([=](bool muted) {
|
||||||
|
if (_instance) {
|
||||||
|
_instance->setIsMuted(muted);
|
||||||
|
}
|
||||||
|
if (_mySsrc) {
|
||||||
|
sendMutedUpdate();
|
||||||
|
}
|
||||||
|
}, _lifetime);
|
||||||
//raw->setAudioOutputDuckingEnabled(settings.callAudioDuckingEnabled());
|
//raw->setAudioOutputDuckingEnabled(settings.callAudioDuckingEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GroupCall::sendMutedUpdate() {
|
||||||
|
_api.request(_updateMuteRequestId).cancel();
|
||||||
|
_updateMuteRequestId = _api.request(MTPphone_EditGroupCallMember(
|
||||||
|
MTP_flags(_muted.current()
|
||||||
|
? MTPphone_EditGroupCallMember::Flag::f_muted
|
||||||
|
: MTPphone_EditGroupCallMember::Flag(0)),
|
||||||
|
inputCall(),
|
||||||
|
MTP_inputUserSelf()
|
||||||
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
_channel->session().api().applyUpdates(result);
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
if (error.type() == u"GROUP_CALL_FORBIDDEN"_q
|
||||||
|
&& _state.current() == State::Joined) {
|
||||||
|
setState(State::Joining);
|
||||||
|
rejoin();
|
||||||
|
}
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
void GroupCall::setCurrentAudioDevice(bool input, const QString &deviceId) {
|
void GroupCall::setCurrentAudioDevice(bool input, const QString &deviceId) {
|
||||||
if (_instance) {
|
if (_instance) {
|
||||||
const auto id = deviceId.toStdString();
|
const auto id = deviceId.toStdString();
|
||||||
|
|
|
@ -43,7 +43,8 @@ public:
|
||||||
void start();
|
void start();
|
||||||
void hangup();
|
void hangup();
|
||||||
void join(const MTPInputGroupCall &inputCall);
|
void join(const MTPInputGroupCall &inputCall);
|
||||||
bool handleUpdate(const MTPGroupCall &call);
|
void handleUpdate(const MTPGroupCall &call);
|
||||||
|
void handleUpdate(const MTPDupdateGroupCallParticipants &data);
|
||||||
|
|
||||||
void setMuted(bool mute);
|
void setMuted(bool mute);
|
||||||
[[nodiscard]] bool muted() const {
|
[[nodiscard]] bool muted() const {
|
||||||
|
@ -95,6 +96,8 @@ private:
|
||||||
|
|
||||||
void setState(State state);
|
void setState(State state);
|
||||||
void finish(FinishType type);
|
void finish(FinishType type);
|
||||||
|
void sendMutedUpdate();
|
||||||
|
void rejoin();
|
||||||
|
|
||||||
[[nodiscard]] MTPInputGroupCall inputCall() const;
|
[[nodiscard]] MTPInputGroupCall inputCall() const;
|
||||||
|
|
||||||
|
@ -109,6 +112,7 @@ private:
|
||||||
uint64 _id = 0;
|
uint64 _id = 0;
|
||||||
uint64 _accessHash = 0;
|
uint64 _accessHash = 0;
|
||||||
uint32 _mySsrc = 0;
|
uint32 _mySsrc = 0;
|
||||||
|
mtpRequestId _updateMuteRequestId = 0;
|
||||||
|
|
||||||
std::unique_ptr<tgcalls::GroupInstanceImpl> _instance;
|
std::unique_ptr<tgcalls::GroupInstanceImpl> _instance;
|
||||||
|
|
||||||
|
|
|
@ -246,6 +246,8 @@ void MembersController::prepareRows() {
|
||||||
auto user = row->peer()->asUser();
|
auto user = row->peer()->asUser();
|
||||||
if (user->isSelf()) {
|
if (user->isSelf()) {
|
||||||
foundSelf = true;
|
foundSelf = true;
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
const auto contains = ranges::contains(
|
const auto contains = ranges::contains(
|
||||||
participants,
|
participants,
|
||||||
|
@ -303,11 +305,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::rowContextMenu(
|
||||||
Expects(row->peer()->isUser());
|
Expects(row->peer()->isUser());
|
||||||
|
|
||||||
const auto user = row->peer()->asUser();
|
const auto user = row->peer()->asUser();
|
||||||
auto result = base::make_unique_q<Ui::PopupMenu>(parent);
|
return nullptr;
|
||||||
//result->addAction( // #TODO calls
|
|
||||||
// tr::lng_context_view_profile(tr::now),
|
|
||||||
// crl::guard(this, [=] { _navigation->showPeerInfo(user); }));
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MembersController::appendRow(not_null<UserData*> user) {
|
bool MembersController::appendRow(not_null<UserData*> user) {
|
||||||
|
|
|
@ -393,6 +393,9 @@ void Instance::handleGroupCallUpdate(
|
||||||
if (const auto existing = session->data().groupCall(callId)) {
|
if (const auto existing = session->data().groupCall(callId)) {
|
||||||
existing->applyUpdate(update);
|
existing->applyUpdate(update);
|
||||||
}
|
}
|
||||||
|
if (_currentGroupCall) {
|
||||||
|
_currentGroupCall->handleUpdate(update);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::handleSignalingData(
|
void Instance::handleSignalingData(
|
||||||
|
|
Loading…
Add table
Reference in a new issue