Fix crash in ChannelsLimitBox.
Fixes https://bugs.telegram.org/c/35214 Deleting `placeholder` in content->heightValue() resulted in `delete` sometimes being called deep inside the layer->show() which already had a reference to that `placeholder` saved and was accessed after -> crash.
This commit is contained in:
parent
c7f11eb05a
commit
d2246337a2
|
@ -68,6 +68,8 @@ public:
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<int> countValue() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void appendRow(not_null<PeerData*> peer, TimeId date);
|
void appendRow(not_null<PeerData*> peer, TimeId date);
|
||||||
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(
|
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(
|
||||||
|
@ -75,6 +77,7 @@ private:
|
||||||
TimeId date) const;
|
TimeId date) const;
|
||||||
|
|
||||||
const not_null<Main::Session*> _session;
|
const not_null<Main::Session*> _session;
|
||||||
|
rpl::variable<int> _count;
|
||||||
mtpRequestId _requestId = 0;
|
mtpRequestId _requestId = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -91,12 +94,15 @@ public:
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
void rowRightActionClicked(not_null<PeerListRow*> row) override;
|
void rowRightActionClicked(not_null<PeerListRow*> row) override;
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<int> countValue() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void appendRow(not_null<PeerData*> peer);
|
void appendRow(not_null<PeerData*> peer);
|
||||||
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(
|
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(
|
||||||
not_null<PeerData*> peer) const;
|
not_null<PeerData*> peer) const;
|
||||||
|
|
||||||
const not_null<Window::SessionNavigation*> _navigation;
|
const not_null<Window::SessionNavigation*> _navigation;
|
||||||
|
rpl::variable<int> _count;
|
||||||
Fn<void()> _closeBox;
|
Fn<void()> _closeBox;
|
||||||
mtpRequestId _requestId = 0;
|
mtpRequestId _requestId = 0;
|
||||||
|
|
||||||
|
@ -210,17 +216,17 @@ void InactiveController::prepare() {
|
||||||
_requestId = _session->api().request(MTPchannels_GetInactiveChannels(
|
_requestId = _session->api().request(MTPchannels_GetInactiveChannels(
|
||||||
)).done([=](const MTPmessages_InactiveChats &result) {
|
)).done([=](const MTPmessages_InactiveChats &result) {
|
||||||
_requestId = 0;
|
_requestId = 0;
|
||||||
result.match([&](const MTPDmessages_inactiveChats &data) {
|
const auto &data = result.data();
|
||||||
_session->data().processUsers(data.vusers());
|
_session->data().processUsers(data.vusers());
|
||||||
const auto &list = data.vchats().v;
|
const auto &list = data.vchats().v;
|
||||||
const auto &dates = data.vdates().v;
|
const auto &dates = data.vdates().v;
|
||||||
for (auto i = 0, count = int(list.size()); i != count; ++i) {
|
for (auto i = 0, count = int(list.size()); i != count; ++i) {
|
||||||
const auto peer = _session->data().processChat(list[i]);
|
const auto peer = _session->data().processChat(list[i]);
|
||||||
const auto date = (i < dates.size()) ? dates[i].v : TimeId();
|
const auto date = (i < dates.size()) ? dates[i].v : TimeId();
|
||||||
appendRow(peer, date);
|
appendRow(peer, date);
|
||||||
}
|
}
|
||||||
delegate()->peerListRefreshRows();
|
delegate()->peerListRefreshRows();
|
||||||
});
|
_count = delegate()->peerListFullRowsCount();
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,6 +234,10 @@ void InactiveController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
delegate()->peerListSetRowChecked(row, !row->checked());
|
delegate()->peerListSetRowChecked(row, !row->checked());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<int> InactiveController::countValue() const {
|
||||||
|
return _count.value();
|
||||||
|
}
|
||||||
|
|
||||||
void InactiveController::appendRow(
|
void InactiveController::appendRow(
|
||||||
not_null<PeerData*> participant,
|
not_null<PeerData*> participant,
|
||||||
TimeId date) {
|
TimeId date) {
|
||||||
|
@ -296,6 +306,10 @@ Main::Session &PublicsController::session() const {
|
||||||
return _navigation->session();
|
return _navigation->session();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<int> PublicsController::countValue() const {
|
||||||
|
return _count.value();
|
||||||
|
}
|
||||||
|
|
||||||
void PublicsController::prepare() {
|
void PublicsController::prepare() {
|
||||||
_requestId = _navigation->session().api().request(
|
_requestId = _navigation->session().api().request(
|
||||||
MTPchannels_GetAdminedPublicChannels(MTP_flags(0))
|
MTPchannels_GetAdminedPublicChannels(MTP_flags(0))
|
||||||
|
@ -315,6 +329,7 @@ void PublicsController::prepare() {
|
||||||
}
|
}
|
||||||
delegate()->peerListRefreshRows();
|
delegate()->peerListRefreshRows();
|
||||||
}
|
}
|
||||||
|
_count = delegate()->peerListFullRowsCount();
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +586,7 @@ void ChannelsLimitBox(
|
||||||
{});
|
{});
|
||||||
|
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
content->heightValue(
|
controller->countValue(
|
||||||
) | rpl::filter(_1 > 0) | rpl::start_with_next([=] {
|
) | rpl::filter(_1 > 0) | rpl::start_with_next([=] {
|
||||||
delete placeholder;
|
delete placeholder;
|
||||||
}, placeholder->lifetime());
|
}, placeholder->lifetime());
|
||||||
|
@ -662,7 +677,7 @@ void PublicLinksLimitBox(
|
||||||
{});
|
{});
|
||||||
|
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
content->heightValue(
|
controller->countValue(
|
||||||
) | rpl::filter(_1 > 0) | rpl::start_with_next([=] {
|
) | rpl::filter(_1 > 0) | rpl::start_with_next([=] {
|
||||||
delete placeholder;
|
delete placeholder;
|
||||||
}, placeholder->lifetime());
|
}, placeholder->lifetime());
|
||||||
|
|
Loading…
Reference in New Issue