diff --git a/Telegram/SourceFiles/iv/iv_instance.cpp b/Telegram/SourceFiles/iv/iv_instance.cpp index c302217945..47daa2199f 100644 --- a/Telegram/SourceFiles/iv/iv_instance.cpp +++ b/Telegram/SourceFiles/iv/iv_instance.cpp @@ -1109,7 +1109,8 @@ private: Markdown::MarkdownArticleContent content, QString title, QString initialFragment, - not_null page); + not_null page, + bool refresh); [[nodiscard]] ShareBoxResult shareBox(ShareBoxDescriptor &&descriptor); [[nodiscard]] std::shared_ptr createMediaRuntime( not_null page) const; @@ -1502,7 +1503,8 @@ void Shown::showWindowed(Prepared result, Source source, bool refresh) { std::move(native.content), std::move(result.name), std::move(result.hash), - page); + page, + refresh); } void Shown::showHtmlWindowed(Prepared result, bool refresh) { @@ -1525,20 +1527,29 @@ void Shown::showMarkdownWindowed( Markdown::MarkdownArticleContent content, QString title, QString initialFragment, - not_null page) { + not_null page, + bool refresh) { _controller = nullptr; - auto options = markdownOpenOptions(std::move(initialFragment), page); - if (_markdownController) { - _markdownController->update( - std::move(content), - std::move(title), - std::move(options)); - } else { + if (!_markdownController) { createMarkdownController( std::move(content), std::move(title), std::move(initialFragment), page); + _markdownController->activate(); + return; + } + auto options = markdownOpenOptions(std::move(initialFragment), page); + if (refresh) { + _markdownController->update( + std::move(content), + std::move(title), + std::move(options)); + } else { + _markdownController->show( + std::move(content), + std::move(title), + std::move(options)); } } diff --git a/Telegram/SourceFiles/iv/markdown/iv_markdown_controller.cpp b/Telegram/SourceFiles/iv/markdown/iv_markdown_controller.cpp index ea637ef3ab..e4558261aa 100644 --- a/Telegram/SourceFiles/iv/markdown/iv_markdown_controller.cpp +++ b/Telegram/SourceFiles/iv/markdown/iv_markdown_controller.cpp @@ -294,6 +294,36 @@ void Controller::update( MarkdownArticleContent content, QString title, OpenOptions options) { + setContent( + std::move(content), + std::move(title), + std::move(options), + true); +} + +void Controller::show( + MarkdownArticleContent content, + QString title, + OpenOptions options) { + setContent( + std::move(content), + std::move(title), + std::move(options), + false); + activate(); +} + +void Controller::setContent( + MarkdownArticleContent content, + QString title, + OpenOptions options, + bool preserveScroll) { + const auto scrollTop = (preserveScroll && _preview) + ? MarkdownPreviewScrollTop(_preview.get()) + : 0; + if (preserveScroll) { + options.initialFragment = QString(); + } _preparedContent = std::move(content); _title = std::move(title); _options = PrepareOpenOptions(std::move(options), _delegate, _title); @@ -307,6 +337,9 @@ void Controller::update( } refreshTitle(); createPreview(); + if (preserveScroll && _preview) { + ScrollMarkdownPreviewToY(_preview.get(), scrollTop); + } if (_window && _window->isActiveWindow() && _preview) { _preview->setFocus(); } @@ -418,10 +451,8 @@ void Controller::updateTitleGeometry(int newWidth) const { - _menuToggle->width()); _subtitle->moveToLeft(st::ivSubtitleLeft, st::ivSubtitleTop); _menuToggle->moveToRight(0, 0); - if (_titleShadow) { - _titleShadow->resizeToWidth(newWidth); - _titleShadow->move(0, st::ivSubtitleHeight); - } + _titleShadow->resizeToWidth(newWidth); + _titleShadow->move(0, st::ivSubtitleHeight); } void Controller::openSource() { @@ -516,21 +547,16 @@ void Controller::createPreview() { parent->sizeValue() | rpl::on_next([=](QSize size) { _preview->resize(size); }, _preview->lifetime()); - if (_titleShadow) { - MarkdownPreviewScrollTopValue( - _preview.get() - ) | rpl::on_next([=](int scrollTop) { - _titleShadow->toggle( - (scrollTop > 0), - anim::type::normal); - }, _preview->lifetime()); - } + + _titleShadow->show(anim::type::instant); + _preview->show(); } void Controller::createWindow() { _window = std::make_unique(); const auto window = _window.get(); + _titleShadow.create(window->body().get()); _subtitleWrap = std::make_unique(window->body().get()); _subtitle = std::make_unique( _subtitleWrap.get(), @@ -570,7 +596,6 @@ void Controller::createWindow() { _container->paintRequest() | rpl::on_next([=](QRect clip) { QPainter(_container).fillRect(clip, st::windowBg); }, _container->lifetime()); - _titleShadow.create(window->body().get()); updateTitleGeometry(window->body()->width()); createLayerManager(); diff --git a/Telegram/SourceFiles/iv/markdown/iv_markdown_controller.h b/Telegram/SourceFiles/iv/markdown/iv_markdown_controller.h index 69f59e3237..7e949a1310 100644 --- a/Telegram/SourceFiles/iv/markdown/iv_markdown_controller.h +++ b/Telegram/SourceFiles/iv/markdown/iv_markdown_controller.h @@ -44,6 +44,10 @@ public: ~Controller(); void activate(); + void show( + MarkdownArticleContent content, + QString title, + OpenOptions options = {}); void update( MarkdownArticleContent content, QString title, @@ -65,6 +69,11 @@ private: void createWindow(); void createLayerManager(); void createPreview(); + void setContent( + MarkdownArticleContent content, + QString title, + OpenOptions options, + bool preserveScroll); void updateTitleGeometry(int newWidth) const; void showMenu(); void openSource(); diff --git a/Telegram/SourceFiles/iv/markdown/iv_markdown_view.cpp b/Telegram/SourceFiles/iv/markdown/iv_markdown_view.cpp index 631dfe8149..74f40a1e13 100644 --- a/Telegram/SourceFiles/iv/markdown/iv_markdown_view.cpp +++ b/Telegram/SourceFiles/iv/markdown/iv_markdown_view.cpp @@ -168,6 +168,8 @@ public: Fn callback, const OpenOptions &options); bool scrollToAnchor(const QString &anchorId); + void scrollToY(int top); + [[nodiscard]] int scrollTop() const; [[nodiscard]] rpl::producer scrollTopValue() const; private: @@ -556,6 +558,16 @@ bool MarkdownPreviewRoot::scrollToAnchor(const QString &anchorId) { return true; } +void MarkdownPreviewRoot::scrollToY(int top) { + if (_scroll) { + _scroll->scrollToY(top); + } +} + +int MarkdownPreviewRoot::scrollTop() const { + return _scroll ? _scroll->scrollTop() : 0; +} + rpl::producer MarkdownPreviewRoot::scrollTopValue() const { return _scroll ? _scroll->scrollTopValue() @@ -569,6 +581,17 @@ bool ScrollMarkdownPreviewToAnchor( return root ? root->scrollToAnchor(anchorId) : false; } +void ScrollMarkdownPreviewToY(Ui::RpWidget *preview, int top) { + if (const auto root = dynamic_cast(preview)) { + root->scrollToY(top); + } +} + +int MarkdownPreviewScrollTop(Ui::RpWidget *preview) { + const auto root = dynamic_cast(preview); + return root ? root->scrollTop() : 0; +} + rpl::producer MarkdownPreviewScrollTopValue(Ui::RpWidget *preview) { const auto root = dynamic_cast(preview); return root ? root->scrollTopValue() : rpl::single(0); diff --git a/Telegram/SourceFiles/iv/markdown/iv_markdown_view.h b/Telegram/SourceFiles/iv/markdown/iv_markdown_view.h index 8e4e19d8e8..ac6678a8e8 100644 --- a/Telegram/SourceFiles/iv/markdown/iv_markdown_view.h +++ b/Telegram/SourceFiles/iv/markdown/iv_markdown_view.h @@ -32,6 +32,8 @@ namespace Iv::Markdown { bool ScrollMarkdownPreviewToAnchor( Ui::RpWidget *preview, const QString &anchorId); +void ScrollMarkdownPreviewToY(Ui::RpWidget *preview, int top); +[[nodiscard]] int MarkdownPreviewScrollTop(Ui::RpWidget *preview); [[nodiscard]] rpl::producer MarkdownPreviewScrollTopValue( Ui::RpWidget *preview);