diff --git a/Telegram/SourceFiles/history/view/history_view_subsection_tabs.cpp b/Telegram/SourceFiles/history/view/history_view_subsection_tabs.cpp index b070db4ca1..564750bc8d 100644 --- a/Telegram/SourceFiles/history/view/history_view_subsection_tabs.cpp +++ b/Telegram/SourceFiles/history/view/history_view_subsection_tabs.cpp @@ -241,45 +241,24 @@ void SubsectionTabs::setupSlider( : scroll->scrollLeftMax(); const auto availableFrom = scrollValue; const auto availableTill = (scrollMax - scrollValue); - if (scrollMax <= 3 * full && _afterAvailable > 0) { + const auto needMore = (scrollMax <= 3 * full && _afterAvailable > 0); + if (needMore) { _beforeLimit *= 2; _afterLimit *= 2; } - const auto findMiddle = [&] { - Expects(!_slice.empty()); - - auto best = -1; - auto bestDistance = -1; - const auto ideal = scrollValue + (full / 2); - for (auto i = 0, count = int(_slice.size()); i != count; ++i) { - const auto a = slider->lookupSectionPosition(i); - const auto b = (i + 1 == count) - ? (full + scrollMax) - : slider->lookupSectionPosition(i + 1); - const auto middle = (a + b) / 2; - const auto distance = std::abs(middle - ideal); - if (best < 0 || distance < bestDistance) { - best = i; - bestDistance = distance; - } - } - - Ensures(best >= 0); - return best; - }; if (availableFrom < full && _beforeSkipped.value_or(0) > 0 && !_slice.empty()) { - _around = _slice[findMiddle()].thread; - refreshSlice(); + refreshAroundMiddle(scroll, slider); } else if (availableTill < full) { if (_afterAvailable > 0) { - _around = _slice[findMiddle()].thread; - refreshSlice(); + refreshAroundMiddle(scroll, slider); } else if (!_afterSkipped.has_value()) { _loading = true; loadMore(); } + } else if (needMore) { + refreshAroundMiddle(scroll, slider); } }, scroll->lifetime()); @@ -641,6 +620,41 @@ void SubsectionTabs::track() { } } +void SubsectionTabs::refreshAroundMiddle( + not_null scroll, + not_null slider) { + Expects(!_slice.empty()); + + const auto full = _vertical ? scroll->height() : scroll->width(); + const auto scrollValue = _vertical + ? scroll->scrollTop() + : scroll->scrollLeft(); + const auto scrollMax = _vertical + ? scroll->scrollTopMax() + : scroll->scrollLeftMax(); + + auto best = -1; + auto bestDistance = -1; + const auto ideal = scrollValue + (full / 2); + for (auto i = 0, count = int(_slice.size()); i != count; ++i) { + const auto a = slider->lookupSectionPosition(i); + const auto b = (i + 1 == count) + ? (full + scrollMax) + : slider->lookupSectionPosition(i + 1); + const auto middle = (a + b) / 2; + const auto distance = std::abs(middle - ideal); + if (best < 0 || distance < bestDistance) { + best = i; + bestDistance = distance; + } + } + + Assert(best >= 0 && best < _slice.size()); + + _around = _slice[best].thread; + refreshSlice(); +} + void SubsectionTabs::refreshSlice() { _refreshScheduled = false; diff --git a/Telegram/SourceFiles/history/view/history_view_subsection_tabs.h b/Telegram/SourceFiles/history/view/history_view_subsection_tabs.h index ef775ee8f4..75a37104ea 100644 --- a/Telegram/SourceFiles/history/view/history_view_subsection_tabs.h +++ b/Telegram/SourceFiles/history/view/history_view_subsection_tabs.h @@ -83,6 +83,9 @@ private: void toggleModes(); void setVisible(bool shown); void refreshSlice(); + void refreshAroundMiddle( + not_null scroll, + not_null slider); void scheduleRefresh(); void loadMore(); void setup(not_null parent);