diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index 58714ae4a..3202b95ec 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -804,8 +804,19 @@ void ListWidget::invalidatePaletteCache() { } } -void ListWidget::registerHeavyItem(not_null item) { - _heavyLayouts.emplace(item); +void ListWidget::registerHeavyItem(not_null item) { + if (!_heavyLayouts.contains(item)) { + _heavyLayouts.emplace(item); + _heavyLayoutsInvalidated = true; + } +} + +void ListWidget::unregisterHeavyItem(not_null item) { + const auto i = _heavyLayouts.find(item); + if (i != _heavyLayouts.end()) { + _heavyLayouts.erase(i); + _heavyLayoutsInvalidated = true; + } } SparseIdsMergedSlice::Key ListWidget::sliceKey( @@ -1114,18 +1125,25 @@ void ListWidget::clearHeavyItems() { if (!visibleHeight) { return; } + _heavyLayoutsInvalidated = false; const auto above = _visibleTop - visibleHeight; const auto below = _visibleBottom + visibleHeight; for (auto i = _heavyLayouts.begin(); i != _heavyLayouts.end();) { - const auto item = *i; + const auto item = const_cast(i->get()); const auto rect = findItemDetails(item).geometry; if (rect.top() + rect.height() <= above || rect.top() >= below) { i = _heavyLayouts.erase(i); item->clearHeavyPart(); + if (_heavyLayoutsInvalidated) { + break; + } } else { ++i; } } + if (_heavyLayoutsInvalidated) { + clearHeavyItems(); + } } auto ListWidget::countScrollState() const -> ScrollTopState { diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.h b/Telegram/SourceFiles/info/media/info_media_list_widget.h index 2bee7b61e..5713cf159 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.h +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.h @@ -76,7 +76,8 @@ public: void saveState(not_null memento); void restoreState(not_null memento); - void registerHeavyItem(not_null item) override; + void registerHeavyItem(not_null item) override; + void unregisterHeavyItem(not_null item) override; private: struct Context; @@ -289,8 +290,9 @@ private: int _idsLimit = kMinimalIdsLimit; SparseIdsMergedSlice _slice; - base::flat_map _layouts; - base::flat_set> _heavyLayouts; + std::unordered_map _layouts; + base::flat_set> _heavyLayouts; + bool _heavyLayoutsInvalidated = false; std::vector
_sections; int _visibleTop = 0; diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index e6e4a2311..433e26815 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -533,6 +533,11 @@ void Video::ensureDataMediaCreated() const { _dataMedia = _data->createMediaView(); _dataMedia->goodThumbnailWanted(); _dataMedia->thumbnailWanted(parent()->fullId()); + delegate()->registerHeavyItem(this); +} + +void Video::clearHeavyPart() { + _dataMedia = nullptr; } float64 Video::dataProgress() const { @@ -828,6 +833,11 @@ void Voice::ensureDataMediaCreated() const { return; } _dataMedia = _data->createMediaView(); + delegate()->registerHeavyItem(this); +} + +void Voice::clearHeavyPart() { + _dataMedia = nullptr; } float64 Voice::dataProgress() const { @@ -1298,6 +1308,11 @@ void Document::ensureDataMediaCreated() const { } _dataMedia = _data->createMediaView(); _dataMedia->thumbnailWanted(parent()->fullId()); + delegate()->registerHeavyItem(this); +} + +void Document::clearHeavyPart() { + _dataMedia = nullptr; } float64 Document::dataProgress() const { @@ -1613,6 +1628,7 @@ void Link::validateThumbnail() { : ImageRoundRadius::Small; _thumbnail = thumbnail->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius); _documentMedia = nullptr; + delegate()->unregisterHeavyItem(this); } } else { const auto size = QSize(st::linksPhotoSize, st::linksPhotoSize); @@ -1654,6 +1670,11 @@ void Link::ensureDocumentMediaCreated() { } _documentMedia = _page->document->createMediaView(); _documentMedia->thumbnailWanted(parent()->fullId()); + delegate()->registerHeavyItem(this); +} + +void Link::clearHeavyPart() { + _documentMedia = nullptr; } TextState Link::getState( diff --git a/Telegram/SourceFiles/overview/overview_layout.h b/Telegram/SourceFiles/overview/overview_layout.h index eabac1376..24bbfb42a 100644 --- a/Telegram/SourceFiles/overview/overview_layout.h +++ b/Telegram/SourceFiles/overview/overview_layout.h @@ -210,6 +210,8 @@ public: QPoint point, StateRequest request) const override; + void clearHeavyPart() override; + protected: float64 dataProgress() const override; bool dataFinished() const override; @@ -244,6 +246,8 @@ public: QPoint point, StateRequest request) const override; + void clearHeavyPart() override; + protected: float64 dataProgress() const override; bool dataFinished() const override; @@ -284,6 +288,8 @@ public: QPoint point, StateRequest request) const override; + void clearHeavyPart() override; + protected: float64 dataProgress() const override; bool dataFinished() const override; @@ -334,6 +340,8 @@ public: QPoint point, StateRequest request) const override; + void clearHeavyPart() override; + protected: const style::RoundCheckbox &checkboxStyle() const override; diff --git a/Telegram/SourceFiles/overview/overview_layout_delegate.h b/Telegram/SourceFiles/overview/overview_layout_delegate.h index addd84430..f57d9d418 100644 --- a/Telegram/SourceFiles/overview/overview_layout_delegate.h +++ b/Telegram/SourceFiles/overview/overview_layout_delegate.h @@ -14,7 +14,8 @@ class ItemBase; class Delegate { public: - virtual void registerHeavyItem(not_null item) = 0; + virtual void registerHeavyItem(not_null item) = 0; + virtual void unregisterHeavyItem(not_null item) = 0; };