mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-03 21:54:05 +02:00
Parse e2e participant keys.
This commit is contained in:
parent
214cc83d4a
commit
5e6c81a98e
11 changed files with 240 additions and 29 deletions
|
@ -230,6 +230,30 @@ void Instance::startOrJoinGroupCall(
|
|||
});
|
||||
}
|
||||
|
||||
void Instance::startOrJoinConferenceCall(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
StartConferenceCallArgs args) {
|
||||
destroyCurrentCall();
|
||||
|
||||
auto call = std::make_unique<GroupCall>(
|
||||
_delegate.get(),
|
||||
Calls::Group::ConferenceInfo{
|
||||
.call = args.call,
|
||||
.linkSlug = args.linkSlug,
|
||||
.joinMessageId = args.joinMessageId,
|
||||
});
|
||||
const auto raw = call.get();
|
||||
|
||||
args.call->peer()->session().account().sessionChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
destroyGroupCall(raw);
|
||||
}, raw->lifetime());
|
||||
|
||||
_currentGroupCallPanel = std::make_unique<Group::Panel>(raw);
|
||||
_currentGroupCall = std::move(call);
|
||||
_currentGroupCallChanges.fire_copy(raw);
|
||||
}
|
||||
|
||||
void Instance::confirmLeaveCurrent(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
|
@ -409,6 +433,24 @@ void Instance::createGroupCall(
|
|||
_currentGroupCallChanges.fire_copy(raw);
|
||||
}
|
||||
|
||||
void Instance::createConferenceCall(Group::ConferenceInfo info) {
|
||||
destroyCurrentCall();
|
||||
|
||||
auto call = std::make_unique<GroupCall>(
|
||||
_delegate.get(),
|
||||
std::move(info));
|
||||
const auto raw = call.get();
|
||||
|
||||
raw->peer()->session().account().sessionChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
destroyGroupCall(raw);
|
||||
}, raw->lifetime());
|
||||
|
||||
_currentGroupCallPanel = std::make_unique<Group::Panel>(raw);
|
||||
_currentGroupCall = std::move(call);
|
||||
_currentGroupCallChanges.fire_copy(raw);
|
||||
}
|
||||
|
||||
void Instance::refreshDhConfig() {
|
||||
Expects(_currentCall != nullptr);
|
||||
|
||||
|
|
|
@ -13,6 +13,10 @@ namespace crl {
|
|||
class semaphore;
|
||||
} // namespace crl
|
||||
|
||||
namespace Data {
|
||||
class GroupCall;
|
||||
} // namespace Data
|
||||
|
||||
namespace Platform {
|
||||
enum class PermissionType;
|
||||
} // namespace Platform
|
||||
|
@ -31,6 +35,7 @@ class Show;
|
|||
|
||||
namespace Calls::Group {
|
||||
struct JoinInfo;
|
||||
struct ConferenceInfo;
|
||||
class Panel;
|
||||
class ChooseJoinAsProcess;
|
||||
class StartRtmpProcess;
|
||||
|
@ -59,6 +64,12 @@ struct StartGroupCallArgs {
|
|||
bool scheduleNeeded = false;
|
||||
};
|
||||
|
||||
struct StartConferenceCallArgs {
|
||||
std::shared_ptr<Data::GroupCall> call;
|
||||
QString linkSlug;
|
||||
MsgId joinMessageId;
|
||||
};
|
||||
|
||||
class Instance final : public base::has_weak_ptr {
|
||||
public:
|
||||
Instance();
|
||||
|
@ -69,6 +80,9 @@ public:
|
|||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
StartGroupCallArgs args);
|
||||
void startOrJoinConferenceCall(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
StartConferenceCallArgs args);
|
||||
void showStartWithRtmp(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
not_null<PeerData*> peer);
|
||||
|
@ -121,6 +135,7 @@ private:
|
|||
void createGroupCall(
|
||||
Group::JoinInfo info,
|
||||
const MTPInputGroupCall &inputCall);
|
||||
void createConferenceCall(Group::ConferenceInfo info);
|
||||
void destroyGroupCall(not_null<GroupCall*> call);
|
||||
void confirmLeaveCurrent(
|
||||
std::shared_ptr<Ui::Show> show,
|
||||
|
|
|
@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "base/global_shortcuts.h"
|
||||
#include "base/random.h"
|
||||
#include "tde2e/tde2e_api.h"
|
||||
#include "webrtc/webrtc_video_track.h"
|
||||
#include "webrtc/webrtc_create_adm.h"
|
||||
#include "webrtc/webrtc_environment.h"
|
||||
|
@ -418,6 +419,21 @@ std::shared_ptr<ParticipantVideoParams> ParseVideoParams(
|
|||
return data;
|
||||
}
|
||||
|
||||
std::shared_ptr<TdE2E::ParticipantState> ParseParticipantState(
|
||||
const MTPDgroupCallParticipant &data) {
|
||||
if (!data.vpublic_key() || data.vpeer().type() != mtpc_peerUser) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto &v = *data.vpublic_key();
|
||||
const auto userId = data.vpeer().c_peerUser().vuser_id().v;
|
||||
using State = TdE2E::ParticipantState;
|
||||
return std::make_shared<State>(State{
|
||||
.id = uint64(userId),
|
||||
.key = { .a = v.h.h, .b = v.h.l, .c = v.l.h, .d = v.l.l },
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
GroupCall::LoadPartTask::LoadPartTask(
|
||||
base::weak_ptr<GroupCall> call,
|
||||
int64 time,
|
||||
|
@ -569,18 +585,38 @@ GroupCall::GroupCall(
|
|||
not_null<Delegate*> delegate,
|
||||
Group::JoinInfo info,
|
||||
const MTPInputGroupCall &inputCall)
|
||||
: GroupCall(delegate, info, {}, inputCall) {
|
||||
}
|
||||
|
||||
GroupCall::GroupCall(
|
||||
not_null<Delegate*> delegate,
|
||||
Group::ConferenceInfo info)
|
||||
: GroupCall(delegate, Group::JoinInfo{
|
||||
.peer = info.call->peer(),
|
||||
.joinAs = info.call->peer(),
|
||||
}, info, info.call->input()) {
|
||||
}
|
||||
|
||||
GroupCall::GroupCall(
|
||||
not_null<Delegate*> delegate,
|
||||
Group::JoinInfo join,
|
||||
Group::ConferenceInfo conference,
|
||||
const MTPInputGroupCall &inputCall)
|
||||
: _delegate(delegate)
|
||||
, _peer(info.peer)
|
||||
, _conferenceCall(conference.call)
|
||||
, _peer(join.peer)
|
||||
, _history(_peer->owner().history(_peer))
|
||||
, _api(&_peer->session().mtp())
|
||||
, _joinAs(info.joinAs)
|
||||
, _possibleJoinAs(std::move(info.possibleJoinAs))
|
||||
, _joinHash(info.joinHash)
|
||||
, _rtmpUrl(info.rtmpInfo.url)
|
||||
, _rtmpKey(info.rtmpInfo.key)
|
||||
, _joinAs(join.joinAs)
|
||||
, _possibleJoinAs(std::move(join.possibleJoinAs))
|
||||
, _joinHash(join.joinHash)
|
||||
, _conferenceLinkSlug(conference.linkSlug)
|
||||
, _conferenceJoinMessageId(conference.joinMessageId)
|
||||
, _rtmpUrl(join.rtmpInfo.url)
|
||||
, _rtmpKey(join.rtmpInfo.key)
|
||||
, _canManage(Data::CanManageGroupCallValue(_peer))
|
||||
, _id(inputCall.c_inputGroupCall().vid().v)
|
||||
, _scheduleDate(info.scheduleDate)
|
||||
, _scheduleDate(join.scheduleDate)
|
||||
, _lastSpokeCheckTimer([=] { checkLastSpoke(); })
|
||||
, _checkJoinedTimer([=] { checkJoined(); })
|
||||
, _playbackDeviceId(
|
||||
|
@ -601,9 +637,14 @@ GroupCall::GroupCall(
|
|||
Webrtc::DeviceIdOrDefault(Core::App().settings().cameraDeviceIdValue()))
|
||||
, _pushToTalkCancelTimer([=] { pushToTalkCancel(); })
|
||||
, _connectingSoundTimer([=] { playConnectingSoundOnce(); })
|
||||
, _listenersHidden(info.rtmp)
|
||||
, _rtmp(info.rtmp)
|
||||
, _listenersHidden(join.rtmp)
|
||||
, _rtmp(join.rtmp)
|
||||
, _rtmpVolume(Group::kDefaultVolume) {
|
||||
if (_conferenceCall) {
|
||||
_e2eState = std::make_unique<TdE2E::CallState>(
|
||||
TdE2E::CreateCallState());
|
||||
}
|
||||
|
||||
_muted.value(
|
||||
) | rpl::combine_previous(
|
||||
) | rpl::start_with_next([=](MuteState previous, MuteState state) {
|
||||
|
@ -657,9 +698,9 @@ GroupCall::GroupCall(
|
|||
setupOutgoingVideo();
|
||||
|
||||
if (_id) {
|
||||
join(inputCall);
|
||||
this->join(inputCall);
|
||||
} else {
|
||||
start(info.scheduleDate, info.rtmp);
|
||||
start(join.scheduleDate, join.rtmp);
|
||||
}
|
||||
if (_scheduleDate) {
|
||||
saveDefaultJoinAs(joinAs());
|
||||
|
@ -1055,6 +1096,9 @@ void GroupCall::setRtmpInfo(const Calls::Group::RtmpInfo &value) {
|
|||
}
|
||||
|
||||
Data::GroupCall *GroupCall::lookupReal() const {
|
||||
if (_conferenceCall) {
|
||||
return _conferenceCall.get();
|
||||
}
|
||||
const auto real = _peer->groupCall();
|
||||
return (real && real->id() == _id) ? real : nullptr;
|
||||
}
|
||||
|
@ -1373,14 +1417,24 @@ void GroupCall::rejoin(not_null<PeerData*> as) {
|
|||
: Flag::f_invite_hash)
|
||||
| (wasVideoStopped
|
||||
? Flag::f_video_stopped
|
||||
: Flag(0));
|
||||
: Flag(0))
|
||||
| (_conferenceJoinMessageId ? Flag::f_invite_msg_id : Flag())
|
||||
| (_e2eState ? Flag::f_public_key : Flag());
|
||||
const auto publicKey = _e2eState
|
||||
? _e2eState->myKey
|
||||
: TdE2E::PublicKey();
|
||||
_api.request(MTPphone_JoinGroupCall(
|
||||
MTP_flags(flags),
|
||||
inputCall(),
|
||||
(_conferenceLinkSlug.isEmpty()
|
||||
? inputCall()
|
||||
: MTP_inputGroupCallSlug(
|
||||
MTP_string(_conferenceLinkSlug))),
|
||||
joinAs()->input,
|
||||
MTP_string(_joinHash),
|
||||
MTPint256(), // public_key
|
||||
MTPint(), // invite_msg_id
|
||||
MTP_int256(
|
||||
MTP_int128(publicKey.a, publicKey.b),
|
||||
MTP_int128(publicKey.c, publicKey.d)),
|
||||
MTP_int(_conferenceJoinMessageId.bare),
|
||||
MTP_dataJSON(MTP_bytes(json))
|
||||
)).done([=](
|
||||
const MTPUpdates &updates,
|
||||
|
@ -1586,6 +1640,7 @@ void GroupCall::applyMeInCallLocally() {
|
|||
: participant
|
||||
? participant->raisedHandRating
|
||||
: FindLocalRaisedHandRating(real->participants());
|
||||
const auto publicKey = _e2eState ? _e2eState->myKey : TdE2E::PublicKey();
|
||||
const auto flags = (canSelfUnmute ? Flag::f_can_self_unmute : Flag(0))
|
||||
| (lastActive ? Flag::f_active_date : Flag(0))
|
||||
| (_joinState.ssrc ? Flag(0) : Flag::f_left)
|
||||
|
@ -1594,7 +1649,8 @@ void GroupCall::applyMeInCallLocally() {
|
|||
| Flag::f_volume // Without flag the volume is reset to 100%.
|
||||
| Flag::f_volume_by_admin // Self volume can only be set by admin.
|
||||
| ((muted() != MuteState::Active) ? Flag::f_muted : Flag(0))
|
||||
| (raisedHandRating > 0 ? Flag::f_raise_hand_rating : Flag(0));
|
||||
| (raisedHandRating > 0 ? Flag::f_raise_hand_rating : Flag(0))
|
||||
| (_e2eState ? Flag::f_public_key : Flag(0));
|
||||
real->applyLocalUpdate(
|
||||
MTP_updateGroupCallParticipants(
|
||||
inputCall(),
|
||||
|
@ -1611,7 +1667,9 @@ void GroupCall::applyMeInCallLocally() {
|
|||
MTP_long(raisedHandRating),
|
||||
MTPGroupCallParticipantVideo(),
|
||||
MTPGroupCallParticipantVideo(),
|
||||
AssertIsDebug() MTPint256())), // public_key
|
||||
MTP_int256(
|
||||
MTP_int128(publicKey.a, publicKey.b),
|
||||
MTP_int128(publicKey.c, publicKey.d)))),
|
||||
MTP_int(0)).c_updateGroupCallParticipants());
|
||||
}
|
||||
|
||||
|
@ -1642,7 +1700,11 @@ void GroupCall::applyParticipantLocally(
|
|||
| (participantPeer == joinAs() ? Flag::f_self : Flag(0))
|
||||
| (participant->raisedHandRating
|
||||
? Flag::f_raise_hand_rating
|
||||
: Flag(0));
|
||||
: Flag(0))
|
||||
| (participant->e2eState ? Flag::f_public_key : Flag(0));
|
||||
const auto publicKey = participant->e2eState
|
||||
? participant->e2eState->key
|
||||
: TdE2E::PublicKey();
|
||||
_peer->groupCall()->applyLocalUpdate(
|
||||
MTP_updateGroupCallParticipants(
|
||||
inputCall(),
|
||||
|
@ -1659,7 +1721,9 @@ void GroupCall::applyParticipantLocally(
|
|||
MTP_long(participant->raisedHandRating),
|
||||
MTPGroupCallParticipantVideo(),
|
||||
MTPGroupCallParticipantVideo(),
|
||||
AssertIsDebug() MTPint256())), // public_key
|
||||
MTP_int256(
|
||||
MTP_int128(publicKey.a, publicKey.b),
|
||||
MTP_int128(publicKey.c, publicKey.d)))),
|
||||
MTP_int(0)).c_updateGroupCallParticipants());
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,11 @@ struct GroupCallParticipant;
|
|||
class GroupCall;
|
||||
} // namespace Data
|
||||
|
||||
namespace TdE2E {
|
||||
struct ParticipantState;
|
||||
struct CallState;
|
||||
} // namespace TdE2E
|
||||
|
||||
namespace Calls {
|
||||
|
||||
namespace Group {
|
||||
|
@ -49,6 +54,7 @@ struct MuteRequest;
|
|||
struct VolumeRequest;
|
||||
struct ParticipantState;
|
||||
struct JoinInfo;
|
||||
struct ConferenceInfo;
|
||||
struct RejoinEvent;
|
||||
struct RtmpInfo;
|
||||
enum class VideoQuality;
|
||||
|
@ -164,6 +170,8 @@ struct ParticipantVideoParams;
|
|||
const tl::conditional<MTPGroupCallParticipantVideo> &camera,
|
||||
const tl::conditional<MTPGroupCallParticipantVideo> &screen,
|
||||
const std::shared_ptr<ParticipantVideoParams> &existing);
|
||||
[[nodiscard]] std::shared_ptr<TdE2E::ParticipantState> ParseParticipantState(
|
||||
const MTPDgroupCallParticipant &data);
|
||||
|
||||
[[nodiscard]] const std::string &GetCameraEndpoint(
|
||||
const std::shared_ptr<ParticipantVideoParams> ¶ms);
|
||||
|
@ -217,6 +225,9 @@ public:
|
|||
not_null<Delegate*> delegate,
|
||||
Group::JoinInfo info,
|
||||
const MTPInputGroupCall &inputCall);
|
||||
GroupCall(
|
||||
not_null<Delegate*> delegate,
|
||||
Group::ConferenceInfo info);
|
||||
~GroupCall();
|
||||
|
||||
[[nodiscard]] CallId id() const {
|
||||
|
@ -469,6 +480,12 @@ private:
|
|||
return true;
|
||||
}
|
||||
|
||||
GroupCall(
|
||||
not_null<Delegate*> delegate,
|
||||
Group::JoinInfo join,
|
||||
Group::ConferenceInfo conference,
|
||||
const MTPInputGroupCall &inputCall);
|
||||
|
||||
void broadcastPartStart(std::shared_ptr<LoadPartTask> task);
|
||||
void broadcastPartCancel(not_null<LoadPartTask*> task);
|
||||
void mediaChannelDescriptionsStart(
|
||||
|
@ -575,6 +592,7 @@ private:
|
|||
[[nodiscard]] MTPInputGroupCall inputCall() const;
|
||||
|
||||
const not_null<Delegate*> _delegate;
|
||||
const std::shared_ptr<Data::GroupCall> _conferenceCall;
|
||||
not_null<PeerData*> _peer; // Can change in legacy group migration.
|
||||
rpl::event_stream<PeerData*> _peerStream;
|
||||
not_null<History*> _history; // Can change in legacy group migration.
|
||||
|
@ -601,9 +619,13 @@ private:
|
|||
rpl::variable<not_null<PeerData*>> _joinAs;
|
||||
std::vector<not_null<PeerData*>> _possibleJoinAs;
|
||||
QString _joinHash;
|
||||
QString _conferenceLinkSlug;
|
||||
MsgId _conferenceJoinMessageId;
|
||||
int64 _serverTimeMs = 0;
|
||||
crl::time _serverTimeMsGotAt = 0;
|
||||
|
||||
std::unique_ptr<TdE2E::CallState> _e2eState;
|
||||
|
||||
QString _rtmpUrl;
|
||||
QString _rtmpKey;
|
||||
|
||||
|
|
|
@ -52,7 +52,8 @@ object_ptr<Ui::GenericBox> ScreenSharingPrivacyRequestBox() {
|
|||
|
||||
void ConferenceCallJoinConfirm(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
std::shared_ptr<Data::GroupCall> call) {
|
||||
std::shared_ptr<Data::GroupCall> call,
|
||||
Fn<void()> join) {
|
||||
box->setTitle(tr::lng_confcall_join_title());
|
||||
|
||||
box->addRow(
|
||||
|
@ -62,7 +63,11 @@ void ConferenceCallJoinConfirm(
|
|||
st::boxLabel));
|
||||
|
||||
box->addButton(tr::lng_confcall_join_button(), [=] {
|
||||
|
||||
const auto weak = Ui::MakeWeak(box);
|
||||
join();
|
||||
if (const auto strong = weak.data()) {
|
||||
strong->closeBox();
|
||||
}
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] {
|
||||
box->closeBox();
|
||||
|
|
|
@ -65,6 +65,12 @@ struct JoinInfo {
|
|||
bool rtmp = false;
|
||||
};
|
||||
|
||||
struct ConferenceInfo {
|
||||
std::shared_ptr<Data::GroupCall> call;
|
||||
QString linkSlug;
|
||||
MsgId joinMessageId;
|
||||
};
|
||||
|
||||
enum class PanelMode {
|
||||
Default,
|
||||
Wide,
|
||||
|
@ -99,6 +105,7 @@ using StickedTooltips = base::flags<StickedTooltip>;
|
|||
|
||||
void ConferenceCallJoinConfirm(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
std::shared_ptr<Data::GroupCall> call);
|
||||
std::shared_ptr<Data::GroupCall> call,
|
||||
Fn<void()> join);
|
||||
|
||||
} // namespace Calls::Group
|
||||
|
|
|
@ -622,15 +622,22 @@ void GroupCall::applyParticipantsSlice(
|
|||
const auto existingVideoParams = (i != end(_participants))
|
||||
? i->videoParams
|
||||
: nullptr;
|
||||
const auto existingState = (i != end(_participants))
|
||||
? i->e2eState
|
||||
: nullptr;
|
||||
auto videoParams = localUpdate
|
||||
? existingVideoParams
|
||||
: Calls::ParseVideoParams(
|
||||
data.vvideo(),
|
||||
data.vpresentation(),
|
||||
existingVideoParams);
|
||||
auto e2eState = localUpdate
|
||||
? existingState
|
||||
: Calls::ParseParticipantState(data);
|
||||
const auto value = Participant{
|
||||
.peer = participantPeer,
|
||||
.videoParams = std::move(videoParams),
|
||||
.e2eState = std::move(e2eState),
|
||||
.date = data.vdate().v,
|
||||
.lastActive = lastActive,
|
||||
.raisedHandRating = raisedHandRating,
|
||||
|
|
|
@ -17,6 +17,10 @@ namespace Calls {
|
|||
struct ParticipantVideoParams;
|
||||
} // namespace Calls
|
||||
|
||||
namespace TdE2E {
|
||||
struct ParticipantState;
|
||||
} // namespace TdE2E
|
||||
|
||||
namespace Data {
|
||||
|
||||
[[nodiscard]] const std::string &RtmpEndpointId();
|
||||
|
@ -29,6 +33,7 @@ struct LastSpokeTimes {
|
|||
struct GroupCallParticipant {
|
||||
not_null<PeerData*> peer;
|
||||
std::shared_ptr<Calls::ParticipantVideoParams> videoParams;
|
||||
std::shared_ptr<TdE2E::ParticipantState> e2eState;
|
||||
TimeId date = 0;
|
||||
TimeId lastActive = 0;
|
||||
uint64 raisedHandRating = 0;
|
||||
|
|
|
@ -7,16 +7,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "tde2e/tde2e_api.h"
|
||||
|
||||
#include "base/algorithm.h"
|
||||
#include "base/assertion.h"
|
||||
|
||||
#include <tde2e/td/e2e/e2e_api.h>
|
||||
|
||||
namespace TdE2E {
|
||||
|
||||
QByteArray GeneratePrivateKey() {
|
||||
const auto result = tde2e_api::key_generate_temporary_private_key();
|
||||
CallState CreateCallState() {
|
||||
const auto id = tde2e_api::key_generate_temporary_private_key();
|
||||
Assert(id.is_ok());
|
||||
const auto key = tde2e_api::key_to_public_key(id.value());
|
||||
Assert(key.is_ok());
|
||||
|
||||
return {};
|
||||
auto result = CallState{
|
||||
.myKeyId = PrivateKeyId{ .v = uint64(id.value()) },
|
||||
};
|
||||
Assert(key.value().size() == sizeof(result.myKey));
|
||||
memcpy(&result.myKey, key.value().data(), 32);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace TdE2E
|
||||
|
|
|
@ -7,3 +7,31 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/basic_types.h"
|
||||
|
||||
namespace TdE2E {
|
||||
|
||||
struct PrivateKeyId {
|
||||
uint64 v = 0;
|
||||
};
|
||||
|
||||
struct PublicKey {
|
||||
uint64 a = 0;
|
||||
uint64 b = 0;
|
||||
uint64 c = 0;
|
||||
uint64 d = 0;
|
||||
};
|
||||
|
||||
struct ParticipantState {
|
||||
uint64 id = 0;
|
||||
PublicKey key;
|
||||
};
|
||||
|
||||
struct CallState {
|
||||
PrivateKeyId myKeyId;
|
||||
PublicKey myKey;
|
||||
};
|
||||
|
||||
[[nodiscard]] CallState CreateCallState();
|
||||
|
||||
} // namespace TdE2E
|
||||
|
|
|
@ -853,7 +853,7 @@ void SessionNavigation::resolveConferenceCall(const QString &slug) {
|
|||
MTP_int(limit)
|
||||
)).done([=](const MTPphone_GroupCall &result) {
|
||||
_conferenceCallRequestId = 0;
|
||||
_conferenceCallSlug = QString();
|
||||
const auto slug = base::take(_conferenceCallSlug);
|
||||
|
||||
result.data().vcall().match([&](const auto &data) {
|
||||
const auto call = std::make_shared<Data::GroupCall>(
|
||||
|
@ -863,8 +863,15 @@ void SessionNavigation::resolveConferenceCall(const QString &slug) {
|
|||
TimeId(), // scheduleDate
|
||||
false); // rtmp
|
||||
call->processFullCall(result);
|
||||
uiShow()->show(
|
||||
Box(Calls::Group::ConferenceCallJoinConfirm, call));
|
||||
const auto join = [=] {
|
||||
Core::App().calls().startOrJoinConferenceCall(
|
||||
uiShow(),
|
||||
{ .call = call, .linkSlug = slug });
|
||||
};
|
||||
uiShow()->show(Box(
|
||||
Calls::Group::ConferenceCallJoinConfirm,
|
||||
call,
|
||||
join));
|
||||
});
|
||||
}).fail([=] {
|
||||
_conferenceCallRequestId = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue