Clear far enough animated sticker sets.

This commit is contained in:
John Preston 2019-07-01 14:38:10 +02:00
parent 5375e7958c
commit 37689affc5
2 changed files with 57 additions and 19 deletions

View file

@ -730,7 +730,7 @@ StickersListWidget::StickersListWidget(
subscribe(Auth().downloaderTaskFinished(), [=] { subscribe(Auth().downloaderTaskFinished(), [=] {
if (isVisible()) { if (isVisible()) {
update(); update();
readVisibleSets(); readVisibleFeatured(getVisibleTop(), getVisibleBottom());
} }
}); });
subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::ChannelStickersChanged, [this](const Notify::PeerUpdate &update) { subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::ChannelStickersChanged, [this](const Notify::PeerUpdate &update) {
@ -765,25 +765,42 @@ void StickersListWidget::visibleTopBottomUpdated(
int visibleBottom) { int visibleBottom) {
Inner::visibleTopBottomUpdated(visibleTop, visibleBottom); Inner::visibleTopBottomUpdated(visibleTop, visibleBottom);
if (_section == Section::Featured) { if (_section == Section::Featured) {
readVisibleSets(); checkVisibleFeatured(visibleTop, visibleBottom);
} else { } else {
pauseInvisibleLottie(); checkVisibleLottie();
} }
validateSelectedIcon(ValidateIconAnimations::Full); validateSelectedIcon(ValidateIconAnimations::Full);
} }
void StickersListWidget::readVisibleSets() { void StickersListWidget::checkVisibleFeatured(
auto itemsVisibleTop = getVisibleTop(); int visibleTop,
auto itemsVisibleBottom = getVisibleBottom(); int visibleBottom) {
auto rowHeight = featuredRowHeight(); readVisibleFeatured(visibleTop, visibleBottom);
int rowFrom = floorclamp(itemsVisibleTop, rowHeight, 0, _featuredSets.size());
int rowTo = ceilclamp(itemsVisibleBottom, rowHeight, 0, _featuredSets.size()); const auto visibleHeight = visibleBottom - visibleTop;
for (int i = rowFrom; i < rowTo; ++i) { const auto rowHeight = featuredRowHeight();
const auto destroyAbove = floorclamp(visibleTop - visibleHeight, rowHeight, 0, _featuredSets.size());
const auto destroyBelow = ceilclamp(visibleBottom + visibleHeight, rowHeight, 0, _featuredSets.size());
for (auto i = 0; i != destroyAbove; ++i) {
destroyLottieIn(_featuredSets[i]);
}
for (auto i = destroyBelow; i != _featuredSets.size(); ++i) {
destroyLottieIn(_featuredSets[i]);
}
}
void StickersListWidget::readVisibleFeatured(
int visibleTop,
int visibleBottom) {
const auto rowHeight = featuredRowHeight();
const auto rowFrom = floorclamp(visibleTop, rowHeight, 0, _featuredSets.size());
const auto rowTo = ceilclamp(visibleBottom, rowHeight, 0, _featuredSets.size());
for (auto i = rowFrom; i < rowTo; ++i) {
auto &set = _featuredSets[i]; auto &set = _featuredSets[i];
if (!(set.flags & MTPDstickerSet_ClientFlag::f_unread)) { if (!(set.flags & MTPDstickerSet_ClientFlag::f_unread)) {
continue; continue;
} }
if (i * rowHeight < itemsVisibleTop || (i + 1) * rowHeight > itemsVisibleBottom) { if (i * rowHeight < visibleTop || (i + 1) * rowHeight > visibleBottom) {
continue; continue;
} }
int count = qMin(int(set.stickers.size()), _columnCount); int count = qMin(int(set.stickers.size()), _columnCount);
@ -1337,15 +1354,35 @@ void StickersListWidget::markLottieFrameShown(Set &set) {
} }
} }
void StickersListWidget::pauseInvisibleLottie() { void StickersListWidget::checkVisibleLottie() {
if (shownSets().empty()) { if (shownSets().empty()) {
return; return;
} }
const auto visibleTop = getVisibleTop();
const auto visibleBottom = getVisibleBottom(); const auto visibleBottom = getVisibleBottom();
const auto top = sectionInfoByOffset(getVisibleTop()); const auto destroyAfterDistance = (visibleBottom - visibleTop) * 2;
pauseInvisibleLottieIn(top); const auto destroyAbove = visibleTop - destroyAfterDistance;
if (top.rowsBottom < visibleBottom) { const auto destroyBelow = visibleBottom + destroyAfterDistance;
pauseInvisibleLottieIn(sectionInfoByOffset(visibleBottom)); enumerateSections([&](const SectionInfo &info) {
if (destroyBelow <= info.rowsTop
|| destroyAbove >= info.rowsBottom) {
destroyLottieIn(shownSets()[info.section]);
} else if ((visibleTop > info.rowsTop && visibleTop < info.rowsBottom)
|| (visibleBottom > info.rowsTop
&& visibleBottom < info.rowsBottom)) {
pauseInvisibleLottieIn(info);
}
return true;
});
}
void StickersListWidget::destroyLottieIn(Set &set) {
if (!set.lottiePlayer) {
return;
}
set.lottiePlayer = nullptr;
for (auto &sticker : set.stickers) {
sticker.animated = nullptr;
} }
} }

View file

@ -219,9 +219,9 @@ private:
std::vector<Set> &shownSets(); std::vector<Set> &shownSets();
const std::vector<Set> &shownSets() const; const std::vector<Set> &shownSets() const;
int featuredRowHeight() const; int featuredRowHeight() const;
void readVisibleSets(); void checkVisibleFeatured(int visibleTop, int visibleBottom);
void readVisibleFeatured(int visibleTop, int visibleBottom);
void paintFeaturedStickers(Painter &p, QRect clip);
void paintStickers(Painter &p, QRect clip); void paintStickers(Painter &p, QRect clip);
void paintMegagroupEmptySet(Painter &p, int y, bool buttonSelected); void paintMegagroupEmptySet(Painter &p, int y, bool buttonSelected);
void paintSticker(Painter &p, Set &set, int y, int section, int index, bool selected, bool deleteSelected); void paintSticker(Painter &p, Set &set, int y, int section, int index, bool selected, bool deleteSelected);
@ -230,8 +230,9 @@ private:
void ensureLottiePlayer(Set &set); void ensureLottiePlayer(Set &set);
void setupLottie(Set &set, int section, int index); void setupLottie(Set &set, int section, int index);
void markLottieFrameShown(Set &set); void markLottieFrameShown(Set &set);
void pauseInvisibleLottie(); void checkVisibleLottie();
void pauseInvisibleLottieIn(const SectionInfo &info); void pauseInvisibleLottieIn(const SectionInfo &info);
void destroyLottieIn(Set &set);
int stickersRight() const; int stickersRight() const;
bool featuredHasAddButton(int index) const; bool featuredHasAddButton(int index) const;