diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 3a7c926bd7..ea9eddd0b8 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -1490,7 +1490,7 @@ confcallLinkButton: RoundButton(defaultActiveButton) { style: semiboldTextStyle; } confcallLinkBox: Box(defaultBox) { - buttonPadding: margins(22px, 11px, 22px, 64px); + buttonPadding: margins(12px, 11px, 24px, 96px); buttonHeight: 42px; button: confcallLinkButton; shadowIgnoreTopSkip: true; @@ -1513,3 +1513,6 @@ confcallLinkCenteredText: FlatLabel(defaultFlatLabel) { confcallLinkFooterOr: FlatLabel(confcallLinkCenteredText) { textFg: windowSubTextFg; } +confcallLinkFooterOrTop: 12px; +confcallLinkFooterOrSkip: 8px; +confcallLinkFooterOrLineTop: 9px; diff --git a/Telegram/SourceFiles/calls/group/calls_group_common.cpp b/Telegram/SourceFiles/calls/group/calls_group_common.cpp index 106fa229d8..9dad51c406 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_common.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_common.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/base_platform_info.h" #include "boxes/share_box.h" +#include "core/local_url_handlers.h" #include "data/data_group_call.h" #include "info/bot/starref/info_bot_starref_common.h" #include "ui/boxes/boost_box.h" @@ -130,19 +131,46 @@ void ShowConferenceCallLinkBox( FastShareLink(controller, link); }; preview->setClickedCallback(copyCallback); - [[maybe_unused]] const auto copy = box->addButton( - tr::lng_group_invite_copy(), - copyCallback, - st::confcallLinkCopyButton); [[maybe_unused]] const auto share = box->addButton( tr::lng_group_invite_share(), shareCallback, st::confcallLinkShareButton); + [[maybe_unused]] const auto copy = box->addButton( + tr::lng_group_invite_copy(), + copyCallback, + st::confcallLinkCopyButton); + + rpl::combine( + box->widthValue(), + copy->widthValue(), + share->widthValue() + ) | rpl::start_with_next([=] { + const auto width = st::boxWideWidth; + const auto padding = st::confcallLinkBox.buttonPadding; + const auto available = width - 2 * padding.right(); + const auto buttonWidth = (available - padding.left()) / 2; + copy->resizeToWidth(buttonWidth); + share->resizeToWidth(buttonWidth); + copy->moveToLeft(padding.right(), copy->y(), width); + share->moveToRight(padding.right(), share->y(), width); + }, box->lifetime()); const auto sep = Ui::CreateChild( copy->parentWidget(), tr::lng_confcall_link_or(), st::confcallLinkFooterOr); + sep->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(sep); + const auto text = sep->textMaxWidth(); + const auto white = (sep->width() - 2 * text) / 2; + const auto line = st::lineWidth; + const auto top = st::confcallLinkFooterOrLineTop; + const auto fg = st::windowSubTextFg->b; + p.setOpacity(0.4); + p.fillRect(0, top, white, line, fg); + p.fillRect(sep->width() - white, top, white, line, fg); + }, sep->lifetime()); + const auto footer = Ui::CreateChild( copy->parentWidget(), tr::lng_confcall_link_join( @@ -154,22 +182,29 @@ void ShowConferenceCallLinkBox( Ui::Text::WithEntities), st::confcallLinkCenteredText); footer->setTryMakeSimilarLines(true); + footer->setClickHandlerFilter([=](const auto &...) { + const auto local = Core::TryConvertUrlToLocal(link); + controller->resolveConferenceCall( + local, + crl::guard(box, [=](bool ok) { if (ok) box->closeBox(); }), + true); + return false; + }); copy->geometryValue() | rpl::start_with_next([=](QRect geometry) { const auto width = st::boxWideWidth - st::boxRowPadding.left() - st::boxRowPadding.right(); footer->resizeToWidth(width); - const auto &st = box->getDelegate()->style(); - const auto top = geometry.y() + geometry.height(); - const auto available = st.buttonPadding.bottom(); - const auto footerHeight = sep->height() + footer->height(); - const auto skip = (available - footerHeight) / 2; + const auto top = geometry.y() + + geometry.height() + + st::confcallLinkFooterOrTop; + sep->resizeToWidth(width / 2); sep->move( st::boxRowPadding.left() + (width - sep->width()) / 2, - top + skip); + top); footer->moveToLeft( st::boxRowPadding.left(), - top + skip + sep->height()); + top + sep->height() + st::confcallLinkFooterOrSkip); }, footer->lifetime()); })); } diff --git a/Telegram/SourceFiles/tde2e/tde2e_api.cpp b/Telegram/SourceFiles/tde2e/tde2e_api.cpp index 526faa18e6..ee25452805 100644 --- a/Telegram/SourceFiles/tde2e/tde2e_api.cpp +++ b/Telegram/SourceFiles/tde2e/tde2e_api.cpp @@ -195,7 +195,6 @@ void Call::apply(int subchain, const Block &last) { }); if (subchain) { - auto &entry = _subchains[subchain]; auto result = tde2e_api::call_receive_inbound_message( libId(), Slice(last.data)); diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 52a213450d..d0a2eae995 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -840,17 +840,42 @@ void SessionNavigation::resolveCollectible( }).send(); } -void SessionNavigation::resolveConferenceCall(const QString &slug) { - resolveConferenceCall(slug, 0); -} - -void SessionNavigation::resolveConferenceCall(MsgId inviteMsgId) { - resolveConferenceCall(QString(), inviteMsgId); +void SessionNavigation::resolveConferenceCall( + QString slug, + Fn finished, + bool skipConfirm) { + resolveConferenceCall( + std::move(slug), + 0, + std::move(finished), + skipConfirm); } void SessionNavigation::resolveConferenceCall( - const QString &slug, - MsgId inviteMsgId) { + MsgId inviteMsgId, + Fn finished, + bool skipConfirm) { + resolveConferenceCall({}, inviteMsgId, std::move(finished), skipConfirm); +} + +void SessionNavigation::resolveConferenceCall( + QString slug, + MsgId inviteMsgId, + Fn finished, + bool skipConfirm) { + // Accept tg://call?slug= links as well. + const auto parts1 = QStringView(slug).split('#'); + if (!parts1.isEmpty()) { + const auto parts2 = parts1.front().split('&'); + if (!parts2.isEmpty()) { + const auto parts3 = parts2.front().split(u"slug="_q); + if (parts3.size() > 1) { + slug = parts3.back().toString(); + } + } + } + + _conferenceCallResolveFinished = std::move(finished); if (_conferenceCallSlug == slug && _conferenceCallInviteMsgId == inviteMsgId) { return; @@ -869,7 +894,7 @@ void SessionNavigation::resolveConferenceCall( _conferenceCallRequestId = 0; const auto slug = base::take(_conferenceCallSlug); const auto inviteMsgId = base::take(_conferenceCallInviteMsgId); - + const auto finished = base::take(_conferenceCallResolveFinished); result.data().vcall().match([&](const auto &data) { const auto call = std::make_shared( session().user(), @@ -888,6 +913,13 @@ void SessionNavigation::resolveConferenceCall( .joinMessageId = inviteMsgId, }); }; + if (skipConfirm) { + join(); + if (finished) { + finished(true); + } + return; + } const auto box = uiShow()->show(Box( Calls::Group::ConferenceCallJoinConfirm, call, @@ -899,11 +931,18 @@ void SessionNavigation::resolveConferenceCall( )).send(); } }, box->lifetime()); + if (finished) { + finished(true); + } }); }).fail([=] { _conferenceCallRequestId = 0; _conferenceCallSlug = QString(); + const auto finished = base::take(_conferenceCallResolveFinished); showToast(tr::lng_group_invite_bad_link(tr::now)); + if (finished) { + finished(false); + } }).send(); } diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index cb8432aaf4..c31772fa3d 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -264,8 +264,14 @@ public: PeerId ownerId, const QString &entity, Fn fail = nullptr); - void resolveConferenceCall(const QString &slug); - void resolveConferenceCall(MsgId inviteMsgId); + void resolveConferenceCall( + QString slug, + Fn finished = nullptr, + bool skipConfirm = false); + void resolveConferenceCall( + MsgId inviteMsgId, + Fn finished = nullptr, + bool skipConfirm = false); base::weak_ptr showToast( Ui::Toast::Config &&config); @@ -292,7 +298,11 @@ private: void resolveChannelById( ChannelId channelId, Fn)> done); - void resolveConferenceCall(const QString &slug, MsgId inviteMsgId); + void resolveConferenceCall( + QString slug, + MsgId inviteMsgId, + Fn finished, + bool skipConfirm); void resolveDone( const MTPcontacts_ResolvedPeer &result, @@ -334,6 +344,7 @@ private: QString _conferenceCallSlug; MsgId _conferenceCallInviteMsgId; + Fn _conferenceCallResolveFinished; mtpRequestId _conferenceCallRequestId = 0; };