Improve top senders rebuild.

Fixes #28296.
This commit is contained in:
John Preston 2024-08-21 10:47:27 +02:00
parent 46304c7a2d
commit 6b83c52c7c
2 changed files with 32 additions and 5 deletions

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "payments/ui/payments_reaction_box.h" #include "payments/ui/payments_reaction_box.h"
#include "base/qt/qt_compare.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "ui/boxes/boost_box.h" // MakeBoostFeaturesBadge. #include "ui/boxes/boost_box.h" // MakeBoostFeaturesBadge.
#include "ui/effects/premium_bubble.h" #include "ui/effects/premium_bubble.h"
@ -196,7 +197,7 @@ void PaidReactionSlider(
state->name.setText(st::defaultTextStyle, data.name); state->name.setText(st::defaultTextStyle, data.name);
const auto count = data.count; const auto count = data.count;
const auto photo = data.photo; const auto photo = data.photo->clone();
photo->subscribeToUpdates([=] { photo->subscribeToUpdates([=] {
result->update(); result->update();
}); });
@ -248,7 +249,16 @@ void FillTopReactors(
object_ptr<FixedHeightWidget>(container, height), object_ptr<FixedHeightWidget>(container, height),
st::paidReactTopMargin)); st::paidReactTopMargin));
const auto parent = wrap->entity(); const auto parent = wrap->entity();
struct Key {
std::shared_ptr<DynamicImage> photo;
int count = 0;
QString name;
inline auto operator<=>(const Key &) const = default;
inline bool operator==(const Key &) const = default;
};
struct State { struct State {
base::flat_map<Key, not_null<RpWidget*>> cache;
std::vector<not_null<RpWidget*>> widgets; std::vector<not_null<RpWidget*>> widgets;
rpl::event_stream<> updated; rpl::event_stream<> updated;
std::optional<int> initialChosen; std::optional<int> initialChosen;
@ -290,11 +300,26 @@ void FillTopReactors(
wrap->hide(anim::type::normal); wrap->hide(anim::type::normal);
} else { } else {
for (const auto &widget : state->widgets) { for (const auto &widget : state->widgets) {
delete widget; widget->hide();
} }
state->widgets.clear(); state->widgets.clear();
for (const auto &entry : list) { for (const auto &entry : list) {
state->widgets.push_back(MakeTopReactor(parent, entry)); const auto key = Key{
.photo = entry.photo,
.count = entry.count,
.name = entry.name,
};
const auto i = state->cache.find(key);
const auto widget = (i != end(state->cache))
? i->second
: MakeTopReactor(parent, entry);
state->widgets.push_back(widget);
widget->show();
}
for (const auto &[k, widget] : state->cache) {
if (widget->isHidden()) {
delete widget;
}
} }
wrap->show(anim::type::normal); wrap->show(anim::type::normal);
} }
@ -313,7 +338,7 @@ void FillTopReactors(
} }
const auto count = int(state->widgets.size()); const auto count = int(state->widgets.size());
auto left = (width - single * count) / 2; auto left = (width - single * count) / 2;
for (const auto widget : state->widgets) { for (const auto &widget : state->widgets) {
widget->setGeometry(left, 0, single, height); widget->setGeometry(left, 0, single, height);
left += single; left += single;
} }

View file

@ -261,7 +261,9 @@ void PeerUserpic::subscribeToUpdates(Fn<void()> callback) {
_subscribed = nullptr; _subscribed = nullptr;
return; return;
} }
_subscribed = std::make_unique<Subscribed>(std::move(callback)); const auto old = std::exchange(
_subscribed,
std::make_unique<Subscribed>(std::move(callback)));
_peer->session().changes().peerUpdates( _peer->session().changes().peerUpdates(
_peer, _peer,