From aa0ddf1b37a8e3aaed78464aed77d71315eb3d65 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 1 Jun 2026 18:45:57 +0300 Subject: [PATCH] Added view removal reason to skip animations on rebuilt views. --- Telegram/SourceFiles/data/data_session.cpp | 8 ++++---- Telegram/SourceFiles/data/data_session.h | 13 ++++++++++--- Telegram/SourceFiles/data/data_types.h | 5 +++++ Telegram/SourceFiles/history/history.cpp | 8 +++++--- Telegram/SourceFiles/history/history.h | 4 +++- .../SourceFiles/history/history_inner_widget.cpp | 6 ++++-- Telegram/SourceFiles/history/history_item.cpp | 4 ++-- Telegram/SourceFiles/history/history_item.h | 3 ++- .../history/view/history_view_element.cpp | 4 ++-- .../SourceFiles/history/view/history_view_element.h | 3 ++- 10 files changed, 39 insertions(+), 19 deletions(-) diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 71737fafaa..a989acf8fb 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -2206,12 +2206,12 @@ auto Session::itemsAboutToBeDestroyed() const } void Session::notifyViewAboutToBeRemoved( - not_null view) { - _viewAboutToBeRemoved.fire_copy(view); + not_null view, + ViewRemovalReason reason) { + _viewAboutToBeRemoved.fire({ view, reason }); } -rpl::producer> -Session::viewAboutToBeRemoved() const { +rpl::producer Session::viewAboutToBeRemoved() const { return _viewAboutToBeRemoved.events(); } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index f11957f18e..9578862879 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -159,6 +159,11 @@ struct RequestViewRepaint { QRect rect; }; +struct ViewRemoval { + not_null view; + ViewRemovalReason reason = ViewRemovalReason::Removed; +}; + class Session final { public: using ViewElement = HistoryView::Element; @@ -431,8 +436,10 @@ public: const std::vector> &items); [[nodiscard]] auto itemsAboutToBeDestroyed() const -> rpl::producer>>; - void notifyViewAboutToBeRemoved(not_null view); - [[nodiscard]] rpl::producer> viewAboutToBeRemoved() const; + void notifyViewAboutToBeRemoved( + not_null view, + ViewRemovalReason reason); + [[nodiscard]] rpl::producer viewAboutToBeRemoved() const; void notifyViewRemoved(not_null view); [[nodiscard]] rpl::producer> viewRemoved() const; void notifyHistoryCleared(not_null history); @@ -1182,7 +1189,7 @@ private: rpl::event_stream _reactionsRemoved; rpl::event_stream> _itemRemoved; rpl::event_stream>> _itemsAboutToBeDestroyed; - rpl::event_stream> _viewAboutToBeRemoved; + rpl::event_stream _viewAboutToBeRemoved; rpl::event_stream> _viewRemoved; rpl::event_stream> _viewPaidReactionSent; rpl::event_stream> _callPaidReactionSent; diff --git a/Telegram/SourceFiles/data/data_types.h b/Telegram/SourceFiles/data/data_types.h index 43d1f4faff..0913a660e4 100644 --- a/Telegram/SourceFiles/data/data_types.h +++ b/Telegram/SourceFiles/data/data_types.h @@ -391,6 +391,11 @@ enum class ForwardOptions { NoNamesAndCaptions, }; +enum class ViewRemovalReason : uchar { + Removed, + Detached, +}; + struct ForwardDraft { MessageIdsList ids; ForwardOptions options = ForwardOptions::PreserveInfo; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 41f2c4e1d7..328744c258 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -530,7 +530,7 @@ not_null History::createItem( owner().fillMessagePeers(peer->id, message); if (const auto result = owner().message(peer, id)) { if (detachExistingItem) { - result->removeMainView(); + result->removeMainView(Data::ViewRemovalReason::Detached); } if (result->needsUpdateForVideoQualities(message)) { owner().updateEditedMessage(message); @@ -4418,10 +4418,12 @@ int HistoryBlock::resizeGetHeight(int newWidth, ResizeRequest request) { return _height; } -void HistoryBlock::remove(not_null view) { +void HistoryBlock::remove( + not_null view, + Data::ViewRemovalReason reason) { Expects(view->block() == this); - _history->owner().notifyViewAboutToBeRemoved(view); + _history->owner().notifyViewAboutToBeRemoved(view, reason); _history->mainViewRemoved(this, view); const auto blockIndex = indexInHistory(); diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index aec0e465c9..d76df92b08 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -716,7 +716,9 @@ public: std::vector> messages; - void remove(not_null view); + void remove( + not_null view, + Data::ViewRemovalReason reason = Data::ViewRemovalReason::Removed); void refreshView(not_null view); int resizeGetHeight(int newWidth, ResizeRequest request); diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 4c8b9f538e..8a8c099519 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -4452,8 +4452,10 @@ void HistoryInner::setupThanosEffect() { lifetime()); session().data().viewAboutToBeRemoved( - ) | rpl::on_next([=](not_null view) { - _thanosController->captureOnRemoval(view->data()); + ) | rpl::on_next([=](Data::ViewRemoval removal) { + if (removal.reason == Data::ViewRemovalReason::Removed) { + _thanosController->captureOnRemoval(removal.view->data()); + } }, lifetime()); } diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 047503e6ef..875b641a7b 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -2089,10 +2089,10 @@ void HistoryItem::refreshMainView() { } } -void HistoryItem::removeMainView() { +void HistoryItem::removeMainView(Data::ViewRemovalReason reason) { if (const auto view = mainView()) { _history->owner().notifyHistoryChangeDelayed(_history); - view->removeFromBlock(); + view->removeFromBlock(reason); } } diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index e810551130..ccda5c30c9 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -240,7 +240,8 @@ public: } void refreshMainView(); void clearMainView(); - void removeMainView(); + void removeMainView( + Data::ViewRemovalReason reason = Data::ViewRemovalReason::Removed); void invalidateChatListEntry(); diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 391b73370e..5e3171379b 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -2627,10 +2627,10 @@ void Element::attachToBlock(not_null block, int index) { previousInBlocksChanged(); } -void Element::removeFromBlock() { +void Element::removeFromBlock(Data::ViewRemovalReason reason) { Expects(_block != nullptr); - _block->remove(this); + _block->remove(this, reason); } void Element::refreshInBlock() { diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index b95b8371b6..d6b37119f3 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -638,7 +638,8 @@ public: [[nodiscard]] HistoryBlock *block(); [[nodiscard]] const HistoryBlock *block() const; void attachToBlock(not_null block, int index); - void removeFromBlock(); + void removeFromBlock( + Data::ViewRemovalReason reason = Data::ViewRemovalReason::Removed); void refreshInBlock(); void setIndexInBlock(int index); [[nodiscard]] int indexInBlock() const;