From 8b2bbfba6aaaa764f83a35ca0c1b26d7bde59187 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 30 Jul 2024 10:19:59 +0200 Subject: [PATCH] Navigate back/forward in tonsite pages. --- Telegram/Resources/iv_html/page.js | 3 - Telegram/SourceFiles/iv/iv.style | 13 +- Telegram/SourceFiles/iv/iv_controller.cpp | 146 ++++++++++++++---- Telegram/SourceFiles/iv/iv_controller.h | 5 +- .../settings/settings_experimental.cpp | 2 + Telegram/lib_webview | 2 +- 6 files changed, 130 insertions(+), 41 deletions(-) diff --git a/Telegram/Resources/iv_html/page.js b/Telegram/Resources/iv_html/page.js index bae02fe48..fda34772f 100644 --- a/Telegram/Resources/iv_html/page.js +++ b/Telegram/Resources/iv_html/page.js @@ -618,9 +618,6 @@ var IV = { element.getAnimations().forEach( (animation) => animation.finish()); }, - back: function () { - window.history.back(); - }, menuShown: function (shown) { var already = document.getElementById('menu_page_blocker'); if (already && shown) { diff --git a/Telegram/SourceFiles/iv/iv.style b/Telegram/SourceFiles/iv/iv.style index c8c9c6b69..6a5757276 100644 --- a/Telegram/SourceFiles/iv/iv.style +++ b/Telegram/SourceFiles/iv/iv.style @@ -22,12 +22,21 @@ ivMenuToggle: IconButton(defaultIconButton) { } } ivMenuPosition: point(-2px, 40px); +ivBackIcon: icon {{ "box_button_back", menuIconColor }}; ivBack: IconButton(ivMenuToggle) { width: 60px; - icon: icon {{ "box_button_back", menuIconColor }}; - iconOver: icon {{ "box_button_back", menuIconColor }}; + icon: ivBackIcon; + iconOver: ivBackIcon; rippleAreaPosition: point(12px, 6px); } +ivBackIconDisabled: icon {{ "box_button_back", menuIconFg }}; +ivForwardIcon: icon {{ "box_button_back-flip_horizontal", menuIconColor }}; +ivForward: IconButton(ivBack) { + width: 48px; + icon: ivForwardIcon; + iconOver: ivForwardIcon; + rippleAreaPosition: point(0px, 6px); +} ivSubtitleFont: font(16px semibold); ivSubtitle: FlatLabel(defaultFlatLabel) { textFg: boxTitleFg; diff --git a/Telegram/SourceFiles/iv/iv_controller.cpp b/Telegram/SourceFiles/iv/iv_controller.cpp index 07ddd4e9d..1870011dc 100644 --- a/Telegram/SourceFiles/iv/iv_controller.cpp +++ b/Telegram/SourceFiles/iv/iv_controller.cpp @@ -127,6 +127,51 @@ namespace { return file.open(QIODevice::ReadOnly) ? file.readAll() : QByteArray(); } +[[nodiscard]] QString TonsiteToHttps(QString value) { + const auto ChangeHost = [](QString tonsite) { + tonsite = tonsite.replace('-', "-h"); + tonsite = tonsite.replace('.', "-d"); + return tonsite + ".magic.org"; + }; + auto parsed = QUrl(value); + if (parsed.isValid()) { + parsed.setScheme("https"); + parsed.setHost(ChangeHost(parsed.host())); + if (parsed.path().isEmpty()) { + parsed.setPath(u"/"_q); + } + return parsed.toString(); + } + const auto part = value.mid(u"tonsite://"_q.size()); + const auto split = part.indexOf('/'); + return "https://" + + ChangeHost((split < 0) ? part : part.left(split)) + + ((split < 0) ? u"/"_q : part.mid(split)); +} + +[[nodiscard]] QString HttpsToTonsite(QString value) { + const auto ChangeHost = [](QString https) { + https.replace(".magic.org", QString()); + https = https.replace("-d", "."); + https = https.replace("-h", "-"); + return https; + }; + auto parsed = QUrl(value); + if (parsed.isValid()) { + parsed.setScheme("tonsite"); + parsed.setHost(ChangeHost(parsed.host())); + if (parsed.path().isEmpty()) { + parsed.setPath(u"/"_q); + } + return parsed.toString(); + } + const auto part = value.mid(u"https://"_q.size()); + const auto split = part.indexOf('/'); + return "tonsite://" + + ChangeHost((split < 0) ? part : part.left(split)) + + ((split < 0) ? u"/"_q : part.mid(split)); +} + } // namespace Controller::Controller( @@ -151,6 +196,7 @@ Controller::~Controller() { _ready = false; _webview = nullptr; _back.destroy(); + _forward.destroy(); _menu = nullptr; _menuToggle.destroy(); _subtitle = nullptr; @@ -168,15 +214,22 @@ void Controller::updateTitleGeometry(int newWidth) const { QPainter(_subtitleWrap.get()).fillRect(clip, st::windowBg); }, _subtitleWrap->lifetime()); - const auto progress = _subtitleLeft.value(_back->toggled() ? 1. : 0.); - const auto left = anim::interpolate( - st::ivSubtitleLeft, - _back->width() + st::ivSubtitleSkip, - progress); + const auto progressBack = _subtitleBackShift.value( + _back->toggled() ? 1. : 0.); + const auto progressForward = _subtitleForwardShift.value( + _forward->toggled() ? 1. : 0.); + const auto backAdded = _back->width() + + st::ivSubtitleSkip + - st::ivSubtitleLeft; + const auto forwardAdded = _forward->width(); + const auto left = st::ivSubtitleLeft + + anim::interpolate(0, backAdded, progressBack) + + anim::interpolate(0, forwardAdded, progressForward); _subtitle->resizeToWidth(newWidth - left - _menuToggle->width()); _subtitle->moveToLeft(left, st::ivSubtitleTop); _back->moveToLeft(0, 0); + _forward->moveToLeft(_back->width() * progressBack, 0); _menuToggle->moveToRight(0, 0); } @@ -191,12 +244,12 @@ void Controller::initControls() { _subtitleWrap.get(), _subtitleText.value(), st::ivSubtitle); + _subtitle->setSelectable(true); _subtitleText.value( ) | rpl::start_with_next([=](const QString &subtitle) { const auto prefix = tr::lng_iv_window_title(tr::now); _window->setWindowTitle(prefix + ' ' + QChar(0x2014) + ' ' + subtitle); }, _subtitle->lifetime()); - _subtitle->setAttribute(Qt::WA_TransparentForMouseEvents); _menuToggle.create(_subtitleWrap.get(), st::ivMenuToggle); _menuToggle->setClickedCallback([=] { showMenu(); }); @@ -206,15 +259,25 @@ void Controller::initControls() { object_ptr(_subtitleWrap.get(), st::ivBack)); _back->entity()->setClickedCallback([=] { if (_webview) { - _webview->eval("IV.back();"); + _webview->eval("window.history.back();"); } else { _back->hide(anim::type::normal); } }); + _forward.create( + _subtitleWrap.get(), + object_ptr(_subtitleWrap.get(), st::ivForward)); + _forward->entity()->setClickedCallback([=] { + if (_webview) { + _webview->eval("window.history.forward();"); + } else { + _forward->hide(anim::type::normal); + } + }); _back->toggledValue( ) | rpl::start_with_next([=](bool toggled) { - _subtitleLeft.start( + _subtitleBackShift.start( [=] { updateTitleGeometry(_window->body()->width()); }, toggled ? 0. : 1., toggled ? 1. : 0., @@ -222,7 +285,18 @@ void Controller::initControls() { }, _back->lifetime()); _back->hide(anim::type::instant); - _subtitleLeft.stop(); + _forward->toggledValue( + ) | rpl::start_with_next([=](bool toggled) { + _subtitleForwardShift.start( + [=] { updateTitleGeometry(_window->body()->width()); }, + toggled ? 0. : 1., + toggled ? 1. : 0., + st::fadeWrapDuration); + }, _forward->lifetime()); + _forward->hide(anim::type::instant); + + _subtitleBackShift.stop(); + _subtitleForwardShift.stop(); } void Controller::show( @@ -254,24 +328,7 @@ void Controller::update(Prepared page) { void Controller::showTonSite( const Webview::StorageId &storageId, QString uri) { - const auto url = [&] { - auto parsed = QUrl(uri); - if (parsed.isValid()) { - auto host = parsed.host(); - host = host.replace('-', "-h"); - host = host.replace('.', "-d"); - parsed.setHost(host + ".magic.org"); - parsed.setScheme("https"); - return parsed.toString(); - } - auto part = uri.mid(u"tonsite://"_q.size()); - const auto split = part.indexOf('/'); - auto host = (split < 0) ? part : part.left(split); - host = host.replace('-', "-h"); - host = host.replace('.', "-d"); - part = (split < 0) ? QString() : part.mid(split); - return "https://" + host + ".magic.org" + part; - }(); + const auto url = TonsiteToHttps(uri); if (!_webview) { createWebview(storageId); } @@ -281,7 +338,13 @@ void Controller::showTonSite( } else { _events.fire({ Event::Type::Close }); } - _subtitleText = uri; + _url = url; + _subtitleText = _url.value( + ) | rpl::filter([=](const QString &url) { + return !url.isEmpty() && url != u"about:blank"_q; + }) | rpl::map([=](QString value) { + return HttpsToTonsite(value); + }); _menuToggle->hide(); } @@ -438,12 +501,12 @@ void Controller::createWebview(const Webview::StorageId &storageId) { if (!script.isEmpty()) { _webview->eval(script); } - } else if (event == u"location_change"_q) { - _index = object.value("index").toInt(); - _hash = object.value("hash").toString(); - _back->toggle( - (object.value("position").toInt() > 0), - anim::type::normal); + //} else if (event == u"location_change"_q) { + // _index = object.value("index").toInt(); + // _hash = object.value("hash").toString(); + // _back->toggle( + // (object.value("position").toInt() > 0), + // anim::type::normal); } }); }); @@ -524,6 +587,21 @@ void Controller::createWebview(const Webview::StorageId &storageId) { return Webview::DataResult::Failed; }); + raw->navigationHistoryState( + ) | rpl::start_with_next([=](Webview::NavigationHistoryState state) { + _back->toggle( + state.canGoBack || state.canGoForward, + anim::type::normal); + _forward->toggle(state.canGoForward, anim::type::normal); + _back->entity()->setDisabled(!state.canGoBack); + _back->entity()->setIconOverride( + state.canGoBack ? nullptr : &st::ivBackIconDisabled, + state.canGoBack ? nullptr : &st::ivBackIconDisabled); + _back->setAttribute( + Qt::WA_TransparentForMouseEvents, + !state.canGoBack); + }, _webview->lifetime()); + raw->init(R"()"); } diff --git a/Telegram/SourceFiles/iv/iv_controller.h b/Telegram/SourceFiles/iv/iv_controller.h index 1f0ecaf9a..b732ec57a 100644 --- a/Telegram/SourceFiles/iv/iv_controller.h +++ b/Telegram/SourceFiles/iv/iv_controller.h @@ -127,11 +127,14 @@ private: std::unique_ptr _window; std::unique_ptr _subtitleWrap; + rpl::variable _url; rpl::variable _subtitleText; std::unique_ptr _subtitle; - Ui::Animations::Simple _subtitleLeft; + Ui::Animations::Simple _subtitleBackShift; + Ui::Animations::Simple _subtitleForwardShift; object_ptr _menuToggle = { nullptr }; object_ptr> _back = { nullptr }; + object_ptr> _forward = { nullptr }; base::unique_qptr _menu; Ui::RpWidget *_container = nullptr; std::unique_ptr _webview; diff --git a/Telegram/SourceFiles/settings/settings_experimental.cpp b/Telegram/SourceFiles/settings/settings_experimental.cpp index f578bce82..69e0ef89e 100644 --- a/Telegram/SourceFiles/settings/settings_experimental.cpp +++ b/Telegram/SourceFiles/settings/settings_experimental.cpp @@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "mainwindow.h" #include "media/player/media_player_instance.h" +#include "webview/platform/win/webview_windows_edge_chromium.h" #include "webview/webview_embed.h" #include "window/main_window.h" #include "window/window_peer_menu.h" @@ -149,6 +150,7 @@ void SetupExperimental( addToggle(Media::Player::kOptionDisableAutoplayNext); addToggle(kOptionSendLargePhotos); addToggle(Webview::kOptionWebviewDebugEnabled); + addToggle(Webview::EdgeChromium::kOptionWebviewLegacyEdge); addToggle(kOptionAutoScrollInactiveChat); addToggle(Window::Notifications::kOptionGNotification); addToggle(Core::kOptionFreeType); diff --git a/Telegram/lib_webview b/Telegram/lib_webview index 363db4e49..cc8f41d10 160000 --- a/Telegram/lib_webview +++ b/Telegram/lib_webview @@ -1 +1 @@ -Subproject commit 363db4e49a0b78e5dd08bd922e09cf8810318c09 +Subproject commit cc8f41d10b66c1e66f16728f95f217a62d2dc7ac