mirror of
https://github.com/vale981/tdesktop
synced 2025-03-05 09:41:41 -05:00
Clear lottie on panel hide.
This commit is contained in:
parent
a10b91fe1a
commit
db2d24ff32
2 changed files with 145 additions and 42 deletions
|
@ -1012,6 +1012,13 @@ void StickersListWidget::refreshSearchRows(
|
|||
const std::vector<uint64> *cloudSets) {
|
||||
clearSelection();
|
||||
|
||||
const auto wasSection = _section;
|
||||
const auto guard = gsl::finally([&] {
|
||||
if (_section == wasSection && _section == Section::Search) {
|
||||
refillLottieData();
|
||||
}
|
||||
});
|
||||
|
||||
_searchSets.clear();
|
||||
fillLocalSearchRows(_searchNextQuery);
|
||||
|
||||
|
@ -1022,9 +1029,7 @@ void StickersListWidget::refreshSearchRows(
|
|||
return;
|
||||
}
|
||||
|
||||
if (_section != Section::Search) {
|
||||
_section = Section::Search;
|
||||
}
|
||||
setSection(Section::Search);
|
||||
if (cloudSets) {
|
||||
fillCloudSearchRows(*cloudSets);
|
||||
}
|
||||
|
@ -1345,7 +1350,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
|||
}
|
||||
|
||||
void StickersListWidget::markLottieFrameShown(Set &set) {
|
||||
if (const auto player = set.lottiePlayer.get()) {
|
||||
if (const auto player = set.lottiePlayer) {
|
||||
const auto paused = controller()->isGifPausedAtLeastFor(
|
||||
Window::GifPauseReason::SavedGifs);
|
||||
if (!paused) {
|
||||
|
@ -1384,11 +1389,12 @@ void StickersListWidget::destroyLottieIn(Set &set) {
|
|||
for (auto &sticker : set.stickers) {
|
||||
sticker.animated = nullptr;
|
||||
}
|
||||
_lottieData.remove(set.id);
|
||||
}
|
||||
|
||||
void StickersListWidget::pauseInvisibleLottieIn(const SectionInfo &info) {
|
||||
auto &set = shownSets()[info.section];
|
||||
const auto player = set.lottiePlayer.get();
|
||||
const auto player = set.lottiePlayer;
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
@ -1474,15 +1480,19 @@ void StickersListWidget::ensureLottiePlayer(Set &set) {
|
|||
if (set.lottiePlayer) {
|
||||
return;
|
||||
}
|
||||
set.lottiePlayer = std::make_unique<Lottie::MultiPlayer>(
|
||||
getLottieRenderer());
|
||||
const auto raw = set.lottiePlayer.get();
|
||||
set.lottiePlayer->updates(
|
||||
const auto [i, ok] = _lottieData.emplace(
|
||||
set.id,
|
||||
LottieSet{ std::make_unique<Lottie::MultiPlayer>(
|
||||
getLottieRenderer()) });
|
||||
Assert(ok);
|
||||
const auto raw = set.lottiePlayer = i->second.player.get();
|
||||
|
||||
raw->updates(
|
||||
) | rpl::start_with_next([=] {
|
||||
const auto &sets = shownSets();
|
||||
PROFILE_LOG(("WIDGET REPAINT REQUESTED"));
|
||||
enumerateSections([&](const SectionInfo &info) {
|
||||
if (shownSets()[info.section].lottiePlayer.get() == raw) {
|
||||
if (shownSets()[info.section].lottiePlayer == raw) {
|
||||
update(
|
||||
0,
|
||||
info.rowsTop,
|
||||
|
@ -1492,7 +1502,7 @@ void StickersListWidget::ensureLottiePlayer(Set &set) {
|
|||
}
|
||||
return true;
|
||||
});
|
||||
}, lifetime());
|
||||
},i->second.lifetime);
|
||||
}
|
||||
|
||||
void StickersListWidget::setupLottie(Set &set, int section, int index) {
|
||||
|
@ -1501,10 +1511,13 @@ void StickersListWidget::setupLottie(Set &set, int section, int index) {
|
|||
|
||||
ensureLottiePlayer(set);
|
||||
sticker.animated = Stickers::LottieAnimationFromDocument(
|
||||
set.lottiePlayer.get(),
|
||||
set.lottiePlayer,
|
||||
document,
|
||||
Stickers::LottieSize::StickersPanel,
|
||||
boundingBoxSize() * cIntRetinaFactor());
|
||||
_lottieData[set.id].items.emplace(
|
||||
document->id,
|
||||
LottieSet::Item{ sticker.animated });
|
||||
}
|
||||
|
||||
QSize StickersListWidget::boundingBoxSize() const {
|
||||
|
@ -1789,7 +1802,7 @@ void StickersListWidget::removeRecentSticker(int section, int index) {
|
|||
|
||||
clearSelection();
|
||||
bool refresh = false;
|
||||
auto &sticker = _mySets[section].stickers[index];
|
||||
const auto &sticker = _mySets[section].stickers[index];
|
||||
const auto document = sticker.document;
|
||||
auto &recent = Stickers::GetRecentPack();
|
||||
for (int32 i = 0, l = recent.size(); i < l; ++i) {
|
||||
|
@ -1830,7 +1843,7 @@ void StickersListWidget::removeFavedSticker(int section, int index) {
|
|||
}
|
||||
|
||||
clearSelection();
|
||||
auto &sticker = _mySets[section].stickers[index];
|
||||
const auto &sticker = _mySets[section].stickers[index];
|
||||
const auto document = sticker.document;
|
||||
Stickers::SetFaved(document, false);
|
||||
Auth().api().toggleFavedSticker(
|
||||
|
@ -1887,44 +1900,42 @@ TabbedSelector::InnerFooter *StickersListWidget::getFooter() const {
|
|||
|
||||
void StickersListWidget::processHideFinished() {
|
||||
clearSelection();
|
||||
clearLottieData();
|
||||
}
|
||||
|
||||
void StickersListWidget::processPanelHideFinished() {
|
||||
clearInstalledLocally();
|
||||
|
||||
clearLottieData();
|
||||
// Preserve panel state through visibility toggles.
|
||||
//// Reset to the recent stickers section.
|
||||
//if (_section == Section::Featured && (!_footer || !_footer->hasOnlyFeaturedSets())) {
|
||||
// _section = Section::Stickers;
|
||||
// setSection(Section::Stickers);
|
||||
// validateSelectedIcon(ValidateIconAnimations::None);
|
||||
//}
|
||||
}
|
||||
|
||||
void StickersListWidget::setSection(Section section) {
|
||||
if (_section == section) {
|
||||
return;
|
||||
}
|
||||
clearLottieData();
|
||||
_section = section;
|
||||
}
|
||||
|
||||
void StickersListWidget::clearLottieData() {
|
||||
for (auto &set : shownSets()) {
|
||||
destroyLottieIn(set);
|
||||
}
|
||||
_lottieData.clear();
|
||||
}
|
||||
|
||||
void StickersListWidget::refreshStickers() {
|
||||
clearSelection();
|
||||
|
||||
_mySets.clear();
|
||||
_favedStickersMap.clear();
|
||||
_mySets.reserve(Auth().data().stickerSetsOrder().size() + 3);
|
||||
|
||||
refreshFavedStickers();
|
||||
refreshRecentStickers(false);
|
||||
refreshMegagroupStickers(GroupStickersPlace::Visible);
|
||||
for (const auto setId : Auth().data().stickerSetsOrder()) {
|
||||
const auto externalLayout = false;
|
||||
appendSet(_mySets, setId, externalLayout, AppendSkip::Archived);
|
||||
}
|
||||
refreshMegagroupStickers(GroupStickersPlace::Hidden);
|
||||
|
||||
_featuredSets.clear();
|
||||
_featuredSets.reserve(Auth().data().featuredStickerSetsOrder().size());
|
||||
|
||||
for (const auto setId : Auth().data().featuredStickerSetsOrder()) {
|
||||
const auto externalLayout = true;
|
||||
appendSet(_featuredSets, setId, externalLayout, AppendSkip::Installed);
|
||||
}
|
||||
|
||||
refreshMySets();
|
||||
refreshFeaturedSets();
|
||||
refreshSearchSets();
|
||||
refillLottieData();
|
||||
|
||||
resizeToWidth(width());
|
||||
|
||||
|
@ -1938,6 +1949,31 @@ void StickersListWidget::refreshStickers() {
|
|||
update();
|
||||
}
|
||||
|
||||
void StickersListWidget::refreshMySets() {
|
||||
_mySets.clear();
|
||||
_favedStickersMap.clear();
|
||||
_mySets.reserve(Auth().data().stickerSetsOrder().size() + 3);
|
||||
|
||||
refreshFavedStickers();
|
||||
refreshRecentStickers(false);
|
||||
refreshMegagroupStickers(GroupStickersPlace::Visible);
|
||||
for (const auto setId : Auth().data().stickerSetsOrder()) {
|
||||
const auto externalLayout = false;
|
||||
appendSet(_mySets, setId, externalLayout, AppendSkip::Archived);
|
||||
}
|
||||
refreshMegagroupStickers(GroupStickersPlace::Hidden);
|
||||
}
|
||||
|
||||
void StickersListWidget::refreshFeaturedSets() {
|
||||
_featuredSets.clear();
|
||||
_featuredSets.reserve(Auth().data().featuredStickerSetsOrder().size());
|
||||
|
||||
for (const auto setId : Auth().data().featuredStickerSetsOrder()) {
|
||||
const auto externalLayout = true;
|
||||
appendSet(_featuredSets, setId, externalLayout, AppendSkip::Installed);
|
||||
}
|
||||
}
|
||||
|
||||
void StickersListWidget::refreshSearchSets() {
|
||||
refreshSearchIndex();
|
||||
|
||||
|
@ -1946,7 +1982,7 @@ void StickersListWidget::refreshSearchSets() {
|
|||
if (const auto it = sets.find(set.id); it != sets.end()) {
|
||||
set.flags = it->flags;
|
||||
if (!it->stickers.empty()) {
|
||||
// #TODO stickers preserve lottie etc.
|
||||
set.lottiePlayer = nullptr;
|
||||
set.stickers = PrepareStickers(it->stickers);
|
||||
}
|
||||
if (!SetInMyList(set.flags)) {
|
||||
|
@ -1969,6 +2005,53 @@ void StickersListWidget::refreshSearchIndex() {
|
|||
}
|
||||
}
|
||||
|
||||
void StickersListWidget::refillLottieData() {
|
||||
for (auto &set : _lottieData) {
|
||||
set.second.stale = true;
|
||||
}
|
||||
for (auto &set : shownSets()) {
|
||||
refillLottieData(set);
|
||||
}
|
||||
for (auto i = begin(_lottieData); i != end(_lottieData);) {
|
||||
if (i->second.stale) {
|
||||
i = _lottieData.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StickersListWidget::refillLottieData(Set &set) {
|
||||
const auto i = _lottieData.find(set.id);
|
||||
if (i == end(_lottieData)) {
|
||||
return;
|
||||
}
|
||||
i->second.stale = true;
|
||||
auto &items = i->second.items;
|
||||
for (auto &item : items) {
|
||||
item.second.stale = true;
|
||||
}
|
||||
for (auto &sticker : set.stickers) {
|
||||
const auto j = items.find(sticker.document->id);
|
||||
if (j != end(items)) {
|
||||
sticker.animated = j->second.animation;
|
||||
i->second.stale = j->second.stale = false;
|
||||
}
|
||||
}
|
||||
if (i->second.stale) {
|
||||
_lottieData.erase(i);
|
||||
return;
|
||||
}
|
||||
for (auto j = begin(items); j != end(items);) {
|
||||
if (j->second.stale) {
|
||||
j = items.erase(j);
|
||||
} else {
|
||||
++j;
|
||||
}
|
||||
}
|
||||
set.lottiePlayer = i->second.player.get();
|
||||
}
|
||||
|
||||
void StickersListWidget::refreshSettingsVisibility() {
|
||||
const auto visible = (_section == Section::Stickers) && _mySets.empty();
|
||||
_settings->setVisible(visible);
|
||||
|
@ -2128,9 +2211,12 @@ void StickersListWidget::refreshRecentStickers(bool performResize) {
|
|||
recentPack.size(),
|
||||
std::move(recentPack));
|
||||
} else {
|
||||
recentIt->lottiePlayer = nullptr;
|
||||
recentIt->stickers = std::move(recentPack);
|
||||
refillLottieData(*recentIt);
|
||||
}
|
||||
} else if (recentIt != _mySets.end()) {
|
||||
_lottieData.remove(recentIt->id);
|
||||
_mySets.erase(recentIt);
|
||||
}
|
||||
|
||||
|
@ -2449,8 +2535,7 @@ void StickersListWidget::showStickerSet(uint64 setId) {
|
|||
|
||||
if (setId == Stickers::FeaturedSetId) {
|
||||
if (_section != Section::Featured) {
|
||||
_section = Section::Featured;
|
||||
|
||||
setSection(Section::Featured);
|
||||
refreshRecentStickers(true);
|
||||
refreshSettingsVisibility();
|
||||
if (_footer) {
|
||||
|
@ -2466,7 +2551,7 @@ void StickersListWidget::showStickerSet(uint64 setId) {
|
|||
|
||||
auto needRefresh = (_section != Section::Stickers);
|
||||
if (needRefresh) {
|
||||
_section = Section::Stickers;
|
||||
setSection(Section::Stickers);
|
||||
refreshRecentStickers(true);
|
||||
refreshSettingsVisibility();
|
||||
}
|
||||
|
|
|
@ -167,10 +167,20 @@ private:
|
|||
ImagePtr thumbnail;
|
||||
std::vector<Sticker> stickers;
|
||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||
std::unique_ptr<Lottie::MultiPlayer> lottiePlayer;
|
||||
Lottie::MultiPlayer *lottiePlayer = nullptr;
|
||||
bool externalLayout = false;
|
||||
int count = 0;
|
||||
};
|
||||
struct LottieSet {
|
||||
struct Item {
|
||||
not_null<Lottie::Animation*> animation;
|
||||
bool stale = false;
|
||||
};
|
||||
std::unique_ptr<Lottie::MultiPlayer> player;
|
||||
base::flat_map<DocumentId, Item> items;
|
||||
bool stale = false;
|
||||
rpl::lifetime lifetime;
|
||||
};
|
||||
|
||||
static std::vector<Sticker> PrepareStickers(const Stickers::Pack &pack);
|
||||
|
||||
|
@ -181,6 +191,7 @@ private:
|
|||
SectionInfo sectionInfo(int section) const;
|
||||
SectionInfo sectionInfoByOffset(int yOffset) const;
|
||||
|
||||
void setSection(Section section);
|
||||
void displaySet(uint64 setId);
|
||||
void installSet(uint64 setId);
|
||||
void removeMegagroupSet(bool locally);
|
||||
|
@ -188,6 +199,8 @@ private:
|
|||
void sendInstallRequest(
|
||||
uint64 setId,
|
||||
const MTPInputStickerSet &input);
|
||||
void refreshMySets();
|
||||
void refreshFeaturedSets();
|
||||
void refreshSearchSets();
|
||||
void refreshSearchIndex();
|
||||
|
||||
|
@ -233,6 +246,9 @@ private:
|
|||
void checkVisibleLottie();
|
||||
void pauseInvisibleLottieIn(const SectionInfo &info);
|
||||
void destroyLottieIn(Set &set);
|
||||
void refillLottieData();
|
||||
void refillLottieData(Set &set);
|
||||
void clearLottieData();
|
||||
|
||||
int stickersRight() const;
|
||||
bool featuredHasAddButton(int index) const;
|
||||
|
@ -320,6 +336,8 @@ private:
|
|||
QString _searchQuery, _searchNextQuery;
|
||||
mtpRequestId _searchRequestId = 0;
|
||||
|
||||
base::flat_map<uint64, LottieSet> _lottieData;
|
||||
|
||||
rpl::event_stream<not_null<DocumentData*>> _chosen;
|
||||
rpl::event_stream<> _scrollUpdated;
|
||||
rpl::event_stream<> _checkForHide;
|
||||
|
|
Loading…
Add table
Reference in a new issue