Reuse views in gifts lists.

This commit is contained in:
John Preston 2025-01-24 13:36:26 +04:00
parent e3030a168f
commit d778276f5d

View file

@ -84,7 +84,8 @@ private:
}; };
struct View { struct View {
std::unique_ptr<GiftButton> button; std::unique_ptr<GiftButton> button;
int entry = 0; Data::SavedStarGiftId id;
int index = 0;
}; };
void visibleTopBottomUpdated( void visibleTopBottomUpdated(
@ -96,7 +97,7 @@ private:
void loadMore(); void loadMore();
void refreshButtons(); void refreshButtons();
void validateButtons(); void validateButtons();
void showGift(int index); void showGift(Data::SavedStarGiftId id);
void refreshAbout(); void refreshAbout();
int resizeGetHeight(int width) override; int resizeGetHeight(int width) override;
@ -179,8 +180,8 @@ void InnerWidget::subscribeToUpdates() {
--_totalCount; --_totalCount;
} }
for (auto &view : _views) { for (auto &view : _views) {
if (view.entry >= index) { if (view.index >= index) {
--view.entry; --view.index;
} }
} }
} else if (update.action == Action::Save } else if (update.action == Action::Save
@ -191,8 +192,9 @@ void InnerWidget::subscribeToUpdates() {
data.hidden = i->gift.hidden; data.hidden = i->gift.hidden;
}); });
for (auto &view : _views) { for (auto &view : _views) {
if (view.entry == index) { if (view.index == index) {
view.entry = -1; view.index = -1;
view.id = {};
} }
} }
} else { } else {
@ -263,7 +265,6 @@ void InnerWidget::loadMore() {
if (base::take(_reloading)) { if (base::take(_reloading)) {
_entries.clear(); _entries.clear();
_views.clear();
} }
_entries.reserve(_entries.size() + data.vgifts().v.size()); _entries.reserve(_entries.size() + data.vgifts().v.size());
for (const auto &gift : data.vgifts().v) { for (const auto &gift : data.vgifts().v) {
@ -320,30 +321,44 @@ void InnerWidget::validateButtons() {
auto y = vskip + fromRow * oneh; auto y = vskip + fromRow * oneh;
auto views = std::vector<View>(); auto views = std::vector<View>();
views.reserve((tillRow - fromRow) * _perRow); views.reserve((tillRow - fromRow) * _perRow);
const auto idUsed = [&](const Data::SavedStarGiftId &id) {
for (auto j = fromRow; j != tillRow; ++j) {
for (auto i = 0; i != _perRow; ++i) {
const auto index = j * _perRow + i;
if (index >= _entries.size()) {
return false;
} else if (_entries[index].gift.id == id) {
return true;
}
}
}
return false;
};
const auto add = [&](int index) { const auto add = [&](int index) {
const auto already = ranges::find(_views, index, &View::entry); const auto id = _entries[index].gift.id;
const auto already = ranges::find(_views, id, &View::id);
if (already != end(_views)) { if (already != end(_views)) {
views.push_back(base::take(*already)); views.push_back(base::take(*already));
views.back().index = index;
return; return;
} }
const auto &descriptor = _entries[index].descriptor; const auto &descriptor = _entries[index].descriptor;
const auto callback = [=] { const auto callback = [=] {
showGift(index); showGift(id);
}; };
const auto unused = ranges::find_if(_views, [&](const View &v) { const auto unused = ranges::find_if(_views, [&](const View &v) {
return v.button return v.button && !idUsed(v.id);
&& ((v.entry < fromRow * _perRow)
|| (v.entry >= tillRow * _perRow));
}); });
if (unused != end(_views)) { if (unused != end(_views)) {
views.push_back(base::take(*unused)); views.push_back(base::take(*unused));
views.back().entry = index; views.back().index = index;
} else { } else {
auto button = std::make_unique<GiftButton>(this, &_delegate); auto button = std::make_unique<GiftButton>(this, &_delegate);
button->show(); button->show();
views.push_back({ views.push_back({
.button = std::move(button), .button = std::move(button),
.entry = index, .id = id,
.index = index,
}); });
} }
views.back().button->setDescriptor(descriptor, mode); views.back().button->setDescriptor(descriptor, mode);
@ -367,12 +382,15 @@ void InnerWidget::validateButtons() {
std::swap(_views, views); std::swap(_views, views);
} }
void InnerWidget::showGift(int index) { void InnerWidget::showGift(Data::SavedStarGiftId id) {
_window->show(Box( const auto savedId = [](const Entry &entry) {
::Settings::SavedStarGiftBox, return entry.gift.id;
_window, };
_peer, const auto i = ranges::find(_entries, id, savedId);
_entries[index].gift)); if (i != end(_entries)) {
using namespace ::Settings;
_window->show(Box(SavedStarGiftBox, _window, _peer, i->gift));
}
} }
void InnerWidget::refreshAbout() { void InnerWidget::refreshAbout() {