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