From 06b85442f8e9ea16a8cbab48e44c6128627fa8bc Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 14 Nov 2024 21:17:44 +0400 Subject: [PATCH] Fix miniapp downloads in fullscreen. --- .../inline_bots/inline_bot_downloads.cpp | 8 +- .../ui/chat/attach/attach_bot_webview.cpp | 82 ++++++++++--------- .../ui/chat/attach/attach_bot_webview.h | 23 +++--- Telegram/lib_ui | 2 +- 4 files changed, 63 insertions(+), 52 deletions(-) diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_downloads.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_downloads.cpp index cbb4ede82..d1c82d54a 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_downloads.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_downloads.cpp @@ -392,6 +392,7 @@ void DownloadFileBox(not_null box, DownloadBoxArgs args) { const auto done = std::move(args.done); const auto name = args.name; const auto session = args.session; + const auto chosen = std::make_shared(); box->addButton(tr::lng_bot_download_file_button(), [=] { const auto path = FileNameForSave( session, @@ -402,14 +403,19 @@ void DownloadFileBox(not_null box, DownloadBoxArgs args) { false, QDir()); if (!path.isEmpty()) { + *chosen = true; box->closeBox(); done(path); } }); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); - done(QString()); }); + box->boxClosing() | rpl::start_with_next([=] { + if (!*chosen) { + done(QString()); + } + }, box->lifetime()); } } // namespace InlineBots diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp index 670d714bc..6fa4bb997 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/file_utilities.h" #include "ui/boxes/confirm_box.h" +#include "ui/chat/attach/attach_bot_downloads.h" #include "ui/effects/radial_animation.h" #include "ui/effects/ripple_animation.h" #include "ui/layers/box_content.h" @@ -430,9 +431,7 @@ Panel::Panel(Args &&args) setTitle(std::move(args.title)); _widget->setTitleBadge(std::move(args.titleBadge)); - if (showWebview(args.url, params, std::move(args.bottom))) { - setupDownloadsProgress(rpl::duplicate(args.downloadsProgress)); - } else { + if (!showWebview(std::move(args), params)) { const auto available = Webview::Availability(); if (available.error != Webview::Available::Error::None) { showWebviewError(tr::lng_bot_no_webview(tr::now), available); @@ -448,35 +447,38 @@ Panel::~Panel() { _widget = nullptr; } -void Panel::setupDownloadsProgress(rpl::producer progress) { - Expects(_menuToggle != nullptr); - - const auto widget = Ui::CreateChild(_menuToggle.data()); +void Panel::setupDownloadsProgress( + not_null button, + rpl::producer progress, + bool fullscreen) { + const auto widget = Ui::CreateChild(button.get()); widget->show(); widget->setAttribute(Qt::WA_TransparentForMouseEvents); - _menuToggle->sizeValue() | rpl::start_with_next([=](QSize size) { + button->sizeValue() | rpl::start_with_next([=](QSize size) { widget->setGeometry(QRect(QPoint(), size)); }, widget->lifetime()); struct State { - State(QWidget *parent, Fn progress) + State(QWidget *parent) : animation([=](crl::time now) { - const auto updated = animation.update(progress(), false, now); + const auto total = progress.total; + const auto current = total + ? (progress.ready / float64(total)) + : 0.; + const auto updated = animation.update(current, false, now); if (!anim::Disabled() || updated) { parent->update(); } }) { } + DownloadsProgress progress; RadialAnimation animation; Animations::Simple fade; bool shown = false; }; - const auto state = widget->lifetime().make_state(widget, [=] { - const auto total = _downloadsProgress.total; - return total ? (_downloadsProgress.ready / float64(total)) : 0.; - }); + const auto state = widget->lifetime().make_state(widget); std::move( progress ) | rpl::start_with_next([=](DownloadsProgress progress) { @@ -492,9 +494,9 @@ void Panel::setupDownloadsProgress(rpl::producer progress) { widget->update(); if (!state->shown && !state->fade.animating() - && (!_downloadsProgress.total - || (_downloadsProgress.ready - == _downloadsProgress.total))) { + && (!state->progress.total + || (state->progress.ready + == state->progress.total))) { state->animation.stop(); } }, shown ? 0. : 2., shown ? 2. : 0., st::radialDuration * 2); @@ -504,14 +506,13 @@ void Panel::setupDownloadsProgress(rpl::producer progress) { state->animation.start(0.); } toggle(true); - } else if ((_downloadsProgress.total && !progress.total) - || (_downloadsProgress.ready < _downloadsProgress.total + } else if ((state->progress.total && !progress.total) + || (state->progress.ready < state->progress.total && progress.ready == progress.total)) { state->animation.update(1., false, crl::now()); toggle(false); } - _downloadsProgress = progress; - _downloadsUpdated.fire({}); + state->progress = progress; }, widget->lifetime()); widget->paintRequest() | rpl::start_with_next([=] { @@ -525,10 +526,14 @@ void Panel::setupDownloadsProgress(rpl::producer progress) { auto p = QPainter(widget); p.setOpacity(opacity); const auto palette = _widget->titleOverridePalette(); - const auto color = palette + const auto color = fullscreen + ? st::radialFg + : palette ? palette->boxTitleCloseFg() : st::paymentsLoading.color; - const auto &st = st::separatePanelMenu; + const auto &st = fullscreen + ? st::fullScreenPanelMenu + : st::separatePanelMenu; const auto size = st.rippleAreaSize; const auto rect = QRect(st.rippleAreaPosition, QSize(size, size)); const auto stroke = st::botWebViewRadialStroke; @@ -666,11 +671,8 @@ void Panel::hideWebviewProgress() { toggleProgress(false); } -bool Panel::showWebview( - const QString &url, - const Webview::ThemeParams ¶ms, - rpl::producer bottomText) { - _bottomText = std::move(bottomText); +bool Panel::showWebview(Args &&args, const Webview::ThemeParams ¶ms) { + _bottomText = std::move(args.bottom); if (!_webview && !createWebview(params)) { return false; } @@ -678,10 +680,15 @@ bool Panel::showWebview( showWebviewProgress(); _widget->hideLayer(anim::type::instant); updateThemeParams(params); + const auto url = args.url; _webview->window.navigate(url); _widget->setBackAllowed(allowBack); - _menuToggle = _widget->setMenuAllowed([=]( + rpl::duplicate(args.downloadsProgress) | rpl::start_with_next([=] { + _downloadsUpdated.fire({}); + }, lifetime()); + + _widget->setMenuAllowed([=]( const Ui::Menu::MenuCallback &callback) { auto list = _delegate->botDownloads(true); if (!list.empty()) { @@ -754,16 +761,15 @@ bool Panel::showWebview( .isAttention = true, }); } - if (_widget->isFullScreen()) { - callback(u"Close Full Screen"_q, [=] { - _fullscreen = false; - }, &st::menuIconPlayerWindowed); - } else { - callback(u"Show Full Screen"_q, [=] { - _fullscreen = true; - }, &st::menuIconPlayerFullScreen); - } + }, [=, progress = std::move(args.downloadsProgress)]( + not_null button, + bool fullscreen) { + setupDownloadsProgress( + button, + rpl::duplicate(progress), + fullscreen); }); + return true; } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h index 7f59731b1..e5a822474 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h @@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/object_ptr.h" #include "base/weak_ptr.h" #include "base/flags.h" -#include "ui/chat/attach/attach_bot_downloads.h" #include "ui/rect_part.h" #include "ui/round_rect.h" #include "webview/webview_common.h" @@ -34,6 +33,10 @@ struct Available; namespace Ui::BotWebView { +struct DownloadsProgress; +struct DownloadsEntry; +enum class DownloadsAction; + [[nodiscard]] TextWithEntities ErrorText(const Webview::Available &info); enum class MenuButton { @@ -75,9 +78,7 @@ public: [[nodiscard]] virtual Webview::ThemeParams botThemeParams() = 0; [[nodiscard]] virtual auto botDownloads(bool forceCheck = false) -> const std::vector & = 0; - virtual void botDownloadsAction( - uint32 id, - Ui::BotWebView::DownloadsAction type) = 0; + virtual void botDownloadsAction(uint32 id, DownloadsAction type) = 0; virtual bool botHandleLocalUri(QString uri, bool keepOpen) = 0; virtual void botHandleInvoice(QString slug) = 0; virtual void botHandleMenuButton(MenuButton button) = 0; @@ -122,11 +123,6 @@ public: void requestActivate(); void toggleProgress(bool shown); - bool showWebview( - const QString &url, - const Webview::ThemeParams ¶ms, - rpl::producer bottomText); - void showBox(object_ptr box); void showBox( object_ptr box, @@ -152,11 +148,16 @@ private: struct Progress; struct WebviewWithLifetime; + bool showWebview(Args &&args, const Webview::ThemeParams ¶ms); + bool createWebview(const Webview::ThemeParams ¶ms); void createWebviewBottom(); void showWebviewProgress(); void hideWebviewProgress(); - void setupDownloadsProgress(rpl::producer progress); + void setupDownloadsProgress( + not_null button, + rpl::producer progress, + bool fullscreen); void setTitle(rpl::producer title); void sendDataMessage(const QJsonObject &args); void switchInlineQueryMessage(const QJsonObject &args); @@ -213,7 +214,6 @@ private: bool _hasSettingsButton = false; MenuButtons _menuButtons = {}; std::unique_ptr _widget; - QPointer _menuToggle; std::unique_ptr _webview; std::unique_ptr _webviewBottom; rpl::variable _bottomText; @@ -229,7 +229,6 @@ private: rpl::lifetime _headerColorLifetime; rpl::lifetime _bodyColorLifetime; rpl::lifetime _bottomBarColorLifetime; - DownloadsProgress _downloadsProgress; rpl::event_stream<> _downloadsUpdated; rpl::variable _fullscreen = false; bool _layerShown : 1 = false; diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 3b5ef7899..46c18e2c7 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 3b5ef7899e5edd544e37ecdf8b1e7e3ba0ca2dc0 +Subproject commit 46c18e2c7e730c6304e8d813be4d5abc6fb364ad