Added ability to start outgoing call without user confirmation.

This commit is contained in:
23rd
2026-01-26 14:37:42 +03:00
parent b97322c198
commit 5146c05ec3
9 changed files with 31 additions and 17 deletions
@@ -612,7 +612,7 @@ void BoxController::rowRightActionClicked(not_null<PeerListRow*> row) {
auto user = row->peer()->asUser(); auto user = row->peer()->asUser();
Assert(user != nullptr); Assert(user != nullptr);
Core::App().calls().startOutgoingCall(user, false); Core::App().calls().startOutgoingCall(user, {});
} }
void BoxController::receivedCalls(const QVector<MTPMessage> &result) { void BoxController::receivedCalls(const QVector<MTPMessage> &result) {
@@ -196,7 +196,9 @@ Instance::~Instance() {
} }
} }
void Instance::startOutgoingCall(not_null<UserData*> user, bool video) { void Instance::startOutgoingCall(
not_null<UserData*> user,
StartOutgoingCallArgs args) {
if (activateCurrentCall()) { if (activateCurrentCall()) {
return; return;
} }
@@ -210,8 +212,8 @@ void Instance::startOutgoingCall(not_null<UserData*> user, bool video) {
return; return;
} }
requestPermissionsOrFail(crl::guard(this, [=] { requestPermissionsOrFail(crl::guard(this, [=] {
createCall(user, Call::Type::Outgoing, video); createCall(user, Call::Type::Outgoing, args);
}), video); }), args.video);
} }
void Instance::startOrJoinGroupCall( void Instance::startOrJoinGroupCall(
@@ -413,7 +415,7 @@ void Instance::destroyCall(not_null<Call*> call) {
void Instance::createCall( void Instance::createCall(
not_null<UserData*> user, not_null<UserData*> user,
CallType type, CallType type,
bool isVideo) { StartOutgoingCallArgs args) {
struct Performer final { struct Performer final {
explicit Performer(Fn<void(bool, bool, const Performer &)> callback) explicit Performer(Fn<void(bool, bool, const Performer &)> callback)
: callback(std::move(callback)) { : callback(std::move(callback)) {
@@ -455,7 +457,7 @@ void Instance::createCall(
} }
_currentCallChanges.fire_copy(raw); _currentCallChanges.fire_copy(raw);
}); });
performer.callback(isVideo, false, performer); performer.callback(args.video, args.isConfirmed, performer);
} }
void Instance::destroyGroupCall(not_null<GroupCall*> call) { void Instance::destroyGroupCall(not_null<GroupCall*> call) {
@@ -702,7 +704,7 @@ void Instance::handleCallUpdate(
< base::unixtime::now()) { < base::unixtime::now()) {
LOG(("Ignoring too old call.")); LOG(("Ignoring too old call."));
} else { } else {
createCall(user, Call::Type::Incoming, phoneCall.is_video()); createCall(user, Call::Type::Incoming, { phoneCall.is_video() });
_currentCall->handleUpdate(call); _currentCall->handleUpdate(call);
} }
} else if (!_currentCall } else if (!_currentCall
+10 -2
View File
@@ -55,6 +55,11 @@ struct DhConfig;
struct InviteRequest; struct InviteRequest;
struct StartConferenceInfo; struct StartConferenceInfo;
struct StartOutgoingCallArgs {
bool video = false;
bool isConfirmed = false;
};
struct StartGroupCallArgs { struct StartGroupCallArgs {
enum class JoinConfirm { enum class JoinConfirm {
None, None,
@@ -80,7 +85,7 @@ public:
Instance(); Instance();
~Instance(); ~Instance();
void startOutgoingCall(not_null<UserData*> user, bool video); void startOutgoingCall(not_null<UserData*> user, StartOutgoingCallArgs);
void startOrJoinGroupCall( void startOrJoinGroupCall(
std::shared_ptr<Ui::Show> show, std::shared_ptr<Ui::Show> show,
not_null<PeerData*> peer, not_null<PeerData*> peer,
@@ -159,7 +164,10 @@ private:
not_null<Media::Audio::Track*> ensureSoundLoaded(const QString &key); not_null<Media::Audio::Track*> ensureSoundLoaded(const QString &key);
void playSoundOnce(const QString &key); void playSoundOnce(const QString &key);
void createCall(not_null<UserData*> user, CallType type, bool isVideo); void createCall(
not_null<UserData*> user,
CallType type,
StartOutgoingCallArgs);
void destroyCall(not_null<Call*> call); void destroyCall(not_null<Call*> call);
void finishConferenceInvitations(const StartConferenceInfo &args); void finishConferenceInvitations(const StartConferenceInfo &args);
@@ -1191,7 +1191,7 @@ object_ptr<Ui::BoxContent> PrepareCreateCallBox(
const auto &invite = selected.front(); const auto &invite = selected.front();
Core::App().calls().startOutgoingCall( Core::App().calls().startOutgoingCall(
invite.user, invite.user,
invite.video); { invite.video });
} }
finished(true); finished(true);
}; };
@@ -154,7 +154,7 @@ TopBarWidget::TopBarWidget(
_delete->setClickedCallback([=] { _deleteSelection.fire({}); }); _delete->setClickedCallback([=] { _deleteSelection.fire({}); });
_delete->setWidthChangedCallback([=] { updateControlsGeometry(); }); _delete->setWidthChangedCallback([=] { updateControlsGeometry(); });
_clear->setClickedCallback([=] { _clearSelection.fire({}); }); _clear->setClickedCallback([=] { _clearSelection.fire({}); });
_call->setClickedCallback([=] { call(); }); _call->setClickedCallback([=] { call({}); });
_groupCall->setClickedCallback([=] { groupCall(); }); _groupCall->setClickedCallback([=] { groupCall(); });
_menuToggle->setClickedCallback([=] { showPeerMenu(); }); _menuToggle->setClickedCallback([=] { showPeerMenu(); });
_infoToggle->setClickedCallback([=] { toggleInfoSection(); }); _infoToggle->setClickedCallback([=] { toggleInfoSection(); });
@@ -288,12 +288,12 @@ void TopBarWidget::refreshLang() {
InvokeQueued(this, [this] { updateControlsGeometry(); }); InvokeQueued(this, [this] { updateControlsGeometry(); });
} }
void TopBarWidget::call() { void TopBarWidget::call(Calls::StartOutgoingCallArgs args) {
if (_controller->showFrozenError()) { if (_controller->showFrozenError()) {
return; return;
} else if (const auto peer = _activeChat.key.peer()) { } else if (const auto peer = _activeChat.key.peer()) {
if (const auto user = peer->asUser()) { if (const auto user = peer->asUser()) {
Core::App().calls().startOutgoingCall(user, false); Core::App().calls().startOutgoingCall(user, std::move(args));
} }
} }
} }
@@ -36,6 +36,10 @@ namespace Window {
class SessionController; class SessionController;
} // namespace Window } // namespace Window
namespace Calls {
struct StartOutgoingCallArgs;
} // namespace Calls
namespace HistoryView { namespace HistoryView {
class SendActionPainter; class SendActionPainter;
@@ -141,7 +145,7 @@ private:
void updateInfoToggleActive(); void updateInfoToggleActive();
void setupDragOnBackButton(); void setupDragOnBackButton();
void call(); void call(Calls::StartOutgoingCallArgs);
void groupCall(); void groupCall();
void showGroupCallMenu(not_null<PeerData*> peer); void showGroupCallMenu(not_null<PeerData*> peer);
void toggleInfoSection(); void toggleInfoSection();
@@ -76,7 +76,7 @@ QSize Call::countOptimalSize() {
strong->resolveConferenceCall(id, contextId); strong->resolveConferenceCall(id, contextId);
} }
} else if (user) { } else if (user) {
Core::App().calls().startOutgoingCall(user, video); Core::App().calls().startOutgoingCall(user, { video });
} }
}); });
auto maxWidth = st::historyCallWidth; auto maxWidth = st::historyCallWidth;
@@ -549,7 +549,7 @@ void WrapWidget::addProfileCallsButton() {
? st::infoLayerTopBarCall ? st::infoLayerTopBarCall
: st::infoTopBarCall)) : st::infoTopBarCall))
)->addClickHandler([=] { )->addClickHandler([=] {
Core::App().calls().startOutgoingCall(user, false); Core::App().calls().startOutgoingCall(user, {});
}); });
}, _topBar->lifetime()); }, _topBar->lifetime());
@@ -861,7 +861,7 @@ void TopBar::setupActions(not_null<Window::SessionController*> controller) {
tr::lng_profile_action_short_call(tr::now), tr::lng_profile_action_short_call(tr::now),
st::infoProfileTopBarActionCall); st::infoProfileTopBarActionCall);
call->setClickedCallback([=] { call->setClickedCallback([=] {
Core::App().calls().startOutgoingCall(user, false); Core::App().calls().startOutgoingCall(user, {});
}); });
buttons.push_back(call); buttons.push_back(call);
_actions->add(call); _actions->add(call);