diff --git a/Telegram/SourceFiles/data/data_replies_list.cpp b/Telegram/SourceFiles/data/data_replies_list.cpp index 4c8aac09af..744c295230 100644 --- a/Telegram/SourceFiles/data/data_replies_list.cpp +++ b/Telegram/SourceFiles/data/data_replies_list.cpp @@ -102,10 +102,10 @@ bool RepliesList::buildFromData(not_null viewer) { const auto i = around ? ranges::lower_bound(_list, around, std::greater<>()) : end(_list); - const auto availableBefore = (i - begin(_list)); - const auto availableAfter = (end(_list) - i); - const auto useBefore = std::min(availableBefore, viewer->limitBefore); - const auto useAfter = std::min(availableAfter, viewer->limitAfter + 1); + const auto availableBefore = (end(_list) - i); + const auto availableAfter = (i - begin(_list)); + const auto useBefore = std::min(availableBefore, viewer->limitBefore + 1); + const auto useAfter = std::min(availableAfter, viewer->limitAfter); const auto slice = &viewer->slice; if (_skippedBefore.has_value()) { slice->skippedBefore @@ -115,20 +115,23 @@ bool RepliesList::buildFromData(not_null viewer) { slice->skippedAfter = (*_skippedAfter + (availableAfter - useAfter)); } + const auto channelId = _history->channelId(); slice->ids.clear(); - slice->ids.reserve(useBefore + useAfter); - for (auto j = i - useBefore, e = i + useAfter; j != e; ++j) { + slice->ids.reserve(useAfter + useBefore); + for (auto j = i - useAfter, e = i + useBefore; j != e; ++j) { slice->ids.emplace_back(channelId, *j); } ranges::reverse(slice->ids); + slice->fullCount = _fullCount.current(); - if (_skippedBefore != 0 && useBefore < viewer->limitBefore) { + if (_skippedBefore != 0 && useBefore < viewer->limitBefore + 1) { loadBefore(); } - if (_skippedAfter != 0 && useAfter < viewer->limitAfter + 1) { + if (_skippedAfter != 0 && useAfter < viewer->limitAfter) { loadAfter(); } + return true; } @@ -365,6 +368,11 @@ bool RepliesList::processMessagesIsEmpty(const MTPmessages_Messages &result) { refreshed.insert(refreshed.end(), _list.begin(), _list.end()); _list = std::move(refreshed); } + if (_fullCount.current() && _skippedBefore && !_skippedAfter) { + _skippedAfter = *_fullCount.current() - *_skippedBefore - _list.size(); + } else if (_fullCount.current() && _skippedAfter && !_skippedBefore) { + _skippedBefore = *_fullCount.current() - *_skippedAfter - _list.size(); + } return false; } diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 6eaa667242..5d5226af7b 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -929,15 +929,13 @@ ClickHandlerPtr goToMessageClickHandler( return std::make_shared([=] { if (const auto main = App::main()) { // multi good if (&main->session() == &peer->session()) { - if (const auto returnTo = peer->owner().message(returnToId)) { - if (returnTo->history()->peer == peer) { - main->pushReplyReturn(returnTo); - } - } - main->controller()->showPeerHistory( - peer, - Window::SectionShow::Way::Forward, - msgId); + auto params = Window::SectionShow{ + Window::SectionShow::Way::Forward + }; + params.origin = Window::SectionShow::OriginMessage{ + returnToId + }; + main->controller()->showPeerHistory(peer, params, msgId); } } }); diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 42d70a1c04..bb473a5c3c 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -930,6 +930,26 @@ std::unique_ptr RepliesWidget::createMemento() { return result; } +bool RepliesWidget::showMessage( + PeerId peerId, + const Window::SectionShow ¶ms, + MsgId messageId) { + if (peerId != _history->peer->id) { + return false; + } + const auto id = FullMsgId{ + _history->channelId(), + messageId + }; + const auto message = _history->owner().message(id); + if (!message || message->replyToTop() != _rootId) { + return false; + } + _highlightMessageId = id; + showAtPosition(Data::MessagePosition(message->date(), id)); + return true; +} + void RepliesWidget::saveState(not_null memento) { memento->setReplies(_replies); _inner->saveState(memento->list()); @@ -1092,37 +1112,6 @@ rpl::producer RepliesWidget::listSource( return _replies->source(aroundId, limitBefore, limitAfter); } -void RepliesWidget::highlightSingleNewMessage( - const Data::MessagesSlice &slice) { - const auto guard = gsl::finally([&] { _lastSlice = slice; }); - if (_lastSlice.ids.empty() - || (slice.ids.size() != _lastSlice.ids.size() + 1)) { - return; - } - auto firstDifferent = 0; - while (firstDifferent != _lastSlice.ids.size()) { - if (slice.ids[firstDifferent] != _lastSlice.ids[firstDifferent]) { - break; - } - ++firstDifferent; - } - auto lastDifferent = slice.ids.size() - 1; - while (lastDifferent != firstDifferent) { - if (slice.ids[lastDifferent] != _lastSlice.ids[lastDifferent - 1]) { - break; - } - --lastDifferent; - } - if (firstDifferent != lastDifferent) { - return; - } - const auto newId = slice.ids[firstDifferent]; - if (const auto item = session().data().message(newId)) { - // _highlightMessageId = newId; - showAtPosition(item->position()); - } -} - bool RepliesWidget::listAllowsMultiSelect() { return true; } diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index a1d1ef7ba0..de3c1146f8 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -80,6 +80,10 @@ public: not_null memento, const Window::SectionShow ¶ms) override; std::unique_ptr createMemento() override; + bool showMessage( + PeerId peerId, + const Window::SectionShow ¶ms, + MsgId messageId) override; void setInternalState( const QRect &geometry, @@ -156,7 +160,6 @@ private: not_null item, Api::SendOptions options, mtpRequestId *const saveEditMsgRequestId); - void highlightSingleNewMessage(const Data::MessagesSlice &slice); void chooseAttach(); [[nodiscard]] SendMenu::Type sendMenuType() const; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index ae383f8489..ad7ad4e374 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1221,10 +1221,6 @@ Image *MainWidget::newBackgroundThumb() { : nullptr; } -void MainWidget::pushReplyReturn(not_null item) { - _history->pushReplyReturn(item); -} - void MainWidget::setInnerFocus() { if (_hider || !_history->peer()) { if (!_hider && _mainSection) { @@ -1381,6 +1377,20 @@ void MainWidget::ui_showPeerHistory( return; } } + if (IsServerMsgId(showAtMsgId) + && _mainSection + && _mainSection->showMessage(peerId, params, showAtMsgId)) { + return; + } + + using OriginMessage = SectionShow::OriginMessage; + if (const auto origin = std::get_if(¶ms.origin)) { + if (const auto returnTo = session().data().message(origin->id)) { + if (returnTo->history()->peer->id == peerId) { + _history->pushReplyReturn(returnTo); + } + } + } _controller->dialogsListFocused().set(false, true); _a_dialogsWidth.stop(); @@ -2642,15 +2652,13 @@ void MainWidget::openPeerByName( } const auto returnToId = clickFromMessageId; InvokeQueued(this, [=] { - if (const auto returnTo = session().data().message(returnToId)) { - if (returnTo->history()->peer == peer) { - pushReplyReturn(returnTo); - } - } - _controller->showPeerHistory( - peer->id, - SectionShow::Way::Forward, - msgId); + auto params = SectionShow{ + SectionShow::Way::Forward + }; + params.origin = SectionShow::OriginMessage{ + returnToId + }; + _controller->showPeerHistory(peer->id, params, msgId); }); } } else { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 671462a0ee..b67f80c02f 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -204,8 +204,6 @@ public: void checkChatBackground(); Image *newBackgroundThumb(); - void pushReplyReturn(not_null item); - // Does offerPeer or showPeerHistory. void choosePeer(PeerId peerId, MsgId showAtMsgId); void clearBotStartToken(PeerData *peer); diff --git a/Telegram/SourceFiles/window/section_widget.h b/Telegram/SourceFiles/window/section_widget.h index f5a88e8ebe..68a0790365 100644 --- a/Telegram/SourceFiles/window/section_widget.h +++ b/Telegram/SourceFiles/window/section_widget.h @@ -40,20 +40,20 @@ class AbstractSectionWidget public: AbstractSectionWidget( QWidget *parent, - not_null controller) + not_null controller) : RpWidget(parent) , _controller(controller) { } [[nodiscard]] Main::Session &session() const; - [[nodiscard]] not_null controller() const { + [[nodiscard]] not_null controller() const { return _controller; } // Tabbed selector management. virtual bool pushTabbedSelectorToThirdSection( not_null peer, - const Window::SectionShow ¶ms) { + const SectionShow ¶ms) { return false; } virtual bool returnTabbedSelector() { @@ -61,7 +61,7 @@ public: } private: - const not_null _controller; + const not_null _controller; }; @@ -82,7 +82,7 @@ class SectionWidget : public AbstractSectionWidget { public: SectionWidget( QWidget *parent, - not_null controller); + not_null controller); virtual Dialogs::RowDescriptor activeChat() const { return {}; @@ -118,6 +118,13 @@ public: not_null memento, const SectionShow ¶ms) = 0; + virtual bool showMessage( + PeerId peerId, + const SectionShow ¶ms, + MsgId messageId) { + return false; + } + // Create a memento of that section to store it in the history stack. // This method may modify the section ("take" heavy items). virtual std::unique_ptr createMemento(); @@ -135,7 +142,7 @@ public: } static void PaintBackground( - not_null controller, + not_null controller, not_null widget, QRect clip); @@ -150,7 +157,7 @@ protected: // Called after the hideChildren() call in showAnimated(). virtual void showAnimatedHook( - const Window::SectionSlideParams ¶ms) { + const SectionSlideParams ¶ms) { } // Called after the showChildren() call in showFinished(). diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index 48718bd336..c9b073a774 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -84,6 +84,12 @@ struct SectionShow { Backward, ClearStack, }; + + struct OriginMessage { + FullMsgId id; + }; + using Origin = std::variant; + SectionShow( Way way = Way::Forward, anim::type animated = anim::type::normal, @@ -112,6 +118,7 @@ struct SectionShow { anim::type animated = anim::type::normal; anim::activation activation = anim::activation::normal; bool thirdColumn = false; + Origin origin; };