mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Join other calls with confirmation.
This commit is contained in:
parent
529c12ea3a
commit
546881c720
11 changed files with 119 additions and 58 deletions
|
@ -1777,6 +1777,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_call_error_audio_io" = "There seems to be a problem with audio playback on your computer. Please make sure that your computer's speakers and microphone are working and try again.";
|
||||
|
||||
"lng_call_bar_hangup" = "End call";
|
||||
"lng_call_leave_to_other_sure" = "Do you want to end your active call and join a voice chat in this group?";
|
||||
|
||||
"lng_call_box_title" = "Calls";
|
||||
"lng_call_box_about" = "You haven't made any Telegram calls yet.";
|
||||
|
@ -1824,6 +1825,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_group_call_leave" = "Leave";
|
||||
"lng_group_call_leave_title" = "Leave voice chat";
|
||||
"lng_group_call_leave_sure" = "Are you sure you want to leave this voice chat?";
|
||||
"lng_group_call_leave_to_other_sure" = "Do you want to leave your active voice chat and join a voice chat in this group?";
|
||||
"lng_group_call_also_end" = "End voice chat";
|
||||
"lng_group_call_settings_title" = "Settings";
|
||||
"lng_group_call_invite_title" = "Invite members";
|
||||
|
|
|
@ -1036,7 +1036,12 @@ void Call::finish(FinishType type, const MTPPhoneCallDiscardReason &reason) {
|
|||
|| (_videoOutgoing->state() != Webrtc::VideoState::Inactive))
|
||||
? MTPphone_DiscardCall::Flag::f_video
|
||||
: MTPphone_DiscardCall::Flag(0);
|
||||
_api.request(MTPphone_DiscardCall(
|
||||
|
||||
// We want to discard request still being sent and processed even if
|
||||
// the call is already destroyed.
|
||||
const auto session = &_user->session();
|
||||
const auto weak = base::make_weak(this);
|
||||
session->api().request(MTPphone_DiscardCall( // We send 'discard' here.
|
||||
MTP_flags(flags),
|
||||
MTP_inputPhoneCall(
|
||||
MTP_long(_id),
|
||||
|
@ -1047,11 +1052,11 @@ void Call::finish(FinishType type, const MTPPhoneCallDiscardReason &reason) {
|
|||
)).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); });
|
||||
_user->session().api().applyUpdates(result);
|
||||
}).fail([this, finalState](const RPCError &error) {
|
||||
crl::on_main(weak, [=] { setState(finalState); });
|
||||
session->api().applyUpdates(result);
|
||||
}).fail(crl::guard(weak, [this, finalState](const RPCError &error) {
|
||||
setState(finalState);
|
||||
}).send();
|
||||
})).send();
|
||||
}
|
||||
|
||||
void Call::setStateQueued(State state) {
|
||||
|
|
|
@ -330,17 +330,22 @@ void GroupCall::finish(FinishType type) {
|
|||
}
|
||||
|
||||
setState(hangupState);
|
||||
_api.request(MTPphone_LeaveGroupCall(
|
||||
|
||||
// We want to leave request still being sent and processed even if
|
||||
// the call is already destroyed.
|
||||
const auto session = &_channel->session();
|
||||
const auto weak = base::make_weak(this);
|
||||
session->api().request(MTPphone_LeaveGroupCall(
|
||||
inputCall(),
|
||||
MTP_int(_mySsrc)
|
||||
)).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) {
|
||||
crl::on_main(weak, [=] { setState(finalState); });
|
||||
session->api().applyUpdates(result);
|
||||
}).fail(crl::guard(weak, [=](const RPCError &error) {
|
||||
setState(finalState);
|
||||
}).send();
|
||||
})).send();
|
||||
}
|
||||
|
||||
void GroupCall::setMuted(MuteState mute) {
|
||||
|
|
|
@ -58,23 +58,13 @@ void Instance::startOutgoingCall(not_null<UserData*> user, bool video) {
|
|||
}), video);
|
||||
}
|
||||
|
||||
void Instance::startGroupCall(not_null<ChannelData*> channel) {
|
||||
if (activateCurrentCall()) {
|
||||
return;
|
||||
}
|
||||
void Instance::startOrJoinGroupCall(not_null<ChannelData*> channel) {
|
||||
destroyCurrentCall();
|
||||
requestPermissionsOrFail(crl::guard(this, [=] {
|
||||
createGroupCall(channel, MTP_inputGroupCall(MTPlong(), MTPlong()));
|
||||
}), false);
|
||||
}
|
||||
|
||||
void Instance::joinGroupCall(
|
||||
not_null<ChannelData*> channel,
|
||||
const MTPInputGroupCall &call) {
|
||||
if (activateCurrentCall()) {
|
||||
return;
|
||||
}
|
||||
requestPermissionsOrFail(crl::guard(this, [=] {
|
||||
createGroupCall(channel, call);
|
||||
const auto call = channel->call();
|
||||
createGroupCall(
|
||||
channel,
|
||||
call ? call->input() : MTP_inputGroupCall(MTPlong(), MTPlong()));
|
||||
}), false);
|
||||
}
|
||||
|
||||
|
@ -432,7 +422,11 @@ void Instance::handleSignalingData(
|
|||
}
|
||||
|
||||
bool Instance::inCall() const {
|
||||
return (_currentCall && _currentCall->state() != Call::State::Busy);
|
||||
if (!_currentCall) {
|
||||
return false;
|
||||
}
|
||||
const auto state = _currentCall->state();
|
||||
return (state != Call::State::Busy);
|
||||
}
|
||||
|
||||
bool Instance::inGroupCall() const {
|
||||
|
@ -446,6 +440,21 @@ bool Instance::inGroupCall() const {
|
|||
&& (state != GroupCall::State::Failed);
|
||||
}
|
||||
|
||||
void Instance::destroyCurrentCall() {
|
||||
if (const auto current = currentCall()) {
|
||||
current->hangup();
|
||||
if (const auto still = currentCall()) {
|
||||
destroyCall(still);
|
||||
}
|
||||
}
|
||||
if (const auto current = currentGroupCall()) {
|
||||
current->hangup();
|
||||
if (const auto still = currentGroupCall()) {
|
||||
destroyGroupCall(still);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Instance::activateCurrentCall() {
|
||||
if (inCall()) {
|
||||
_currentCallPanel->showAndActivate();
|
||||
|
|
|
@ -40,10 +40,7 @@ public:
|
|||
~Instance();
|
||||
|
||||
void startOutgoingCall(not_null<UserData*> user, bool video);
|
||||
void startGroupCall(not_null<ChannelData*> channel);
|
||||
void joinGroupCall(
|
||||
not_null<ChannelData*> channel,
|
||||
const MTPInputGroupCall &call);
|
||||
void startOrJoinGroupCall(not_null<ChannelData*> channel);
|
||||
void handleUpdate(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPUpdate &update);
|
||||
|
@ -53,6 +50,9 @@ public:
|
|||
[[nodiscard]] rpl::producer<Call*> currentCallValue() const;
|
||||
[[nodiscard]] GroupCall *currentGroupCall() const;
|
||||
[[nodiscard]] rpl::producer<GroupCall*> currentGroupCallValue() const;
|
||||
[[nodiscard]] bool inCall() const;
|
||||
[[nodiscard]] bool inGroupCall() const;
|
||||
bool activateCurrentCall();
|
||||
std::shared_ptr<tgcalls::VideoCaptureInterface> getVideoCapture() override;
|
||||
|
||||
void setCurrentAudioDevice(bool input, const QString &deviceId);
|
||||
|
@ -98,9 +98,7 @@ private:
|
|||
void refreshServerConfig(not_null<Main::Session*> session);
|
||||
bytes::const_span updateDhConfig(const MTPmessages_DhConfig &data);
|
||||
|
||||
bool activateCurrentCall();
|
||||
[[nodiscard]] bool inCall() const;
|
||||
[[nodiscard]] bool inGroupCall() const;
|
||||
void destroyCurrentCall();
|
||||
void handleCallUpdate(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPPhoneCall &call);
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "lang/lang_keys.h"
|
||||
#include "mainwidget.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_domain.h" // Core::App().domain().activate().
|
||||
#include "apiwrap.h"
|
||||
#include "layout.h"
|
||||
#include "history/history.h"
|
||||
|
@ -75,6 +76,24 @@ constexpr auto kPinnedMessageTextLimit = 16;
|
|||
});
|
||||
}
|
||||
|
||||
[[nodiscard]] ClickHandlerPtr ChannelCallClickHandler(
|
||||
not_null<ChannelData*> megagroup,
|
||||
uint64 callId) {
|
||||
return std::make_shared<LambdaClickHandler>([=] {
|
||||
const auto call = megagroup->call();
|
||||
if (call && call->id() == callId) {
|
||||
const auto &windows = megagroup->session().windows();
|
||||
if (windows.empty()) {
|
||||
Core::App().domain().activate(&megagroup->session().account());
|
||||
if (windows.empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
windows.front()->startOrJoinGroupCall(megagroup);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void HistoryService::setMessageByAction(const MTPmessageAction &action) {
|
||||
|
@ -518,12 +537,7 @@ HistoryService::PreparedText HistoryService::prepareStartedCallText(
|
|||
const auto channel = history()->peer->asChannel();
|
||||
auto chatText = tr::lng_action_group_call_started_chat(tr::now);
|
||||
if (channel && linkCallId) {
|
||||
result.links.push_back(std::make_shared<LambdaClickHandler>([=] {
|
||||
const auto call = channel->call();
|
||||
if (call && call->id() == linkCallId) {
|
||||
Core::App().calls().joinGroupCall(channel, call->input());
|
||||
}
|
||||
}));
|
||||
result.links.push_back(ChannelCallClickHandler(channel, linkCallId));
|
||||
chatText = textcmdLink(2, chatText);
|
||||
}
|
||||
result.text = tr::lng_action_group_call_started(
|
||||
|
@ -545,12 +559,7 @@ HistoryService::PreparedText HistoryService::prepareInvitedToCallText(
|
|||
result.links.push_back(fromLink());
|
||||
auto linkIndex = 1;
|
||||
if (channel && linkCallId) {
|
||||
result.links.push_back(std::make_shared<LambdaClickHandler>([=] {
|
||||
const auto call = channel->call();
|
||||
if (call && call->id() == linkCallId) {
|
||||
Core::App().calls().joinGroupCall(channel, call->input());
|
||||
}
|
||||
}));
|
||||
result.links.push_back(ChannelCallClickHandler(channel, linkCallId));
|
||||
chatText = textcmdLink(++linkIndex, chatText);
|
||||
}
|
||||
if (users.size() == 1) {
|
||||
|
|
|
@ -5441,8 +5441,8 @@ void HistoryWidget::setupGroupCallTracker() {
|
|||
.text = tr::lng_group_call_no_anonymous(tr::now),
|
||||
});
|
||||
return;
|
||||
} else if (const auto call = channel->call()) {
|
||||
Core::App().calls().joinGroupCall(channel, call->input());
|
||||
} else if (channel->call()) {
|
||||
controller()->startOrJoinGroupCall(channel);
|
||||
}
|
||||
}, _groupCallBar->lifetime());
|
||||
|
||||
|
|
|
@ -221,18 +221,10 @@ void TopBarWidget::call() {
|
|||
void TopBarWidget::groupCall() {
|
||||
if (const auto peer = _activeChat.key.peer()) {
|
||||
if (const auto megagroup = peer->asMegagroup()) {
|
||||
if (megagroup->amAnonymous()) {
|
||||
Ui::ShowMultilineToast({
|
||||
.text = tr::lng_group_call_no_anonymous(tr::now),
|
||||
});
|
||||
} else if (const auto call = megagroup->call()) {
|
||||
Core::App().calls().joinGroupCall(megagroup, call->input());
|
||||
} else {
|
||||
Core::App().calls().startGroupCall(megagroup);
|
||||
}
|
||||
_controller->startOrJoinGroupCall(megagroup);
|
||||
} else if (const auto chat = peer->asChat()) {
|
||||
const auto start = [=](not_null<ChannelData*> megagroup) {
|
||||
Core::App().calls().startGroupCall(megagroup);
|
||||
_controller->startOrJoinGroupCall(megagroup);
|
||||
};
|
||||
peer->session().api().migrateChat(chat, crl::guard(this, start));
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ private:
|
|||
|
||||
void call();
|
||||
void groupCall();
|
||||
void startGroupCall(not_null<ChannelData*> megagroup, bool confirmed);
|
||||
void search();
|
||||
void showMenu();
|
||||
void toggleInfoSection();
|
||||
|
|
|
@ -38,6 +38,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/delayed_activation.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
#include "calls/calls_instance.h" // Core::App().calls().inCall().
|
||||
#include "boxes/calendar_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "mainwidget.h"
|
||||
|
@ -930,6 +932,40 @@ void SessionController::closeThirdSection() {
|
|||
}
|
||||
}
|
||||
|
||||
void SessionController::startOrJoinGroupCall(
|
||||
not_null<ChannelData*> megagroup,
|
||||
bool confirmedLeaveOther) {
|
||||
if (megagroup->amAnonymous()) {
|
||||
Ui::ShowMultilineToast({
|
||||
.text = tr::lng_group_call_no_anonymous(tr::now),
|
||||
});
|
||||
return;
|
||||
}
|
||||
auto &calls = Core::App().calls();
|
||||
const auto confirm = [&](QString text, QString button) {
|
||||
Ui::show(Box<ConfirmBox>(text, button, crl::guard(this, [=] {
|
||||
Ui::hideLayer();
|
||||
startOrJoinGroupCall(megagroup, true);
|
||||
})));
|
||||
};
|
||||
if (!confirmedLeaveOther && calls.inCall()) {
|
||||
// Do you want to leave your active voice chat to join a voice chat in this group?
|
||||
confirm(
|
||||
tr::lng_call_leave_to_other_sure(tr::now),
|
||||
tr::lng_call_bar_hangup(tr::now));
|
||||
} else if (!confirmedLeaveOther && calls.inGroupCall()) {
|
||||
if (calls.currentGroupCall()->channel() == megagroup) {
|
||||
calls.activateCurrentCall();
|
||||
} else {
|
||||
confirm(
|
||||
tr::lng_group_call_leave_to_other_sure(tr::now),
|
||||
tr::lng_group_call_leave(tr::now));
|
||||
}
|
||||
} else {
|
||||
calls.startOrJoinGroupCall(megagroup);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionController::showJumpToDate(Dialogs::Key chat, QDate requestedDate) {
|
||||
const auto currentPeerDate = [&] {
|
||||
if (const auto history = chat.history()) {
|
||||
|
|
|
@ -296,6 +296,10 @@ public:
|
|||
void resizeForThirdSection();
|
||||
void closeThirdSection();
|
||||
|
||||
void startOrJoinGroupCall(
|
||||
not_null<ChannelData*> megagroup,
|
||||
bool confirmedLeaveOther = false);
|
||||
|
||||
void showSection(
|
||||
SectionMemento &&memento,
|
||||
const SectionShow ¶ms = SectionShow()) override;
|
||||
|
|
Loading…
Add table
Reference in a new issue