mirror of https://github.com/procxx/kepka.git
Load more official sets while scrolling.
This commit is contained in:
parent
dfc0491524
commit
46f3cf3395
|
@ -44,6 +44,8 @@ namespace {
|
||||||
constexpr auto kInlineItemsMaxPerRow = 5;
|
constexpr auto kInlineItemsMaxPerRow = 5;
|
||||||
constexpr auto kSearchRequestDelay = 400;
|
constexpr auto kSearchRequestDelay = 400;
|
||||||
constexpr auto kRecentDisplayLimit = 20;
|
constexpr auto kRecentDisplayLimit = 20;
|
||||||
|
constexpr auto kPreloadOfficialPages = 4;
|
||||||
|
constexpr auto kOfficialLoadLimit = 40;
|
||||||
|
|
||||||
bool SetInMyList(MTPDstickerSet::Flags flags) {
|
bool SetInMyList(MTPDstickerSet::Flags flags) {
|
||||||
return (flags & MTPDstickerSet::Flag::f_installed_date)
|
return (flags & MTPDstickerSet::Flag::f_installed_date)
|
||||||
|
@ -891,25 +893,86 @@ void StickersListWidget::checkVisibleFeatured(
|
||||||
readVisibleFeatured(visibleTop, visibleBottom);
|
readVisibleFeatured(visibleTop, visibleBottom);
|
||||||
|
|
||||||
const auto visibleHeight = visibleBottom - visibleTop;
|
const auto visibleHeight = visibleBottom - visibleTop;
|
||||||
|
|
||||||
|
if (visibleBottom > height() - visibleHeight * kPreloadOfficialPages) {
|
||||||
|
preloadMoreOfficial();
|
||||||
|
}
|
||||||
|
|
||||||
const auto rowHeight = featuredRowHeight();
|
const auto rowHeight = featuredRowHeight();
|
||||||
const auto destroyAbove = floorclamp(visibleTop - visibleHeight, rowHeight, 0, _featuredSets.size());
|
const auto destroyAbove = floorclamp(visibleTop - visibleHeight, rowHeight, 0, _officialSets.size());
|
||||||
const auto destroyBelow = ceilclamp(visibleBottom + visibleHeight, rowHeight, 0, _featuredSets.size());
|
const auto destroyBelow = ceilclamp(visibleBottom + visibleHeight, rowHeight, 0, _officialSets.size());
|
||||||
for (auto i = 0; i != destroyAbove; ++i) {
|
for (auto i = 0; i != destroyAbove; ++i) {
|
||||||
destroyLottieIn(_featuredSets[i]);
|
destroyLottieIn(_officialSets[i]);
|
||||||
}
|
}
|
||||||
for (auto i = destroyBelow; i != _featuredSets.size(); ++i) {
|
for (auto i = destroyBelow; i != _officialSets.size(); ++i) {
|
||||||
destroyLottieIn(_featuredSets[i]);
|
destroyLottieIn(_officialSets[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StickersListWidget::preloadMoreOfficial() {
|
||||||
|
if (_officialRequestId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_officialRequestId = _api.request(MTPmessages_GetOldFeaturedStickers(
|
||||||
|
MTP_int(_officialOffset),
|
||||||
|
MTP_int(kOfficialLoadLimit),
|
||||||
|
MTP_int(0)
|
||||||
|
)).done([=](const MTPmessages_FeaturedStickers &result) {
|
||||||
|
_officialRequestId = 0;
|
||||||
|
result.match([&](const MTPDmessages_featuredStickersNotModified &d) {
|
||||||
|
LOG(("Api Error: messages.featuredStickersNotModified."));
|
||||||
|
}, [&](const MTPDmessages_featuredStickers &data) {
|
||||||
|
const auto &list = data.vsets().v;
|
||||||
|
_officialOffset += list.size();
|
||||||
|
for (int i = 0, l = list.size(); i != l; ++i) {
|
||||||
|
auto &data = list[i];
|
||||||
|
const auto setData = data.match([&](const auto &data) {
|
||||||
|
return data.vset().match([](const MTPDstickerSet &data) {
|
||||||
|
return &data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const auto covers = data.match([](const MTPDstickerSetCovered &) {
|
||||||
|
return Stickers::Pack();
|
||||||
|
}, [&](const MTPDstickerSetMultiCovered &data) {
|
||||||
|
auto result = Stickers::Pack();
|
||||||
|
for (const auto &cover : data.vcovers().v) {
|
||||||
|
const auto document = session().data().processDocument(cover);
|
||||||
|
if (document->sticker()) {
|
||||||
|
result.push_back(document);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
if (const auto set = Stickers::FeedSet(*setData)) {
|
||||||
|
if (!covers.empty()) {
|
||||||
|
set->covers = covers;
|
||||||
|
}
|
||||||
|
if (set->stickers.empty() && set->covers.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto externalLayout = true;
|
||||||
|
appendSet(
|
||||||
|
_officialSets,
|
||||||
|
set->id,
|
||||||
|
externalLayout,
|
||||||
|
AppendSkip::Installed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
resizeToWidth(width());
|
||||||
|
update();
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
void StickersListWidget::readVisibleFeatured(
|
void StickersListWidget::readVisibleFeatured(
|
||||||
int visibleTop,
|
int visibleTop,
|
||||||
int visibleBottom) {
|
int visibleBottom) {
|
||||||
const auto rowHeight = featuredRowHeight();
|
const auto rowHeight = featuredRowHeight();
|
||||||
const auto rowFrom = floorclamp(visibleTop, rowHeight, 0, _featuredSets.size());
|
const auto rowFrom = floorclamp(visibleTop, rowHeight, 0, _featuredSetsCount);
|
||||||
const auto rowTo = ceilclamp(visibleBottom, rowHeight, 0, _featuredSets.size());
|
const auto rowTo = ceilclamp(visibleBottom, rowHeight, 0, _featuredSetsCount);
|
||||||
for (auto i = rowFrom; i < rowTo; ++i) {
|
for (auto i = rowFrom; i < rowTo; ++i) {
|
||||||
auto &set = _featuredSets[i];
|
auto &set = _officialSets[i];
|
||||||
if (!(set.flags & MTPDstickerSet_ClientFlag::f_unread)) {
|
if (!(set.flags & MTPDstickerSet_ClientFlag::f_unread)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -925,7 +988,7 @@ void StickersListWidget::readVisibleFeatured(
|
||||||
++loaded;
|
++loaded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (loaded == count) {
|
if (count > 0 && loaded == count) {
|
||||||
session().api().readFeaturedSetDelayed(set.id);
|
session().api().readFeaturedSetDelayed(set.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1217,7 +1280,7 @@ void StickersListWidget::addSearchRow(not_null<const Stickers::Set*> set) {
|
||||||
|
|
||||||
auto StickersListWidget::shownSets() const -> const std::vector<Set> & {
|
auto StickersListWidget::shownSets() const -> const std::vector<Set> & {
|
||||||
switch (_section) {
|
switch (_section) {
|
||||||
case Section::Featured: return _featuredSets;
|
case Section::Featured: return _officialSets;
|
||||||
case Section::Search: return _searchSets;
|
case Section::Search: return _searchSets;
|
||||||
case Section::Stickers: return _mySets;
|
case Section::Stickers: return _mySets;
|
||||||
}
|
}
|
||||||
|
@ -1226,7 +1289,7 @@ auto StickersListWidget::shownSets() const -> const std::vector<Set> & {
|
||||||
|
|
||||||
auto StickersListWidget::shownSets() -> std::vector<Set> & {
|
auto StickersListWidget::shownSets() -> std::vector<Set> & {
|
||||||
switch (_section) {
|
switch (_section) {
|
||||||
case Section::Featured: return _featuredSets;
|
case Section::Featured: return _officialSets;
|
||||||
case Section::Search: return _searchSets;
|
case Section::Search: return _searchSets;
|
||||||
case Section::Stickers: return _mySets;
|
case Section::Stickers: return _mySets;
|
||||||
}
|
}
|
||||||
|
@ -1339,10 +1402,11 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
}
|
}
|
||||||
auto &set = sets[info.section];
|
auto &set = sets[info.section];
|
||||||
if (set.externalLayout) {
|
if (set.externalLayout) {
|
||||||
const auto size = (set.flags
|
const auto loadedCount = int(set.stickers.size());
|
||||||
|
const auto count = (set.flags
|
||||||
& MTPDstickerSet_ClientFlag::f_not_loaded)
|
& MTPDstickerSet_ClientFlag::f_not_loaded)
|
||||||
? set.count
|
? set.count
|
||||||
: int(set.stickers.size());
|
: loadedCount;
|
||||||
|
|
||||||
auto widthForTitle = stickersRight() - (st::emojiPanHeaderLeft - st::buttonRadius);
|
auto widthForTitle = stickersRight() - (st::emojiPanHeaderLeft - st::buttonRadius);
|
||||||
if (featuredHasAddButton(info.section)) {
|
if (featuredHasAddButton(info.section)) {
|
||||||
|
@ -1392,7 +1456,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto statusText = (size > 0) ? tr::lng_stickers_count(tr::now, lt_count, size) : tr::lng_contacts_loading(tr::now);
|
auto statusText = (count > 0) ? tr::lng_stickers_count(tr::now, lt_count, count) : tr::lng_contacts_loading(tr::now);
|
||||||
p.setFont(st::stickersTrendingSubheaderFont);
|
p.setFont(st::stickersTrendingSubheaderFont);
|
||||||
p.setPen(st::stickersTrendingSubheaderFg);
|
p.setPen(st::stickersTrendingSubheaderFg);
|
||||||
p.drawTextLeft(st::emojiPanHeaderLeft - st::buttonRadius, info.top + st::stickersTrendingSubheaderTop, width(), statusText);
|
p.drawTextLeft(st::emojiPanHeaderLeft - st::buttonRadius, info.top + st::stickersTrendingSubheaderTop, width(), statusText);
|
||||||
|
@ -1403,7 +1467,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
|
|
||||||
for (int j = fromColumn; j < toColumn; ++j) {
|
for (int j = fromColumn; j < toColumn; ++j) {
|
||||||
int index = j;
|
int index = j;
|
||||||
if (index >= size) break;
|
if (index >= loadedCount) break;
|
||||||
|
|
||||||
auto selected = selectedSticker ? (selectedSticker->section == info.section && selectedSticker->index == index) : false;
|
auto selected = selectedSticker ? (selectedSticker->section == info.section && selectedSticker->index == index) : false;
|
||||||
auto deleteSelected = false;
|
auto deleteSelected = false;
|
||||||
|
@ -2106,12 +2170,33 @@ void StickersListWidget::refreshMySets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::refreshFeaturedSets() {
|
void StickersListWidget::refreshFeaturedSets() {
|
||||||
_featuredSets.clear();
|
auto wasFeaturedSetsCount = base::take(_featuredSetsCount);
|
||||||
_featuredSets.reserve(session().data().featuredStickerSetsOrder().size());
|
auto wereOfficial = base::take(_officialSets);
|
||||||
|
_officialSets.reserve(
|
||||||
|
session().data().featuredStickerSetsOrder().size()
|
||||||
|
+ wereOfficial.size()
|
||||||
|
- wasFeaturedSetsCount);
|
||||||
for (const auto setId : session().data().featuredStickerSetsOrder()) {
|
for (const auto setId : session().data().featuredStickerSetsOrder()) {
|
||||||
const auto externalLayout = true;
|
const auto externalLayout = true;
|
||||||
appendSet(_featuredSets, setId, externalLayout, AppendSkip::Installed);
|
appendSet(_officialSets, setId, externalLayout, AppendSkip::Installed);
|
||||||
|
}
|
||||||
|
_featuredSetsCount = _officialSets.size();
|
||||||
|
if (wereOfficial.size() > wasFeaturedSetsCount) {
|
||||||
|
auto &sets = session().data().stickerSets();
|
||||||
|
const auto from = begin(wereOfficial) + wasFeaturedSetsCount;
|
||||||
|
const auto till = end(wereOfficial);
|
||||||
|
for (auto i = from; i != till; ++i) {
|
||||||
|
auto &set = *i;
|
||||||
|
auto it = sets.constFind(set.id);
|
||||||
|
if (it == sets.cend()
|
||||||
|
|| ((it->flags & MTPDstickerSet::Flag::f_installed_date)
|
||||||
|
&& !(it->flags & MTPDstickerSet::Flag::f_archived)
|
||||||
|
&& !_installedLocallySets.contains(set.id))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
set.flags = it->flags;
|
||||||
|
_officialSets.push_back(std::move(set));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2237,28 +2322,27 @@ uint64 StickersListWidget::currentSet(int yOffset) const {
|
||||||
: sets[sectionInfoByOffset(yOffset).section].id;
|
: sets[sectionInfoByOffset(yOffset).section].id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::appendSet(
|
bool StickersListWidget::appendSet(
|
||||||
std::vector<Set> &to,
|
std::vector<Set> &to,
|
||||||
uint64 setId,
|
uint64 setId,
|
||||||
bool externalLayout,
|
bool externalLayout,
|
||||||
AppendSkip skip) {
|
AppendSkip skip) {
|
||||||
auto &sets = session().data().stickerSets();
|
auto &sets = session().data().stickerSets();
|
||||||
auto it = sets.constFind(setId);
|
auto it = sets.constFind(setId);
|
||||||
if (it == sets.cend() || it->stickers.isEmpty()) {
|
if (it == sets.cend() || (!externalLayout && it->stickers.isEmpty())) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if ((skip == AppendSkip::Archived)
|
if ((skip == AppendSkip::Archived)
|
||||||
&& (it->flags & MTPDstickerSet::Flag::f_archived)) {
|
&& (it->flags & MTPDstickerSet::Flag::f_archived)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if ((skip == AppendSkip::Installed)
|
if ((skip == AppendSkip::Installed)
|
||||||
&& (it->flags & MTPDstickerSet::Flag::f_installed_date)
|
&& (it->flags & MTPDstickerSet::Flag::f_installed_date)
|
||||||
&& !(it->flags & MTPDstickerSet::Flag::f_archived)) {
|
&& !(it->flags & MTPDstickerSet::Flag::f_archived)) {
|
||||||
if (!_installedLocallySets.contains(setId)) {
|
if (!_installedLocallySets.contains(setId)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
to.emplace_back(
|
to.emplace_back(
|
||||||
it->id,
|
it->id,
|
||||||
it->flags,
|
it->flags,
|
||||||
|
@ -2267,7 +2351,10 @@ void StickersListWidget::appendSet(
|
||||||
it->thumbnail,
|
it->thumbnail,
|
||||||
externalLayout,
|
externalLayout,
|
||||||
it->count,
|
it->count,
|
||||||
PrepareStickers(it->stickers));
|
PrepareStickers((it->stickers.empty() && externalLayout)
|
||||||
|
? it->covers
|
||||||
|
: it->stickers));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::refreshRecent() {
|
void StickersListWidget::refreshRecent() {
|
||||||
|
@ -2477,7 +2564,7 @@ void StickersListWidget::refreshMegagroupStickers(GroupStickersPlace place) {
|
||||||
void StickersListWidget::fillIcons(QList<StickerIcon> &icons) {
|
void StickersListWidget::fillIcons(QList<StickerIcon> &icons) {
|
||||||
icons.clear();
|
icons.clear();
|
||||||
icons.reserve(_mySets.size() + 1);
|
icons.reserve(_mySets.size() + 1);
|
||||||
if (!_featuredSets.empty()) {
|
if (!_officialSets.empty()) {
|
||||||
icons.push_back(StickerIcon(Stickers::FeaturedSetId));
|
icons.push_back(StickerIcon(Stickers::FeaturedSetId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,11 @@ private:
|
||||||
bool externalLayout = false;
|
bool externalLayout = false;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
};
|
};
|
||||||
|
struct FeaturedSet {
|
||||||
|
uint64 id = 0;
|
||||||
|
MTPDstickerSet::Flags flags = MTPDstickerSet::Flags();
|
||||||
|
std::vector<Sticker> stickers;
|
||||||
|
};
|
||||||
struct LottieSet {
|
struct LottieSet {
|
||||||
struct Item {
|
struct Item {
|
||||||
not_null<Lottie::Animation*> animation;
|
not_null<Lottie::Animation*> animation;
|
||||||
|
@ -192,6 +197,7 @@ private:
|
||||||
|
|
||||||
static std::vector<Sticker> PrepareStickers(const Stickers::Pack &pack);
|
static std::vector<Sticker> PrepareStickers(const Stickers::Pack &pack);
|
||||||
|
|
||||||
|
void preloadMoreOfficial();
|
||||||
QSize boundingBoxSize() const;
|
QSize boundingBoxSize() const;
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
|
@ -273,7 +279,7 @@ private:
|
||||||
Archived,
|
Archived,
|
||||||
Installed,
|
Installed,
|
||||||
};
|
};
|
||||||
void appendSet(
|
bool appendSet(
|
||||||
std::vector<Set> &to,
|
std::vector<Set> &to,
|
||||||
uint64 setId,
|
uint64 setId,
|
||||||
bool externalLayout,
|
bool externalLayout,
|
||||||
|
@ -303,13 +309,17 @@ private:
|
||||||
ChannelData *_megagroupSet = nullptr;
|
ChannelData *_megagroupSet = nullptr;
|
||||||
uint64 _megagroupSetIdRequested = 0;
|
uint64 _megagroupSetIdRequested = 0;
|
||||||
std::vector<Set> _mySets;
|
std::vector<Set> _mySets;
|
||||||
std::vector<Set> _featuredSets;
|
std::vector<Set> _officialSets;
|
||||||
std::vector<Set> _searchSets;
|
std::vector<Set> _searchSets;
|
||||||
|
int _featuredSetsCount = 0;
|
||||||
base::flat_set<uint64> _installedLocallySets;
|
base::flat_set<uint64> _installedLocallySets;
|
||||||
std::vector<bool> _custom;
|
std::vector<bool> _custom;
|
||||||
base::flat_set<not_null<DocumentData*>> _favedStickersMap;
|
base::flat_set<not_null<DocumentData*>> _favedStickersMap;
|
||||||
std::weak_ptr<Lottie::FrameRenderer> _lottieRenderer;
|
std::weak_ptr<Lottie::FrameRenderer> _lottieRenderer;
|
||||||
|
|
||||||
|
mtpRequestId _officialRequestId = 0;
|
||||||
|
int _officialOffset = 0;
|
||||||
|
|
||||||
Section _section = Section::Stickers;
|
Section _section = Section::Stickers;
|
||||||
|
|
||||||
bool _displayingSet = false;
|
bool _displayingSet = false;
|
||||||
|
|
Loading…
Reference in New Issue