Join voice chats by invite links.

This commit is contained in:
John Preston 2021-03-11 00:03:20 +04:00
parent c587335ae1
commit c0df6f7bca
9 changed files with 56 additions and 12 deletions

View file

@ -177,6 +177,7 @@ GroupCall::GroupCall(
, _api(&_peer->session().mtp()) , _api(&_peer->session().mtp())
, _joinAs(info.joinAs) , _joinAs(info.joinAs)
, _possibleJoinAs(std::move(info.possibleJoinAs)) , _possibleJoinAs(std::move(info.possibleJoinAs))
, _joinHash(info.joinHash)
, _lastSpokeCheckTimer([=] { checkLastSpoke(); }) , _lastSpokeCheckTimer([=] { checkLastSpoke(); })
, _checkJoinedTimer([=] { checkJoined(); }) , _checkJoinedTimer([=] { checkJoined(); })
, _pushToTalkCancelTimer([=] { pushToTalkCancel(); }) , _pushToTalkCancelTimer([=] { pushToTalkCancel(); })
@ -390,6 +391,15 @@ void GroupCall::rejoin() {
rejoin(_joinAs); rejoin(_joinAs);
} }
void GroupCall::rejoinWithHash(const QString &hash) {
if (!hash.isEmpty()
&& (muted() == MuteState::ForceMuted
|| muted() == MuteState::RaisedHand)) {
_joinHash = hash;
rejoin();
}
}
void GroupCall::rejoin(not_null<PeerData*> as) { void GroupCall::rejoin(not_null<PeerData*> as) {
if (state() != State::Joining if (state() != State::Joining
&& state() != State::Joined && state() != State::Joined
@ -436,12 +446,14 @@ void GroupCall::rejoin(not_null<PeerData*> as) {
const auto wasMuteState = muted(); const auto wasMuteState = muted();
using Flag = MTPphone_JoinGroupCall::Flag; using Flag = MTPphone_JoinGroupCall::Flag;
_api.request(MTPphone_JoinGroupCall( _api.request(MTPphone_JoinGroupCall(
MTP_flags((wasMuteState != MuteState::Active) MTP_flags((wasMuteState != MuteState::Active
? Flag::f_muted ? Flag::f_muted
: Flag(0)), : Flag(0)) | (_joinHash.isEmpty()
? Flag(0)
: Flag::f_invite_hash)),
inputCall(), inputCall(),
_joinAs->input, _joinAs->input,
MTPstring(), // #TODO calls invite_hash MTP_string(_joinHash),
MTP_dataJSON(MTP_bytes(json)) MTP_dataJSON(MTP_bytes(json))
)).done([=](const MTPUpdates &updates) { )).done([=](const MTPUpdates &updates) {
_mySsrc = ssrc; _mySsrc = ssrc;

View file

@ -113,6 +113,7 @@ public:
void hangup(); void hangup();
void discard(); void discard();
void rejoinAs(Group::JoinInfo info); void rejoinAs(Group::JoinInfo info);
void rejoinWithHash(const QString &hash);
void join(const MTPInputGroupCall &inputCall); void join(const MTPInputGroupCall &inputCall);
void handleUpdate(const MTPGroupCall &call); void handleUpdate(const MTPGroupCall &call);
void handleUpdate(const MTPDupdateGroupCallParticipants &data); void handleUpdate(const MTPDupdateGroupCallParticipants &data);
@ -271,6 +272,7 @@ private:
not_null<PeerData*> _joinAs; not_null<PeerData*> _joinAs;
std::vector<not_null<PeerData*>> _possibleJoinAs; std::vector<not_null<PeerData*>> _possibleJoinAs;
QString _joinHash;
rpl::variable<MuteState> _muted = MuteState::Muted; rpl::variable<MuteState> _muted = MuteState::Muted;
bool _initialMuteStateSent = false; bool _initialMuteStateSent = false;

View file

@ -43,6 +43,7 @@ struct JoinInfo {
not_null<PeerData*> peer; not_null<PeerData*> peer;
not_null<PeerData*> joinAs; not_null<PeerData*> joinAs;
std::vector<not_null<PeerData*>> possibleJoinAs; std::vector<not_null<PeerData*>> possibleJoinAs;
QString joinHash;
}; };
} // namespace Calls::Group } // namespace Calls::Group

View file

@ -190,7 +190,7 @@ object_ptr<ShareBox> ShareInviteLinkBox(
.bottomWidget = std::move(bottom), .bottomWidget = std::move(bottom),
.stMultiSelect = &st::groupCallMultiSelect, .stMultiSelect = &st::groupCallMultiSelect,
.stComment = &st::groupCallShareBoxComment, .stComment = &st::groupCallShareBoxComment,
.stItem = &st::groupCallShareBoxList }); .st = &st::groupCallShareBoxList });
*box = result.data(); *box = result.data();
return result; return result;
} }

View file

@ -61,7 +61,9 @@ void Instance::startOutgoingCall(not_null<UserData*> user, bool video) {
}), video); }), video);
} }
void Instance::startOrJoinGroupCall(not_null<PeerData*> peer) { void Instance::startOrJoinGroupCall(
not_null<PeerData*> peer,
const QString &joinHash) {
const auto context = peer->groupCall() const auto context = peer->groupCall()
? Group::ChooseJoinAsProcess::Context::Join ? Group::ChooseJoinAsProcess::Context::Join
: Group::ChooseJoinAsProcess::Context::Create; : Group::ChooseJoinAsProcess::Context::Create;
@ -71,6 +73,7 @@ void Instance::startOrJoinGroupCall(not_null<PeerData*> peer) {
Ui::Toast::Show(text); Ui::Toast::Show(text);
}, [=](Group::JoinInfo info) { }, [=](Group::JoinInfo info) {
const auto call = info.peer->groupCall(); const auto call = info.peer->groupCall();
info.joinHash = joinHash;
createGroupCall( createGroupCall(
std::move(info), std::move(info),
call ? call->input() : MTP_inputGroupCall(MTPlong(), MTPlong())); call ? call->input() : MTP_inputGroupCall(MTPlong(), MTPlong()));
@ -486,11 +489,14 @@ bool Instance::hasActivePanel(not_null<Main::Session*> session) const {
return false; return false;
} }
bool Instance::activateCurrentCall() { bool Instance::activateCurrentCall(const QString &joinHash) {
if (inCall()) { if (inCall()) {
_currentCallPanel->showAndActivate(); _currentCallPanel->showAndActivate();
return true; return true;
} else if (inGroupCall()) { } else if (inGroupCall()) {
if (!joinHash.isEmpty()) {
_currentGroupCall->rejoinWithHash(joinHash);
}
_currentGroupCallPanel->showAndActivate(); _currentGroupCallPanel->showAndActivate();
return true; return true;
} }

View file

@ -43,7 +43,9 @@ public:
~Instance(); ~Instance();
void startOutgoingCall(not_null<UserData*> user, bool video); void startOutgoingCall(not_null<UserData*> user, bool video);
void startOrJoinGroupCall(not_null<PeerData*> peer); void startOrJoinGroupCall(
not_null<PeerData*> peer,
const QString &joinHash = QString());
void handleUpdate( void handleUpdate(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const MTPUpdate &update); const MTPUpdate &update);
@ -57,7 +59,7 @@ public:
[[nodiscard]] bool inGroupCall() const; [[nodiscard]] bool inGroupCall() const;
[[nodiscard]] bool hasActivePanel( [[nodiscard]] bool hasActivePanel(
not_null<Main::Session*> session) const; not_null<Main::Session*> session) const;
bool activateCurrentCall(); bool activateCurrentCall(const QString &joinHash = QString());
bool minimizeCurrentActiveCall(); bool minimizeCurrentActiveCall();
bool closeCurrentActiveCall(); bool closeCurrentActiveCall();
auto getVideoCapture() auto getVideoCapture()

View file

@ -299,6 +299,9 @@ bool ResolveUsername(
} }
: Navigation::RepliesByLinkInfo{ v::null }, : Navigation::RepliesByLinkInfo{ v::null },
.startToken = startToken, .startToken = startToken,
.voicechatHash = (params.contains(u"voicechat"_q)
? std::make_optional(params.value(u"voicechat"_q))
: std::nullopt),
.clickFromMessageId = fromMessageId, .clickFromMessageId = fromMessageId,
}); });
return true; return true;

View file

@ -151,7 +151,7 @@ void SessionNavigation::resolveChannelById(
return; return;
} }
const auto fail = [=] { const auto fail = [=] {
Ui::show(Box<InformBox>(tr::lng_error_post_link_invalid(tr::now))); Ui::Toast::Show(tr::lng_error_post_link_invalid(tr::now));
}; };
_session->api().request(base::take(_resolveRequestId)).cancel(); _session->api().request(base::take(_resolveRequestId)).cancel();
_resolveRequestId = _session->api().request(MTPchannels_GetChannels( _resolveRequestId = _session->api().request(MTPchannels_GetChannels(
@ -175,6 +175,21 @@ void SessionNavigation::resolveChannelById(
void SessionNavigation::showPeerByLinkResolved( void SessionNavigation::showPeerByLinkResolved(
not_null<PeerData*> peer, not_null<PeerData*> peer,
const PeerByLinkInfo &info) { const PeerByLinkInfo &info) {
if (info.voicechatHash && peer->isChannel()) {
const auto hash = *info.voicechatHash;
_session->api().request(base::take(_resolveRequestId)).cancel();
_resolveRequestId = _session->api().request(
MTPchannels_GetFullChannel(peer->asChannel()->inputChannel)
).done([=](const MTPmessages_ChatFull &result) {
_session->api().processFullPeer(peer, result);
if (const auto call = peer->groupCall()) {
parentController()->startOrJoinGroupCall(peer, hash);
} else {
Ui::Toast::Show(tr::lng_error_post_link_invalid(tr::now));
}
}).send();
return;
}
auto params = SectionShow{ auto params = SectionShow{
SectionShow::Way::Forward SectionShow::Way::Forward
}; };
@ -933,6 +948,7 @@ void SessionController::closeThirdSection() {
void SessionController::startOrJoinGroupCall( void SessionController::startOrJoinGroupCall(
not_null<PeerData*> peer, not_null<PeerData*> peer,
QString joinHash,
bool confirmedLeaveOther) { bool confirmedLeaveOther) {
//const auto channel = peer->asChannel(); // #TODO calls //const auto channel = peer->asChannel(); // #TODO calls
//if (channel && channel->amAnonymous()) { //if (channel && channel->amAnonymous()) {
@ -945,7 +961,7 @@ void SessionController::startOrJoinGroupCall(
const auto confirm = [&](QString text, QString button) { const auto confirm = [&](QString text, QString button) {
Ui::show(Box<ConfirmBox>(text, button, crl::guard(this, [=] { Ui::show(Box<ConfirmBox>(text, button, crl::guard(this, [=] {
Ui::hideLayer(); Ui::hideLayer();
startOrJoinGroupCall(peer, true); startOrJoinGroupCall(peer, joinHash, true);
}))); })));
}; };
if (!confirmedLeaveOther && calls.inCall()) { if (!confirmedLeaveOther && calls.inCall()) {
@ -956,14 +972,14 @@ void SessionController::startOrJoinGroupCall(
tr::lng_call_bar_hangup(tr::now)); tr::lng_call_bar_hangup(tr::now));
} else if (!confirmedLeaveOther && calls.inGroupCall()) { } else if (!confirmedLeaveOther && calls.inGroupCall()) {
if (calls.currentGroupCall()->peer() == peer) { if (calls.currentGroupCall()->peer() == peer) {
calls.activateCurrentCall(); calls.activateCurrentCall(joinHash);
} else { } else {
confirm( confirm(
tr::lng_group_call_leave_to_other_sure(tr::now), tr::lng_group_call_leave_to_other_sure(tr::now),
tr::lng_group_call_leave(tr::now)); tr::lng_group_call_leave(tr::now));
} }
} else { } else {
calls.startOrJoinGroupCall(peer); calls.startOrJoinGroupCall(peer, joinHash);
} }
} }

View file

@ -151,6 +151,7 @@ public:
MsgId messageId = ShowAtUnreadMsgId; MsgId messageId = ShowAtUnreadMsgId;
RepliesByLinkInfo repliesInfo; RepliesByLinkInfo repliesInfo;
QString startToken; QString startToken;
std::optional<QString> voicechatHash;
FullMsgId clickFromMessageId; FullMsgId clickFromMessageId;
}; };
void showPeerByLink(const PeerByLinkInfo &info); void showPeerByLink(const PeerByLinkInfo &info);
@ -299,6 +300,7 @@ public:
void startOrJoinGroupCall( void startOrJoinGroupCall(
not_null<PeerData*> peer, not_null<PeerData*> peer,
QString joinHash = QString(),
bool confirmedLeaveOther = false); bool confirmedLeaveOther = false);
void showSection( void showSection(