diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index 7c5584186..a01e06d08 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -202,43 +202,90 @@ void Instance::startOutgoingCall(not_null user, bool video) { }), video); } -void Instance::showStartOrJoinGroupCall( +void Instance::startOrJoinGroupCall( std::shared_ptr show, not_null peer, - const StartGroupCallArgs &args) { - using JoinConfirm = StartGroupCallArgs::JoinConfirm; - const auto context = (args.confirm == JoinConfirm::Always) - ? Group::ChooseJoinAsProcess::Context::JoinWithConfirm - : peer->groupCall() - ? Group::ChooseJoinAsProcess::Context::Join - : args.scheduleNeeded - ? Group::ChooseJoinAsProcess::Context::CreateScheduled - : Group::ChooseJoinAsProcess::Context::Create; - _chooseJoinAs->start(peer, context, [=](object_ptr box) { - show->showBox(std::move(box), Ui::LayerOption::KeepOther); - }, [=](QString text) { - Ui::Toast::Show(show->toastParent(), text); - }, [=](Group::JoinInfo info) { - const auto call = info.peer->groupCall(); - info.joinHash = args.joinHash; - if (call) { - info.rtmp = call->rtmp(); - } - createGroupCall( - std::move(info), - call ? call->input() : MTP_inputGroupCall({}, {})); + StartGroupCallArgs args) { + confirmLeaveCurrent(show, peer, args, [=](StartGroupCallArgs args) { + using JoinConfirm = Calls::StartGroupCallArgs::JoinConfirm; + const auto context = (args.confirm == JoinConfirm::Always) + ? Group::ChooseJoinAsProcess::Context::JoinWithConfirm + : peer->groupCall() + ? Group::ChooseJoinAsProcess::Context::Join + : args.scheduleNeeded + ? Group::ChooseJoinAsProcess::Context::CreateScheduled + : Group::ChooseJoinAsProcess::Context::Create; + _chooseJoinAs->start(peer, context, show, [=](Group::JoinInfo info) { + const auto call = info.peer->groupCall(); + info.joinHash = args.joinHash; + if (call) { + info.rtmp = call->rtmp(); + } + createGroupCall( + std::move(info), + call ? call->input() : MTP_inputGroupCall({}, {})); + }); }); } +void Instance::confirmLeaveCurrent( + std::shared_ptr show, + not_null peer, + StartGroupCallArgs args, + Fn confirmed) { + using JoinConfirm = Calls::StartGroupCallArgs::JoinConfirm; + + auto confirmedArgs = args; + confirmedArgs.confirm = JoinConfirm::None; + + const auto askConfirmation = [&](QString text, QString button) { + show->showBox(Ui::MakeConfirmBox({ + .text = text, + .confirmed = [=] { + show->hideLayer(); + confirmed(confirmedArgs); + }, + .confirmText = button, + })); + }; + if (args.confirm != JoinConfirm::None && inCall()) { + // Do you want to leave your active voice chat + // to join a voice chat in this group? + askConfirmation( + (peer->isBroadcast() + ? tr::lng_call_leave_to_other_sure_channel + : tr::lng_call_leave_to_other_sure)(tr::now), + tr::lng_call_bar_hangup(tr::now)); + } else if (args.confirm != JoinConfirm::None && inGroupCall()) { + const auto now = currentGroupCall()->peer(); + if (now == peer) { + activateCurrentCall(args.joinHash); + } else if (currentGroupCall()->scheduleDate()) { + confirmed(confirmedArgs); + } else { + askConfirmation( + ((peer->isBroadcast() && now->isBroadcast()) + ? tr::lng_group_call_leave_channel_to_other_sure_channel + : now->isBroadcast() + ? tr::lng_group_call_leave_channel_to_other_sure + : peer->isBroadcast() + ? tr::lng_group_call_leave_to_other_sure_channel + : tr::lng_group_call_leave_to_other_sure)(tr::now), + tr::lng_group_call_leave(tr::now)); + } + } else { + confirmed(args); + } +} + void Instance::showStartWithRtmp( std::shared_ptr show, not_null peer) { - _startWithRtmp->start(peer, [=](object_ptr box) { - show->showBox(std::move(box), Ui::LayerOption::KeepOther); - }, [=](QString text) { - Ui::Toast::Show(show->toastParent(), text); - }, [=](Group::JoinInfo info) { - createGroupCall(std::move(info), MTP_inputGroupCall({}, {})); + _startWithRtmp->start(peer, show, [=](Group::JoinInfo info) { + confirmLeaveCurrent(show, peer, {}, [=](auto) { + _startWithRtmp->close(); + createGroupCall(std::move(info), MTP_inputGroupCall({}, {})); + }); }); } diff --git a/Telegram/SourceFiles/calls/calls_instance.h b/Telegram/SourceFiles/calls/calls_instance.h index f3f93532a..750821ca8 100644 --- a/Telegram/SourceFiles/calls/calls_instance.h +++ b/Telegram/SourceFiles/calls/calls_instance.h @@ -65,10 +65,10 @@ public: ~Instance(); void startOutgoingCall(not_null user, bool video); - void showStartOrJoinGroupCall( + void startOrJoinGroupCall( std::shared_ptr show, not_null peer, - const StartGroupCallArgs &args); + StartGroupCallArgs args); void showStartWithRtmp( std::shared_ptr show, not_null peer); @@ -120,6 +120,11 @@ private: Group::JoinInfo info, const MTPInputGroupCall &inputCall); void destroyGroupCall(not_null call); + void confirmLeaveCurrent( + std::shared_ptr show, + not_null peer, + StartGroupCallArgs args, + Fn confirmed); void requestPermissionOrFail( Platform::PermissionType type, diff --git a/Telegram/SourceFiles/calls/group/calls_choose_join_as.cpp b/Telegram/SourceFiles/calls/group/calls_choose_join_as.cpp index 27a4cd15c..2c3b6e0ce 100644 --- a/Telegram/SourceFiles/calls/group/calls_choose_join_as.cpp +++ b/Telegram/SourceFiles/calls/group/calls_choose_join_as.cpp @@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/layers/generic_box.h" #include "ui/boxes/choose_date_time.h" #include "ui/text/text_utilities.h" +#include "ui/toast/toast.h" #include "boxes/peer_list_box.h" #include "base/unixtime.h" #include "base/timer_rpl.h" @@ -308,8 +309,7 @@ ChooseJoinAsProcess::~ChooseJoinAsProcess() { void ChooseJoinAsProcess::start( not_null peer, Context context, - Fn)> showBox, - Fn showToast, + std::shared_ptr show, Fn done, PeerData *changingJoinAsFrom) { Expects(done != nullptr); @@ -320,8 +320,7 @@ void ChooseJoinAsProcess::start( if (_request) { if (_request->peer == peer && !isScheduled) { _request->context = context; - _request->showBox = std::move(showBox); - _request->showToast = std::move(showToast); + _request->show = std::move(show); _request->done = std::move(done); _request->changingJoinAsFrom = changingJoinAsFrom; return; @@ -330,13 +329,10 @@ void ChooseJoinAsProcess::start( _request = nullptr; } - const auto createRequest = [=, - showToast = std::move(showToast), - done = std::move(done)] { + const auto createRequest = [=, done = std::move(done)] { _request = std::make_unique(ChannelsListRequest{ .peer = peer, - .showBox = showBox, - .showToast = std::move(showToast), + .show = show, .done = std::move(done), .context = context, .changingJoinAsFrom = changingJoinAsFrom }); @@ -350,7 +346,7 @@ void ChooseJoinAsProcess::start( createRequest(); finish(info); }); - showBox(std::move(box)); + show->showBox(std::move(box)); return; } @@ -411,7 +407,9 @@ void ChooseJoinAsProcess::processList( auto info = JoinInfo{ .peer = peer, .joinAs = self }; const auto selectedId = peer->groupCallDefaultJoinAs(); if (list.empty()) { - _request->showToast(Lang::Hard::ServerError()); + Ui::Toast::Show( + _request->show->toastParent(), + Lang::Hard::ServerError()); return; } info.joinAs = [&]() -> not_null { @@ -464,7 +462,7 @@ void ChooseJoinAsProcess::processList( const auto safeFinish = crl::guard(guard, [=] { finish(info); }); const auto filter = [=](const auto &...) { if (guard) { - _request->showBox(Box( + _request->show->showBox(Box( ScheduleGroupCallBox, info, crl::guard(guard, [=](auto info) { finish(info); }))); @@ -485,7 +483,7 @@ void ChooseJoinAsProcess::processList( }, _request->lifetime); _request->box = box.data(); - _request->showBox(std::move(box)); + _request->show->showBox(std::move(box)); return; } auto box = Box( @@ -499,7 +497,7 @@ void ChooseJoinAsProcess::processList( }, _request->lifetime); _request->box = box.data(); - _request->showBox(std::move(box)); + _request->show->showBox(std::move(box)); } } // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/group/calls_choose_join_as.h b/Telegram/SourceFiles/calls/group/calls_choose_join_as.h index f078497c1..eb899b556 100644 --- a/Telegram/SourceFiles/calls/group/calls_choose_join_as.h +++ b/Telegram/SourceFiles/calls/group/calls_choose_join_as.h @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class PeerData; namespace Ui { +class Show; class BoxContent; } // namespace Ui @@ -36,8 +37,7 @@ public: void start( not_null peer, Context context, - Fn)> showBox, - Fn showToast, + std::shared_ptr show, Fn done, PeerData *changingJoinAsFrom = nullptr); @@ -48,8 +48,7 @@ private: struct ChannelsListRequest { not_null peer; - Fn)> showBox; - Fn showToast; + std::shared_ptr show; Fn done; base::has_weak_ptr guard; QPointer box; diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp index 5cb34b58e..3de65526e 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp @@ -1328,8 +1328,7 @@ void Panel::chooseJoinAs() { _joinAsProcess.start( _peer, context, - showBoxCallback, - showToastCallback, + std::make_shared(this), callback, _call->joinAs()); } @@ -1470,6 +1469,10 @@ void Panel::showBox( _layerBg->showBox(std::move(box), options, animated); } +void Panel::hideLayer(anim::type animated) { + _layerBg->hideAll(animated); +} + void Panel::kickParticipantSure(not_null participantPeer) { if (const auto chat = _peer->asChat()) { chat->session().api().chatParticipants().kick(chat, participantPeer); @@ -2555,4 +2558,38 @@ not_null Panel::widget() const { return _window.widget(); } +Show::Show(not_null panel) +: _panel(base::make_weak(panel.get())) { +} + +Show::~Show() = default; + +void Show::showBox( + object_ptr content, + Ui::LayerOptions options) const { + if (const auto panel = _panel.get()) { + panel->showBox(std::move(content), options); + } +} + +void Show::hideLayer() const { + if (const auto panel = _panel.get()) { + panel->hideLayer(); + } +} + +not_null Show::toastParent() const { + const auto panel = _panel.get(); + Assert(panel != nullptr); + return panel->widget(); +} + +bool Show::valid() const { + return !_panel.empty(); +} + +Show::operator bool() const { + return valid(); +} + } // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.h b/Telegram/SourceFiles/calls/group/calls_group_panel.h index 731bb874d..6dfca8b28 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.h +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.h @@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "calls/group/ui/desktop_capture_choose_source.h" #include "ui/effects/animations.h" #include "ui/gl/gl_window.h" +#include "ui/layers/show.h" #include "ui/rp_widget.h" class Image; @@ -74,11 +75,14 @@ enum class PanelMode; enum class StickedTooltip; class MicLevelTester; -class Panel final : private Ui::DesktopCapture::ChooseSourceDelegate { +class Panel final + : public base::has_weak_ptr + , private Ui::DesktopCapture::ChooseSourceDelegate { public: Panel(not_null call); ~Panel(); + [[nodiscard]] not_null widget() const; [[nodiscard]] not_null call() const; [[nodiscard]] bool isActive() const; @@ -88,6 +92,7 @@ public: object_ptr box, Ui::LayerOptions options, anim::type animated = anim::type::normal); + void hideLayer(anim::type animated = anim::type::normal); void minimize(); void close(); @@ -111,7 +116,6 @@ private: }; [[nodiscard]] not_null window() const; - [[nodiscard]] not_null widget() const; [[nodiscard]] PanelMode mode() const; @@ -269,4 +273,21 @@ private: }; +class Show : public Ui::Show { +public: + explicit Show(not_null panel); + ~Show(); + void showBox( + object_ptr content, + Ui::LayerOptions options = Ui::LayerOption::KeepOther) const override; + void hideLayer() const override; + [[nodiscard]] not_null toastParent() const override; + [[nodiscard]] bool valid() const override; + operator bool() const override; + +private: + const base::weak_ptr _panel; + +}; + } // namespace Calls::Group diff --git a/Telegram/SourceFiles/calls/group/calls_group_rtmp.cpp b/Telegram/SourceFiles/calls/group/calls_group_rtmp.cpp index 9859387d7..1891a2ca0 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_rtmp.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_rtmp.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/boxes/confirm_box.h" #include "ui/layers/generic_box.h" #include "ui/text/text_utilities.h" +#include "ui/toast/toast.h" #include "ui/widgets/buttons.h" #include "ui/widgets/popup_menu.h" #include "ui/wrap/vertical_layout.h" @@ -39,8 +40,7 @@ void StartWithBox( not_null box, Fn done, Fn revoke, - Fn)> showBox, - Fn showToast, + std::shared_ptr show, rpl::producer &&data) { struct State { base::unique_qptr menu; @@ -50,8 +50,7 @@ void StartWithBox( StartRtmpProcess::FillRtmpRows( box->verticalLayout(), true, - std::move(showBox), - std::move(showToast), + std::move(show), std::move(data), &st::boxLabel, &st::groupCallRtmpShowButton, @@ -97,23 +96,19 @@ void StartWithBox( } // namespace StartRtmpProcess::~StartRtmpProcess() { - if (_request) { - _request->peer->session().api().request(_request->id).cancel(); - } + close(); } void StartRtmpProcess::start( not_null peer, - Fn)> showBox, - Fn showToast, + std::shared_ptr show, Fn done) { Expects(done != nullptr); const auto session = &peer->session(); if (_request) { if (_request->peer == peer) { - _request->showBox = std::move(showBox); - _request->showToast = std::move(showToast); + _request->show = std::move(show); _request->done = std::move(done); return; } @@ -123,9 +118,9 @@ void StartRtmpProcess::start( _request = std::make_unique( RtmpRequest{ .peer = peer, - .showBox = std::move(showBox), - .showToast = std::move(showToast), - .done = std::move(done) }); + .show = std::move(show), + .done = std::move(done), + }); session->account().sessionChanges( ) | rpl::start_with_next([=] { _request = nullptr; @@ -134,6 +129,16 @@ void StartRtmpProcess::start( requestUrl(false); } +void StartRtmpProcess::close() { + if (_request) { + _request->peer->session().api().request(_request->id).cancel(); + if (const auto strong = _request->box.data()) { + strong->closeBox(); + } + _request = nullptr; + } +} + void StartRtmpProcess::requestUrl(bool revoke) { const auto session = &_request->peer->session(); _request->id = session->api().request(MTPphone_GetGroupCallStreamRtmpUrl( @@ -146,7 +151,9 @@ void StartRtmpProcess::requestUrl(bool revoke) { }); processUrl(std::move(data)); }).fail([=] { - _request->showToast(Lang::Hard::ServerError()); + Ui::Toast::Show( + _request->show->toastParent(), + Lang::Hard::ServerError()); }).send(); } @@ -158,15 +165,8 @@ void StartRtmpProcess::processUrl(RtmpInfo data) { } void StartRtmpProcess::finish(JoinInfo info) { - const auto done = std::move(_request->done); - const auto box = _request->box; - const auto current = _request->data.current(); - _request = nullptr; - info.rtmpInfo = current; - done(std::move(info)); - if (const auto strong = box.data()) { - strong->closeBox(); - } + info.rtmpInfo = _request->data.current(); + _request->done(std::move(info)); } void StartRtmpProcess::createBox() { @@ -176,7 +176,7 @@ void StartRtmpProcess::createBox() { }; auto revoke = [=] { const auto guard = base::make_weak(&_request->guard); - _request->showBox(Ui::MakeConfirmBox({ + _request->show->showBox(Ui::MakeConfirmBox({ .text = tr::lng_group_call_rtmp_revoke_sure(), .confirmed = crl::guard(guard, [=](Fn &&close) { requestUrl(true); @@ -189,22 +189,20 @@ void StartRtmpProcess::createBox() { StartWithBox, std::move(done), std::move(revoke), - _request->showBox, - _request->showToast, + _request->show, _request->data.value()); object->boxClosing( ) | rpl::start_with_next([=] { _request = nullptr; }, _request->lifetime); _request->box = Ui::MakeWeak(object.data()); - _request->showBox(std::move(object)); + _request->show->showBox(std::move(object)); } void StartRtmpProcess::FillRtmpRows( not_null container, bool divider, - Fn)> showBox, - Fn showToast, + std::shared_ptr show, rpl::producer &&data, const style::FlatLabel *labelStyle, const style::IconButton *showButtonStyle, @@ -230,6 +228,9 @@ void StartRtmpProcess::FillRtmpRows( data ) | rpl::map([=](const auto &d) { return d.url; }); + const auto showToast = [=](const QString &text) { + Ui::Toast::Show(show->toastParent(), text); + }; const auto addButton = [&]( bool key, rpl::producer &&text) { @@ -332,7 +333,7 @@ void StartRtmpProcess::FillRtmpRows( newValue); }; if (!state->warned && state->hidden.current()) { - showBox(Ui::MakeConfirmBox({ + show->showBox(Ui::MakeConfirmBox({ .text = tr::lng_group_call_rtmp_key_warning( Ui::Text::RichLangValue), .confirmed = [=](Fn &&close) { diff --git a/Telegram/SourceFiles/calls/group/calls_group_rtmp.h b/Telegram/SourceFiles/calls/group/calls_group_rtmp.h index 16c1790c2..eb5d4b5fa 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_rtmp.h +++ b/Telegram/SourceFiles/calls/group/calls_group_rtmp.h @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL class PeerData; namespace Ui { +class Show; class BoxContent; class VerticalLayout; } // namespace Ui @@ -36,15 +37,14 @@ public: void start( not_null peer, - Fn)> showBox, - Fn showToast, + std::shared_ptr show, Fn done); + void close(); static void FillRtmpRows( not_null container, bool divider, - Fn)> showBox, - Fn showToast, + std::shared_ptr show, rpl::producer &&data, const style::FlatLabel *labelStyle, const style::IconButton *showButtonStyle, @@ -61,8 +61,7 @@ private: struct RtmpRequest { not_null peer; rpl::variable data; - Fn)> showBox; - Fn showToast; + std::shared_ptr show; Fn done; base::has_weak_ptr guard; QPointer box; diff --git a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp index 9b027a450..a9d803679 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp @@ -733,18 +733,10 @@ void SettingsBox( return true; }); - StartRtmpProcess::FillRtmpRows( layout, false, - [=](object_ptr &&object) { - box->getDelegate()->show(std::move(object)); - }, - [=](QString text) { - Ui::Toast::Show( - box->getDelegate()->outerContainer(), - text); - }, + std::make_shared(box), state->data.events(), &st::groupCallBoxLabel, &st::groupCallSettingsRtmpShowButton, diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 97f30ba3c..b745f3c39 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -1273,54 +1273,11 @@ void SessionController::showPeer(not_null peer, MsgId msgId) { void SessionController::startOrJoinGroupCall( not_null peer, - const Calls::StartGroupCallArgs &args) { - using JoinConfirm = Calls::StartGroupCallArgs::JoinConfirm; - auto &calls = Core::App().calls(); - auto confirmedArgs = args; - confirmedArgs.confirm = JoinConfirm::None; - - const auto askConfirmation = [&](QString text, QString button) { - show(Ui::MakeConfirmBox({ - .text = text, - .confirmed = crl::guard(this,[=] { - hideLayer(); - startOrJoinGroupCall(peer, confirmedArgs); - }), - .confirmText = button, - })); - }; - if (args.confirm != JoinConfirm::None && calls.inCall()) { - // Do you want to leave your active voice chat - // to join a voice chat in this group? - askConfirmation( - (peer->isBroadcast() - ? tr::lng_call_leave_to_other_sure_channel - : tr::lng_call_leave_to_other_sure)(tr::now), - tr::lng_call_bar_hangup(tr::now)); - } else if (args.confirm != JoinConfirm::None - && calls.inGroupCall()) { - const auto now = calls.currentGroupCall()->peer(); - if (now == peer) { - calls.activateCurrentCall(args.joinHash); - } else if (calls.currentGroupCall()->scheduleDate()) { - startOrJoinGroupCall(peer, confirmedArgs); - } else { - askConfirmation( - ((peer->isBroadcast() && now->isBroadcast()) - ? tr::lng_group_call_leave_channel_to_other_sure_channel - : now->isBroadcast() - ? tr::lng_group_call_leave_channel_to_other_sure - : peer->isBroadcast() - ? tr::lng_group_call_leave_to_other_sure_channel - : tr::lng_group_call_leave_to_other_sure)(tr::now), - tr::lng_group_call_leave(tr::now)); - } - } else { - calls.showStartOrJoinGroupCall( - std::make_shared(this), - peer, - args); - } + Calls::StartGroupCallArgs args) { + Core::App().calls().startOrJoinGroupCall( + std::make_shared(this), + peer, + args); } void SessionController::showCalendar(Dialogs::Key chat, QDate requestedDate) { diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index 4d5338825..e503f7d57 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -387,7 +387,7 @@ public: void startOrJoinGroupCall( not_null peer, - const Calls::StartGroupCallArgs &args); + Calls::StartGroupCallArgs args); void showSection( std::shared_ptr memento,