diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index 6d4ac95e7..d11dcefa0 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -247,6 +247,7 @@ private: int32 _rowHeight; std::vector> _rows; + std::vector> _oldRows; std::vector _shiftingStartTimes; crl::time _aboveShadowFadeStart = 0; anim::value _aboveShadowFadeOpacity; @@ -1993,6 +1994,7 @@ void StickersBox::Inner::rebuild(bool masks) { auto maxNameWidth = countMaxNameWidth(); + _oldRows = std::move(_rows); clear(); const auto &order = ([&]() -> const StickersSetsOrder & { if (_section == Section::Installed) { @@ -2044,6 +2046,7 @@ void StickersBox::Inner::rebuild(bool masks) { set->accessHash); } } + _oldRows.clear(); session().api().requestStickerSets(); updateSize(); } @@ -2156,19 +2159,55 @@ void StickersBox::Inner::rebuildAppendSet( QString title = fillSetTitle(set, maxNameWidth, &titleWidth); int count = fillSetCount(set); - _rows.push_back(std::make_unique( - set, - sticker, - count, - title, - titleWidth, - installed, - official, - unread, - archived, - removed, - pixw, - pixh)); + const auto existing = [&]{ + const auto now = int(_rows.size()); + const auto setProj = [](const std::unique_ptr &row) { + return row ? row->set.get() : nullptr; + }; + if (_oldRows.size() > now + && setProj(_oldRows[now]) == set.get()) { + return _oldRows.begin() + now; + } + return ranges::find(_oldRows, set.get(), setProj); + }(); + if (existing != end(_oldRows)) { + const auto raw = existing->get(); + raw->sticker = sticker; + raw->count = count; + raw->title = title; + raw->titleWidth = titleWidth; + raw->installed = installed; + raw->official = official; + raw->unread = unread; + raw->archived = archived; + raw->removed = removed; + raw->pixw = pixw; + raw->pixh = pixh; + raw->yadd = {}; + auto oldStickerMedia = std::move(raw->stickerMedia); + auto oldThumbnailMedia = std::move(raw->thumbnailMedia); + raw->stickerMedia = sticker->activeMediaView(); + raw->thumbnailMedia = set->activeThumbnailView(); + if (raw->thumbnailMedia != oldThumbnailMedia + || (!raw->thumbnailMedia && raw->stickerMedia != oldStickerMedia)) { + raw->lottie = nullptr; + } + _rows.push_back(std::move(*existing)); + } else { + _rows.push_back(std::make_unique( + set, + sticker, + count, + title, + titleWidth, + installed, + official, + unread, + archived, + removed, + pixw, + pixh)); + } _shiftingStartTimes.push_back(0); }