From 36cb28d5cf5a652e8de5788c567d63278102db20 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 4 Apr 2024 18:20:33 +0400 Subject: [PATCH] Respect 'try_instant_view' in webapps. --- .../inline_bots/bot_attach_web_view.cpp | 49 +++++++++++++++++++ .../inline_bots/bot_attach_web_view.h | 5 ++ Telegram/SourceFiles/iv/iv_instance.cpp | 19 ++++--- Telegram/SourceFiles/iv/iv_instance.h | 4 ++ .../ui/chat/attach/attach_bot_webview.cpp | 6 ++- .../ui/chat/attach/attach_bot_webview.h | 1 + 6 files changed, 76 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index 056aa224e4..c3f78b2d05 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -17,10 +17,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document.h" #include "data/data_document_media.h" #include "data/data_session.h" +#include "data/data_web_page.h" #include "main/main_session.h" #include "main/main_domain.h" #include "storage/storage_domain.h" #include "info/profile/info_profile_values.h" +#include "iv/iv_instance.h" #include "ui/boxes/confirm_box.h" #include "ui/chat/attach/attach_bot_webview.h" #include "ui/widgets/checkbox.h" @@ -653,6 +655,53 @@ void AttachWebView::botHandleMenuButton(Ui::BotWebView::MenuButton button) { } } +void AttachWebView::botOpenIvLink(QString uri) { + const auto parts = uri.split('#'); + if (parts.isEmpty()) { + return; + } + const auto hash = (parts.size() > 1) ? parts[1] : u""_q; + const auto url = parts[0]; + if (const auto i = _ivCache.find(url); i != end(_ivCache)) { + const auto page = i->second; + if (page && page->iv) { + const auto window = _context + ? _context->controller.get() + : nullptr; + if (window) { + Core::App().iv().show(window, page->iv.get(), hash); + } else { + Core::App().iv().show(_session, page->iv.get(), hash); + } + } else { + UrlClickHandler::Open(uri); + } + return; + } else if (_ivRequestUri == uri) { + return; + } else if (_ivRequestId) { + _session->api().request(_ivRequestId).cancel(); + } + const auto finish = [=](WebPageData *page) { + _ivRequestId = 0; + _ivRequestUri = QString(); + _ivCache[url] = page; + botOpenIvLink(uri); + }; + _ivRequestUri = uri; + _ivRequestId = _session->api().request(MTPmessages_GetWebPage( + MTP_string(url), + MTP_int(0) + )).done([=](const MTPmessages_WebPage &result) { + const auto &data = result.data(); + _session->data().processUsers(data.vusers()); + _session->data().processChats(data.vchats()); + finish(_session->data().processWebpage(data.vwebpage())); + }).fail([=] { + finish(nullptr); + }).send(); +} + void AttachWebView::botSendData(QByteArray data) { if (!_context || _context->fromSwitch diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h index d1d2c0e44e..c172cd5c37 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h @@ -165,6 +165,7 @@ private: bool botHandleLocalUri(QString uri, bool keepOpen) override; void botHandleInvoice(QString slug) override; void botHandleMenuButton(Ui::BotWebView::MenuButton button) override; + void botOpenIvLink(QString uri) override; void botSendData(QByteArray data) override; void botSwitchInlineQuery( std::vector chatTypes, @@ -266,6 +267,10 @@ private: rpl::event_stream<> _attachBotsUpdates; base::flat_set> _disclaimerAccepted; + base::flat_map _ivCache; + QString _ivRequestUri; + mtpRequestId _ivRequestId = 0; + std::unique_ptr _panel; bool _catchingCancelInShowCall = false; diff --git a/Telegram/SourceFiles/iv/iv_instance.cpp b/Telegram/SourceFiles/iv/iv_instance.cpp index 5174154358..f84d55223a 100644 --- a/Telegram/SourceFiles/iv/iv_instance.cpp +++ b/Telegram/SourceFiles/iv/iv_instance.cpp @@ -63,7 +63,7 @@ class Shown final : public base::has_weak_ptr { public: Shown( not_null delegate, - std::shared_ptr show, + not_null session, not_null data, QString hash); @@ -169,12 +169,11 @@ private: Shown::Shown( not_null delegate, - std::shared_ptr show, + not_null session, not_null data, QString hash) : _delegate(delegate) -, _session(&show->session()) -, _show(show) { +, _session(session) { prepare(data, hash); } @@ -818,7 +817,13 @@ void Instance::show( std::shared_ptr show, not_null data, QString hash) { - const auto session = &show->session(); + this->show(&show->session(), data, hash); +} + +void Instance::show( + not_null session, + not_null data, + QString hash) { const auto guard = gsl::finally([&] { if (data->partial()) { requestFull(session, data->id()); @@ -828,7 +833,7 @@ void Instance::show( _shown->moveTo(data, hash); return; } - _shown = std::make_unique(_delegate, show, data, hash); + _shown = std::make_unique(_delegate, session, data, hash); _shownSession = session; _shown->events() | rpl::start_with_next([=](Controller::Event event) { using Type = Controller::Event::Type; @@ -896,7 +901,7 @@ void Instance::show( if (page && page->iv) { const auto parts = event.url.split('#'); const auto hash = (parts.size() > 1) ? parts[1] : u""_q; - this->show(show, page->iv.get(), hash); + this->show(_shownSession, page->iv.get(), hash); } else { UrlClickHandler::Open(event.url); } diff --git a/Telegram/SourceFiles/iv/iv_instance.h b/Telegram/SourceFiles/iv/iv_instance.h index ba3d8f72c1..608c9c2835 100644 --- a/Telegram/SourceFiles/iv/iv_instance.h +++ b/Telegram/SourceFiles/iv/iv_instance.h @@ -36,6 +36,10 @@ public: std::shared_ptr show, not_null data, QString hash); + void show( + not_null session, + not_null data, + QString hash); [[nodiscard]] bool hasActiveWindow( not_null session) const; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp index 42eac21dec..c9f3f93f85 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.cpp @@ -801,6 +801,7 @@ void Panel::openExternalLink(const QJsonObject &args) { return; } const auto url = args["url"].toString(); + const auto iv = args["try_instant_view"].toBool(); const auto lower = url.toLower(); if (url.isEmpty() || (!lower.startsWith("http://") && !lower.startsWith("https://"))) { @@ -809,8 +810,11 @@ void Panel::openExternalLink(const QJsonObject &args) { return; } else if (!allowOpenLink()) { return; + } else if (iv) { + _delegate->botOpenIvLink(url); + } else { + File::OpenUrl(url); } - File::OpenUrl(url); } void Panel::openInvoice(const QJsonObject &args) { diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h index 9c4be46d04..bb22a4dfc2 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_bot_webview.h @@ -57,6 +57,7 @@ public: virtual bool botHandleLocalUri(QString uri, bool keepOpen) = 0; virtual void botHandleInvoice(QString slug) = 0; virtual void botHandleMenuButton(MenuButton button) = 0; + virtual void botOpenIvLink(QString uri) = 0; virtual void botSendData(QByteArray data) = 0; virtual void botSwitchInlineQuery( std::vector chatTypes,