From 2dcf40817e39e52e744b423310362c2997c6658c Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 26 Jul 2024 19:25:47 +0200 Subject: [PATCH] Initial tonsite:// show in IV window. --- Telegram/SourceFiles/core/ui_integration.cpp | 3 + Telegram/SourceFiles/iv/iv_controller.cpp | 20 +++ Telegram/SourceFiles/iv/iv_controller.h | 2 + Telegram/SourceFiles/iv/iv_instance.cpp | 156 +++++++++++++++++-- Telegram/SourceFiles/iv/iv_instance.h | 6 + 5 files changed, 177 insertions(+), 10 deletions(-) diff --git a/Telegram/SourceFiles/core/ui_integration.cpp b/Telegram/SourceFiles/core/ui_integration.cpp index 1bc5a1f85..bf1b49432 100644 --- a/Telegram/SourceFiles/core/ui_integration.cpp +++ b/Telegram/SourceFiles/core/ui_integration.cpp @@ -238,6 +238,9 @@ bool UiIntegration::handleUrlClick( } else if (local.startsWith(u"tg://"_q, Qt::CaseInsensitive)) { Core::App().openLocalUrl(local, context); return true; + } else if (local.startsWith(u"tonsite://"_q, Qt::CaseInsensitive)) { + Core::App().iv().showTonSite(url, context); + return true; } else if (local.startsWith(u"internal:"_q, Qt::CaseInsensitive)) { Core::App().openInternalUrl(local, context); return true; diff --git a/Telegram/SourceFiles/iv/iv_controller.cpp b/Telegram/SourceFiles/iv/iv_controller.cpp index b3fb82a0d..6720f3c93 100644 --- a/Telegram/SourceFiles/iv/iv_controller.cpp +++ b/Telegram/SourceFiles/iv/iv_controller.cpp @@ -251,6 +251,26 @@ void Controller::update(Prepared page) { } } +void Controller::showTonSite( + const Webview::StorageId &storageId, + QString uri) { + auto part = uri.mid(u"tonsite://"_q.size()); + part = part.replace('-', "-h"); + part = part.replace('.', "-d"); + const auto url = "https://" + part + ".magic.org"; + if (!_webview) { + createWebview(storageId); + } + if (_webview && _webview->widget()) { + _webview->navigate(url); + activate(); + } else { + _events.fire({ Event::Type::Close }); + } + _subtitleText = uri; + _menuToggle->hide(); +} + QByteArray Controller::fillInChannelValuesScript( base::flat_map> inChannelValues) { auto result = QByteArray(); diff --git a/Telegram/SourceFiles/iv/iv_controller.h b/Telegram/SourceFiles/iv/iv_controller.h index 473813fca..1f0ecaf9a 100644 --- a/Telegram/SourceFiles/iv/iv_controller.h +++ b/Telegram/SourceFiles/iv/iv_controller.h @@ -76,6 +76,8 @@ public: base::flat_map> inChannelValues); void update(Prepared page); + void showTonSite(const Webview::StorageId &storageId, QString uri); + [[nodiscard]] bool active() const; void showJoinedTooltip(); void minimize(); diff --git a/Telegram/SourceFiles/iv/iv_instance.cpp b/Telegram/SourceFiles/iv/iv_instance.cpp index a49ba8887..00cfaa615 100644 --- a/Telegram/SourceFiles/iv/iv_instance.cpp +++ b/Telegram/SourceFiles/iv/iv_instance.cpp @@ -171,6 +171,39 @@ private: }; +class TonSite final : public base::has_weak_ptr { +public: + TonSite(not_null delegate, QString uri); + + [[nodiscard]] bool active() const; + + void moveTo(QString uri); + + void minimize(); + + [[nodiscard]] rpl::producer events() const { + return _events.events(); + } + + [[nodiscard]] rpl::lifetime &lifetime() { + return _lifetime; + } + +private: + void createController(); + + void showWindowed(); + + const not_null _delegate; + QString _uri; + std::unique_ptr _controller; + + rpl::event_stream _events; + + rpl::lifetime _lifetime; + +}; + Shown::Shown( not_null delegate, not_null session, @@ -742,6 +775,50 @@ void Shown::minimize() { } } +TonSite::TonSite(not_null delegate, QString uri) +: _delegate(delegate) +, _uri(uri) { + showWindowed(); +} + +void TonSite::createController() { + Expects(!_controller); + + const auto showShareBox = [=](ShareBoxDescriptor &&descriptor) { + return ShareBoxResult(); + }; + _controller = std::make_unique( + _delegate, + std::move(showShareBox)); + + _controller->events( + ) | rpl::start_to_stream(_events, _controller->lifetime()); +} + +void TonSite::showWindowed() { + if (!_controller) { + createController(); + } + + _controller->showTonSite( + {},//_session->local().resolveStorageIdOther(), + _uri); +} + +bool TonSite::active() const { + return _controller && _controller->active(); +} + +void TonSite::moveTo(QString uri) { + _controller->showTonSite({}, uri); +} + +void TonSite::minimize() { + if (_controller) { + _controller->minimize(); + } +} + Instance::Instance(not_null delegate) : _delegate(delegate) { } @@ -785,6 +862,7 @@ void Instance::show( const auto lower = event.url.toLower(); const auto urlChecked = lower.startsWith("http://") || lower.startsWith("https://"); + const auto tonsite = lower.startsWith("tonsite://"); switch (event.type) { case Type::Close: _shown = nullptr; @@ -801,8 +879,10 @@ void Instance::show( case Type::OpenLinkExternal: if (urlChecked) { File::OpenUrl(event.url); + closeAll(); + } else if (tonsite) { + showTonSite(event.url); } - closeAll(); break; case Type::OpenMedia: if (const auto window = Core::App().activeWindow()) { @@ -840,7 +920,10 @@ void Instance::show( break; case Type::OpenPage: case Type::OpenLink: { - if (!urlChecked) { + if (tonsite) { + showTonSite(event.url); + break; + } else if (!urlChecked) { break; } const auto session = _shownSession; @@ -990,6 +1073,52 @@ void Instance::openWithIvPreferred( }).send(); } +void Instance::showTonSite( + const QString &uri, + QVariant context) { + if (Platform::IsMac()) { + // Otherwise IV is not visible under the media viewer. + Core::App().hideMediaView(); + } + if (_tonSite) { + _tonSite->moveTo(uri); + return; + } + _tonSite = std::make_unique(_delegate, uri); + _tonSite->events() | rpl::start_with_next([=](Controller::Event event) { + using Type = Controller::Event::Type; + const auto lower = event.url.toLower(); + const auto urlChecked = lower.startsWith("http://") + || lower.startsWith("https://"); + const auto tonsite = lower.startsWith("tonsite://"); + switch (event.type) { + case Type::Close: + _tonSite = nullptr; + break; + case Type::Quit: + Shortcuts::Launch(Shortcuts::Command::Quit); + break; + case Type::OpenLinkExternal: + if (urlChecked) { + File::OpenUrl(event.url); + closeAll(); + } else if (tonsite) { + showTonSite(event.url); + } + break; + case Type::OpenPage: + case Type::OpenLink: + if (urlChecked) { + File::OpenUrl(event.url); + closeAll(); + } else if (tonsite) { + showTonSite(event.url); + } + break; + } + }, _tonSite->lifetime()); +} + void Instance::requestFull( not_null session, const QString &id) { @@ -1085,23 +1214,30 @@ bool Instance::hasActiveWindow(not_null session) const { } bool Instance::closeActive() { - if (!_shown || !_shown->active()) { - return false; + if (_shown && _shown->active()) { + _shown = nullptr; + return true; + } else if (_tonSite && _tonSite->active()) { + _tonSite = nullptr; + return true; } - _shown = nullptr; - return true; + return false; } bool Instance::minimizeActive() { - if (!_shown || !_shown->active()) { - return false; + if (_shown && _shown->active()) { + _shown->minimize(); + return true; + } else if (_tonSite && _tonSite->active()) { + _tonSite->minimize(); + return true; } - _shown->minimize(); - return true; + return false; } void Instance::closeAll() { _shown = nullptr; + _tonSite = nullptr; } bool PreferForUri(const QString &uri) { diff --git a/Telegram/SourceFiles/iv/iv_instance.h b/Telegram/SourceFiles/iv/iv_instance.h index 9083734ad..c48cf569e 100644 --- a/Telegram/SourceFiles/iv/iv_instance.h +++ b/Telegram/SourceFiles/iv/iv_instance.h @@ -22,6 +22,7 @@ namespace Iv { class Data; class Shown; +class TonSite; class Instance final { public: @@ -50,6 +51,10 @@ public: QString uri, QVariant context = {}); + void showTonSite( + const QString &uri, + QVariant context = {}); + [[nodiscard]] bool hasActiveWindow( not_null session) const; @@ -97,6 +102,7 @@ private: QString _ivRequestUri; mtpRequestId _ivRequestId = 0; + std::unique_ptr _tonSite; rpl::lifetime _lifetime;