diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 69b6fffe23..984349d60a 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -4306,6 +4306,15 @@ bool HistoryInner::focusNextPrevChild(bool next) { } void HistoryInner::adjustCurrent(int32 y) const { + auto gapShift = 0; + for (const auto &gap : _collapseGaps) { + if (y < gap.absY + gapShift) { + break; + } + gapShift += gap.height; + } + y -= gapShift; + int32 htop = historyTop(), hdrawtop = historyDrawTop(), mtop = migratedTop(); _curHistory = nullptr; if (mtop >= 0) { diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 79c96fbe0e..4fbf54552f 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -2870,6 +2870,15 @@ TextSelection ListWidget::getSelectedTextRange( int ListWidget::findItemIndexByY(int y) const { Expects(!_items.empty()); + auto gapShift = 0; + for (const auto &gap : _collapseGaps) { + if (y < gap.absY + gapShift) { + break; + } + gapShift += gap.height; + } + y -= gapShift; + if (y < _itemsTop) { return 0; } @@ -2891,7 +2900,11 @@ Element *ListWidget::strictFindItemByY(int y) const { if (_items.empty()) { return nullptr; } - return (y >= _itemsTop && y < _itemsTop + _itemsHeight) + auto gapTotal = 0; + for (const auto &gap : _collapseGaps) { + gapTotal += gap.height; + } + return (y >= _itemsTop && y < _itemsTop + _itemsHeight + gapTotal) ? findItemByY(y).get() : nullptr; } diff --git a/Telegram/SourceFiles/ui/effects/thanos_effect_controller.cpp b/Telegram/SourceFiles/ui/effects/thanos_effect_controller.cpp index 0261d8e63a..c67af812bf 100644 --- a/Telegram/SourceFiles/ui/effects/thanos_effect_controller.cpp +++ b/Telegram/SourceFiles/ui/effects/thanos_effect_controller.cpp @@ -21,8 +21,8 @@ namespace Ui { namespace { constexpr auto kBaseMs = 400; -constexpr auto kPerPixelMs = 0.5; -constexpr auto kMaxMs = 1200; +constexpr auto kPerPixelMs = 0.15; +constexpr auto kMaxMs = 600; } // namespace @@ -36,6 +36,15 @@ ThanosEffectController::ThanosEffectController( ) | rpl::on_next([=](const auto &items) { captureItemsBatch(items); }, lifetime); + + _session->data().historyChanged( + ) | rpl::on_next([=](not_null history) { + if (_restoreScrollPending && history == _capturedHistory) { + _restoreScrollPending = false; + _capturedHistory = nullptr; + _delegate.scrollToY(_savedScrollTop); + } + }, lifetime); } ThanosEffectController::~ThanosEffectController() = default; @@ -45,10 +54,21 @@ void ThanosEffectController::captureItemsBatch( if (!ThanosEffect::Supported()) { return; } - _suppressCollapseAnimation = true; - const auto guard = gsl::finally([&] { - _suppressCollapseAnimation = false; - }); + auto firstHistory = (History*)nullptr; + for (const auto &item : items) { + if (_delegate.viewForItem(item)) { + firstHistory = item->history(); + break; + } + } + if (!firstHistory) { + return; + } + if (!_restoreScrollPending) { + _capturedHistory = firstHistory; + _savedScrollTop = _delegate.scrollArea()->scrollTop(); + _restoreScrollPending = true; + } for (const auto &item : items) { if (const auto view = _delegate.viewForItem(item)) { const auto top = _delegate.itemTop(view); @@ -226,12 +246,6 @@ void ThanosEffectController::startCollapseAnimation( syncCollapseGapsToHost(); - const auto aboveViewport = std::max(0, scrollTop - itemTop); - const auto scrollAdjust = std::min(height, aboveViewport); - if (scrollAdjust > 0) { - _delegate.scrollToY(scrollTop + scrollAdjust); - } - auto totalHeight = 0; for (const auto &gap : _collapseGaps) { totalHeight += gap.currentHeight; @@ -246,7 +260,7 @@ void ThanosEffectController::startCollapseAnimation( 0., 1., duration, - anim::easeOutCirc); + anim::halfSine); } void ThanosEffectController::collapseAnimationCallback() { diff --git a/Telegram/SourceFiles/ui/effects/thanos_effect_controller.h b/Telegram/SourceFiles/ui/effects/thanos_effect_controller.h index bee945003b..dc0eeeb65a 100644 --- a/Telegram/SourceFiles/ui/effects/thanos_effect_controller.h +++ b/Telegram/SourceFiles/ui/effects/thanos_effect_controller.h @@ -24,6 +24,7 @@ namespace HistoryView { class Element; } // namespace HistoryView +class History; class HistoryItem; namespace Ui { @@ -93,11 +94,14 @@ private: base::flat_map< not_null, PreCapturedView> _preCaptured; - bool _suppressCollapseAnimation = false; std::vector _renderGaps; std::vector _collapseGaps; Animations::Simple _collapseAnimation; + + History *_capturedHistory = nullptr; + int _savedScrollTop = 0; + bool _restoreScrollPending = false; }; } // namespace Ui