From 4b6d74dd9b870f9d0c1b4e47540caa9c93cdaac4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 2 Oct 2020 19:26:04 +0300 Subject: [PATCH] Fix opening Replies section on unread bar. --- Telegram/SourceFiles/data/data_messages.cpp | 6 +++++ Telegram/SourceFiles/data/data_messages.h | 3 +-- .../SourceFiles/data/data_replies_list.cpp | 11 +++++++++ .../history/view/history_view_list_widget.cpp | 9 +++++--- .../history/view/history_view_list_widget.h | 2 +- .../view/history_view_replies_section.cpp | 23 +++++++++++++++---- .../view/history_view_replies_section.h | 1 + 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/Telegram/SourceFiles/data/data_messages.cpp b/Telegram/SourceFiles/data/data_messages.cpp index 74c81d1a0..857442270 100644 --- a/Telegram/SourceFiles/data/data_messages.cpp +++ b/Telegram/SourceFiles/data/data_messages.cpp @@ -479,9 +479,15 @@ void MessagesSliceBuilder::requestMessagesCount() { MessagesSlice MessagesSliceBuilder::snapshot() const { auto result = MessagesSlice(); result.ids.reserve(_ids.size()); + auto nearestToAround = std::optional(); for (const auto &position : _ids) { result.ids.push_back(position.fullId); + if (!nearestToAround && position >= _key) { + nearestToAround = position.fullId; + } } + result.nearestToAround = nearestToAround.value_or( + _ids.empty() ? FullMsgId() : _ids.back().fullId); result.skippedBefore = _skippedBefore; result.skippedAfter = _skippedAfter; result.fullCount = _fullCount; diff --git a/Telegram/SourceFiles/data/data_messages.h b/Telegram/SourceFiles/data/data_messages.h index 98c214d70..083baf641 100644 --- a/Telegram/SourceFiles/data/data_messages.h +++ b/Telegram/SourceFiles/data/data_messages.h @@ -93,10 +93,10 @@ constexpr auto UnreadMessagePosition = MessagePosition( struct MessagesSlice { std::vector ids; + FullMsgId nearestToAround; std::optional skippedBefore; std::optional skippedAfter; std::optional fullCount; - }; struct MessagesQuery { @@ -112,7 +112,6 @@ struct MessagesQuery { MessagePosition aroundId; int limitBefore = 0; int limitAfter = 0; - }; struct MessagesResult { diff --git a/Telegram/SourceFiles/data/data_replies_list.cpp b/Telegram/SourceFiles/data/data_replies_list.cpp index 41946f0b7..a0bf9d588 100644 --- a/Telegram/SourceFiles/data/data_replies_list.cpp +++ b/Telegram/SourceFiles/data/data_replies_list.cpp @@ -227,6 +227,7 @@ void RepliesList::injectRootDivider( bool RepliesList::buildFromData(not_null viewer) { if (_list.empty() && _skippedBefore == 0 && _skippedAfter == 0) { viewer->slice.ids.clear(); + viewer->slice.nearestToAround = FullMsgId(); viewer->slice.fullCount = viewer->slice.skippedBefore = viewer->slice.skippedAfter @@ -268,10 +269,20 @@ bool RepliesList::buildFromData(not_null viewer) { const auto channelId = _history->channelId(); slice->ids.clear(); + auto nearestToAround = std::optional(); slice->ids.reserve(useAfter + useBefore); for (auto j = i - useAfter, e = i + useBefore; j != e; ++j) { + if (!nearestToAround && *j < around) { + nearestToAround = (j == i - useAfter) + ? *j + : *(j - 1); + } slice->ids.emplace_back(channelId, *j); } + slice->nearestToAround = FullMsgId( + channelId, + nearestToAround.value_or( + slice->ids.empty() ? 0 : slice->ids.back().msg)); slice->fullCount = _fullCount.current(); injectRootMessageAndReverse(slice); diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 59daddc8d..dbca99ca9 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -336,12 +336,16 @@ void ListWidget::refreshRows() { _items.clear(); _items.reserve(_slice.ids.size()); + auto nearestIndex = -1; for (const auto &fullId : _slice.ids) { if (const auto item = session().data().message(fullId)) { + if (_slice.nearestToAround == fullId) { + nearestIndex = int(_items.size()); + } _items.push_back(enforceViewForItem(item)); } } - updateAroundPositionFromRows(); + updateAroundPositionFromNearest(nearestIndex); updateItemsGeometry(); checkUnreadBarCreation(); @@ -573,8 +577,7 @@ not_null ListWidget::enforceViewForItem( return i->second.get(); } -void ListWidget::updateAroundPositionFromRows() { - const auto nearestIndex = findNearestItem(_aroundPosition); +void ListWidget::updateAroundPositionFromNearest(int nearestIndex) { if (nearestIndex < 0) { _aroundIndex = -1; return; diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.h b/Telegram/SourceFiles/history/view/history_view_list_widget.h index c2918e189..5fa88ecde 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.h @@ -305,7 +305,7 @@ private: using CursorState = HistoryView::CursorState; void refreshViewer(); - void updateAroundPositionFromRows(); + void updateAroundPositionFromNearest(int nearestIndex); void refreshRows(); ScrollTopState countScrollState() const; void saveScrollState(); diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 70a80491c..af0a9acae 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -1519,7 +1519,7 @@ void RepliesWidget::updateControlsGeometry() { const auto bottom = height(); const auto controlsHeight = _composeControls->heightCurrent(); - const auto scrollY = _topBar->height() + _rootView->height(); + const auto scrollY = _topBar->height() + _rootViewHeight; const auto scrollHeight = bottom - scrollY - controlsHeight; const auto scrollSize = QSize(contentWidth, scrollHeight); if (_scroll->size() != scrollSize) { @@ -1585,13 +1585,28 @@ void RepliesWidget::updatePinnedVisibility() { return _root; }(); const auto view = _inner->viewByPosition(item->position()); - setPinnedVisibility(!view - || (view->y() + view->height() <= _scroll->scrollTop())); + const auto visible = !view + || (view->y() + view->height() <= _scroll->scrollTop()); + setPinnedVisibility(visible); } void RepliesWidget::setPinnedVisibility(bool shown) { if (!animating()) { - _rootView->toggle(shown, anim::type::normal); + if (!_rootViewInited) { + const auto height = shown ? st::historyReplyHeight : 0; + if (const auto delta = height - _rootViewHeight) { + _rootViewHeight = height; + if (_scroll->scrollTop() == _scroll->scrollTopMax()) { + setGeometryWithTopMoved(geometry(), delta); + } else { + updateControlsGeometry(); + } + } + _rootView->toggle(shown, anim::type::instant); + _rootViewInited = true; + } else { + _rootView->toggle(shown, anim::type::normal); + } } } diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index e58c9e8cd..90c9a64b8 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -255,6 +255,7 @@ private: object_ptr> _rootView; int _rootViewHeight = 0; object_ptr _rootShadow; + bool _rootViewInited = false; std::unique_ptr _scroll;