diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index cfefab843..6b583a8e9 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -3135,6 +3135,17 @@ auto History::findFirstNonEmpty() const -> Element* { return nullptr; } +auto History::findFirstDisplayed() const -> Element* { + for (const auto &block : blocks) { + for (const auto &element : block->messages) { + if (!element->data()->isEmpty() && !element->isHidden()) { + return element.get(); + } + } + } + return nullptr; +} + auto History::findLastNonEmpty() const -> Element* { for (const auto &block : ranges::view::reverse(blocks)) { for (const auto &element : ranges::view::reverse(block->messages)) { @@ -3146,6 +3157,17 @@ auto History::findLastNonEmpty() const -> Element* { return nullptr; } +auto History::findLastDisplayed() const -> Element* { + for (const auto &block : ranges::view::reverse(blocks)) { + for (const auto &element : ranges::view::reverse(block->messages)) { + if (!element->data()->isEmpty() && !element->isHidden()) { + return element.get(); + } + } + } + return nullptr; +} + bool History::nonEmptyCountMoreThan(int count) const { Expects(count >= 0); diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 3ede42830..3006e59a2 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -81,7 +81,9 @@ public: bool isEmpty() const; bool isDisplayedEmpty() const; Element *findFirstNonEmpty() const; + Element *findFirstDisplayed() const; Element *findLastNonEmpty() const; + Element *findLastDisplayed() const; bool hasOrphanMediaGroupPart() const; bool removeOrphanMediaGroupPart(); QVector collectMessagesFromUserToDelete( diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 1d9666f00..5755342ca 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -2432,14 +2432,14 @@ void HistoryInner::adjustCurrent(int32 y, History *history) const { auto HistoryInner::prevItem(Element *view) -> Element* { if (!view) { return nullptr; - } else if (const auto result = view->previousInBlocks()) { + } else if (const auto result = view->previousDisplayedInBlocks()) { return result; } else if (view->data()->history() == _history && _migrated && _history->loadedAtTop() && !_migrated->isEmpty() && _migrated->loadedAtBottom()) { - return _migrated->blocks.back()->messages.back().get(); + return _migrated->findLastDisplayed(); } return nullptr; } @@ -2447,13 +2447,13 @@ auto HistoryInner::prevItem(Element *view) -> Element* { auto HistoryInner::nextItem(Element *view) -> Element* { if (!view) { return nullptr; - } else if (const auto result = view->nextInBlocks()) { + } else if (const auto result = view->nextDisplayedInBlocks()) { return result; } else if (view->data()->history() == _migrated && _migrated->loadedAtBottom() && _history->loadedAtTop() && !_history->isEmpty()) { - return _history->blocks.front()->messages.front().get(); + return _history->findFirstDisplayed(); } return nullptr; } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 34285e6d3..aaa93c06e 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -5044,14 +5044,15 @@ bool HistoryWidget::replyToPreviousMessage() { _replyToId); if (const auto item = session().data().message(fullId)) { if (const auto view = item->mainView()) { - if (const auto previousView = view->previousInBlocks()) { + if (const auto previousView = view->previousDisplayedInBlocks()) { const auto previous = previousView->data(); Ui::showPeerHistoryAtItem(previous); replyToMessage(previous); return true; } } - } else if (const auto previous = _history->lastMessage()) { + } else if (const auto previousView = _history->findLastDisplayed()) { + const auto previous = previousView->data(); Ui::showPeerHistoryAtItem(previous); replyToMessage(previous); return true; @@ -5068,7 +5069,7 @@ bool HistoryWidget::replyToNextMessage() { _replyToId); if (const auto item = session().data().message(fullId)) { if (const auto view = item->mainView()) { - if (const auto nextView = view->nextInBlocks()) { + if (const auto nextView = view->nextDisplayedInBlocks()) { const auto next = nextView->data(); Ui::showPeerHistoryAtItem(next); replyToMessage(next); diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 53b984c11..47de82c0b 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -485,8 +485,14 @@ bool Element::isInOneDayWithPrevious() const { } void Element::recountAttachToPreviousInBlocks() { + if (isHidden() || data()->isEmpty()) { + if (const auto next = nextDisplayedInBlocks()) { + next->recountAttachToPreviousInBlocks(); + } + return; + } auto attachToPrevious = false; - if (const auto previous = previousInBlocks()) { + if (const auto previous = previousDisplayedInBlocks()) { attachToPrevious = computeIsAttachToPrevious(previous); previous->setAttachToNext(attachToPrevious); } @@ -496,11 +502,11 @@ void Element::recountAttachToPreviousInBlocks() { void Element::recountDisplayDateInBlocks() { setDisplayDate([&] { const auto item = data(); - if (item->isEmpty()) { + if (isHidden() || item->isEmpty()) { return false; } - if (const auto previous = previousInBlocks()) { + if (const auto previous = previousDisplayedInBlocks()) { const auto prev = previous->data(); return prev->isEmpty() || (previous->dateTime().date() != dateTime().date()); @@ -707,6 +713,14 @@ Element *Element::previousInBlocks() const { return nullptr; } +Element *Element::previousDisplayedInBlocks() const { + auto result = previousInBlocks(); + while (result && (result->data()->isEmpty() || result->isHidden())) { + result = result->previousInBlocks(); + } + return result; +} + Element *Element::nextInBlocks() const { if (_block && _indexInBlock >= 0) { if (_indexInBlock + 1 < _block->messages.size()) { @@ -720,6 +734,14 @@ Element *Element::nextInBlocks() const { return nullptr; } +Element *Element::nextDisplayedInBlocks() const { + auto result = nextInBlocks(); + while (result && (result->data()->isEmpty() || result->isHidden())) { + result = result->nextInBlocks(); + } + return result; +} + void Element::drawInfo( Painter &p, int right, diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index 85e90ed57..29bae0031 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -296,7 +296,9 @@ public: void setIndexInBlock(int index); int indexInBlock() const; Element *previousInBlocks() const; + Element *previousDisplayedInBlocks() const; Element *nextInBlocks() const; + Element *nextDisplayedInBlocks() const; void previousInBlocksChanged(); void nextInBlocksRemoved();