mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-19 09:58:52 +00:00
Fix crash in admin log events.
This commit is contained in:
parent
67d12fa6d2
commit
b236844c94
@ -411,9 +411,9 @@ void InnerWidget::requestAdmins() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (auto [user, canEdit] : filtered) {
|
for (auto [user, canEdit] : filtered) {
|
||||||
_admins.push_back(user);
|
_admins.emplace_back(user);
|
||||||
if (canEdit) {
|
if (canEdit) {
|
||||||
_adminsCanEdit.push_back(user);
|
_adminsCanEdit.emplace_back(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -530,8 +530,13 @@ void InnerWidget::saveState(not_null<SectionMemento*> memento) {
|
|||||||
memento->setAdminsCanEdit(std::move(_adminsCanEdit));
|
memento->setAdminsCanEdit(std::move(_adminsCanEdit));
|
||||||
memento->setSearchQuery(std::move(_searchQuery));
|
memento->setSearchQuery(std::move(_searchQuery));
|
||||||
if (!_filterChanged) {
|
if (!_filterChanged) {
|
||||||
memento->setItems(std::move(_items), std::move(_itemsByIds), _upLoaded, _downLoaded);
|
memento->setItems(
|
||||||
memento->setIdManager(std::move(_idManager));
|
base::take(_items),
|
||||||
|
base::take(_eventIds),
|
||||||
|
_upLoaded,
|
||||||
|
_downLoaded);
|
||||||
|
memento->setIdManager(base::take(_idManager));
|
||||||
|
base::take(_itemsByData);
|
||||||
}
|
}
|
||||||
_upLoaded = _downLoaded = true; // Don't load or handle anything anymore.
|
_upLoaded = _downLoaded = true; // Don't load or handle anything anymore.
|
||||||
}
|
}
|
||||||
@ -540,8 +545,9 @@ void InnerWidget::restoreState(not_null<SectionMemento*> memento) {
|
|||||||
_items = memento->takeItems();
|
_items = memento->takeItems();
|
||||||
for (auto &item : _items) {
|
for (auto &item : _items) {
|
||||||
item.refreshView(this);
|
item.refreshView(this);
|
||||||
|
_itemsByData.emplace(item->data(), item.get());
|
||||||
}
|
}
|
||||||
_itemsByIds = memento->takeItemsByIds();
|
_eventIds = memento->takeEventIds();
|
||||||
if (auto manager = memento->takeIdManager()) {
|
if (auto manager = memento->takeIdManager()) {
|
||||||
_idManager = std::move(manager);
|
_idManager = std::move(manager);
|
||||||
}
|
}
|
||||||
@ -614,38 +620,40 @@ void InnerWidget::addEvents(Direction direction, const QVector<MTPChannelAdminLo
|
|||||||
// When loading items down we add them to a new vector and copy _items after them.
|
// When loading items down we add them to a new vector and copy _items after them.
|
||||||
auto newItemsForDownDirection = std::vector<OwnedItem>();
|
auto newItemsForDownDirection = std::vector<OwnedItem>();
|
||||||
auto oldItemsCount = _items.size();
|
auto oldItemsCount = _items.size();
|
||||||
auto &addToItems = (direction == Direction::Up) ? _items : newItemsForDownDirection;
|
auto &addToItems = (direction == Direction::Up)
|
||||||
|
? _items
|
||||||
|
: newItemsForDownDirection;
|
||||||
addToItems.reserve(oldItemsCount + events.size() * 2);
|
addToItems.reserve(oldItemsCount + events.size() * 2);
|
||||||
for_const (auto &event, events) {
|
for (const auto &event : events) {
|
||||||
Assert(event.type() == mtpc_channelAdminLogEvent);
|
event.match([&](const MTPDchannelAdminLogEvent &data) {
|
||||||
const auto &data = event.c_channelAdminLogEvent();
|
const auto id = data.vid.v;
|
||||||
const auto id = data.vid.v;
|
if (_eventIds.find(id) != _eventIds.end()) {
|
||||||
if (_itemsByIds.find(id) != _itemsByIds.cend()) {
|
return;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto count = 0;
|
|
||||||
const auto addOne = [&](OwnedItem item) {
|
|
||||||
_itemsByIds.emplace(id, item.get());
|
|
||||||
_itemsByData.emplace(item->data(), item.get());
|
|
||||||
addToItems.push_back(std::move(item));
|
|
||||||
++count;
|
|
||||||
};
|
|
||||||
GenerateItems(
|
|
||||||
this,
|
|
||||||
_history,
|
|
||||||
_idManager.get(),
|
|
||||||
data,
|
|
||||||
addOne);
|
|
||||||
if (count > 1) {
|
|
||||||
// Reverse the inner order of the added messages, because we load events
|
|
||||||
// from bottom to top but inside one event they go from top to bottom.
|
|
||||||
auto full = addToItems.size();
|
|
||||||
auto from = full - count;
|
|
||||||
for (auto i = 0, toReverse = count / 2; i != toReverse; ++i) {
|
|
||||||
std::swap(addToItems[from + i], addToItems[full - i - 1]);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
auto count = 0;
|
||||||
|
const auto addOne = [&](OwnedItem item) {
|
||||||
|
_eventIds.emplace(id);
|
||||||
|
_itemsByData.emplace(item->data(), item.get());
|
||||||
|
addToItems.push_back(std::move(item));
|
||||||
|
++count;
|
||||||
|
};
|
||||||
|
GenerateItems(
|
||||||
|
this,
|
||||||
|
_history,
|
||||||
|
_idManager.get(),
|
||||||
|
data,
|
||||||
|
addOne);
|
||||||
|
if (count > 1) {
|
||||||
|
// Reverse the inner order of the added messages, because we load events
|
||||||
|
// from bottom to top but inside one event they go from top to bottom.
|
||||||
|
auto full = addToItems.size();
|
||||||
|
auto from = full - count;
|
||||||
|
for (auto i = 0, toReverse = count / 2; i != toReverse; ++i) {
|
||||||
|
std::swap(addToItems[from + i], addToItems[full - i - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
auto newItemsCount = _items.size() + ((direction == Direction::Up) ? 0 : newItemsForDownDirection.size());
|
auto newItemsCount = _items.size() + ((direction == Direction::Up) ? 0 : newItemsForDownDirection.size());
|
||||||
if (newItemsCount != oldItemsCount) {
|
if (newItemsCount != oldItemsCount) {
|
||||||
@ -662,11 +670,11 @@ void InnerWidget::addEvents(Direction direction, const QVector<MTPChannelAdminLo
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::updateMinMaxIds() {
|
void InnerWidget::updateMinMaxIds() {
|
||||||
if (_itemsByIds.empty() || _filterChanged) {
|
if (_eventIds.empty() || _filterChanged) {
|
||||||
_maxId = _minId = 0;
|
_maxId = _minId = 0;
|
||||||
} else {
|
} else {
|
||||||
_maxId = (--_itemsByIds.end())->first;
|
_maxId = *_eventIds.rbegin();
|
||||||
_minId = _itemsByIds.begin()->first;
|
_minId = *_eventIds.begin();
|
||||||
if (_minId == 1) {
|
if (_minId == 1) {
|
||||||
_upLoaded = true;
|
_upLoaded = true;
|
||||||
}
|
}
|
||||||
@ -836,7 +844,8 @@ void InnerWidget::clearAfterFilterChange() {
|
|||||||
_selectedText = TextSelection();
|
_selectedText = TextSelection();
|
||||||
_filterChanged = false;
|
_filterChanged = false;
|
||||||
_items.clear();
|
_items.clear();
|
||||||
_itemsByIds.clear();
|
_eventIds.clear();
|
||||||
|
_itemsByData.clear();
|
||||||
_idManager = nullptr;
|
_idManager = nullptr;
|
||||||
_idManager = _history->adminLogIdManager();
|
_idManager = _history->adminLogIdManager();
|
||||||
updateEmptyText();
|
updateEmptyText();
|
||||||
@ -1133,7 +1142,9 @@ void InnerWidget::suggestRestrictUser(not_null<UserData*> user) {
|
|||||||
auto weak = QPointer<InnerWidget>(this);
|
auto weak = QPointer<InnerWidget>(this);
|
||||||
auto weakBox = std::make_shared<QPointer<EditRestrictedBox>>();
|
auto weakBox = std::make_shared<QPointer<EditRestrictedBox>>();
|
||||||
auto box = Box<EditRestrictedBox>(_channel, user, hasAdminRights, currentRights);
|
auto box = Box<EditRestrictedBox>(_channel, user, hasAdminRights, currentRights);
|
||||||
box->setSaveCallback([user, weak, weakBox](const MTPChatBannedRights &oldRights, const MTPChatBannedRights &newRights) {
|
box->setSaveCallback([=](
|
||||||
|
const MTPChatBannedRights &oldRights,
|
||||||
|
const MTPChatBannedRights &newRights) {
|
||||||
if (weak) {
|
if (weak) {
|
||||||
weak->restrictUser(user, oldRights, newRights);
|
weak->restrictUser(user, oldRights, newRights);
|
||||||
}
|
}
|
||||||
@ -1148,7 +1159,10 @@ void InnerWidget::suggestRestrictUser(not_null<UserData*> user) {
|
|||||||
if (base::contains(_admins, user)) {
|
if (base::contains(_admins, user)) {
|
||||||
editRestrictions(true, MTP_chatBannedRights(MTP_flags(0), MTP_int(0)));
|
editRestrictions(true, MTP_chatBannedRights(MTP_flags(0), MTP_int(0)));
|
||||||
} else {
|
} else {
|
||||||
request(MTPchannels_GetParticipant(_channel->inputChannel, user->inputUser)).done([=](const MTPchannels_ChannelParticipant &result) {
|
request(MTPchannels_GetParticipant(
|
||||||
|
_channel->inputChannel,
|
||||||
|
user->inputUser
|
||||||
|
)).done([=](const MTPchannels_ChannelParticipant &result) {
|
||||||
Expects(result.type() == mtpc_channels_channelParticipant);
|
Expects(result.type() == mtpc_channels_channelParticipant);
|
||||||
|
|
||||||
auto &participant = result.c_channels_channelParticipant();
|
auto &participant = result.c_channels_channelParticipant();
|
||||||
|
@ -190,7 +190,7 @@ private:
|
|||||||
// for each found userpic (from the top to the bottom) using enumerateItems() method.
|
// for each found userpic (from the top to the bottom) using enumerateItems() method.
|
||||||
//
|
//
|
||||||
// Method has "bool (*Method)(not_null<Element*> view, int userpicTop)" signature
|
// Method has "bool (*Method)(not_null<Element*> view, int userpicTop)" signature
|
||||||
// if it returns false the enumeration stops immidiately.
|
// if it returns false the enumeration stops immediately.
|
||||||
template <typename Method>
|
template <typename Method>
|
||||||
void enumerateUserpics(Method method);
|
void enumerateUserpics(Method method);
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ private:
|
|||||||
// for each found date element (from the bottom to the top) using enumerateItems() method.
|
// for each found date element (from the bottom to the top) using enumerateItems() method.
|
||||||
//
|
//
|
||||||
// Method has "bool (*Method)(not_null<HistoryItem*> item, int itemtop, int dateTop)" signature
|
// Method has "bool (*Method)(not_null<HistoryItem*> item, int itemtop, int dateTop)" signature
|
||||||
// if it returns false the enumeration stops immidiately.
|
// if it returns false the enumeration stops immediately.
|
||||||
template <typename Method>
|
template <typename Method>
|
||||||
void enumerateDates(Method method);
|
void enumerateDates(Method method);
|
||||||
|
|
||||||
@ -206,8 +206,8 @@ private:
|
|||||||
not_null<ChannelData*> _channel;
|
not_null<ChannelData*> _channel;
|
||||||
not_null<History*> _history;
|
not_null<History*> _history;
|
||||||
std::vector<OwnedItem> _items;
|
std::vector<OwnedItem> _items;
|
||||||
std::map<uint64, not_null<Element*>> _itemsByIds;
|
std::set<uint64> _eventIds;
|
||||||
std::map<not_null<HistoryItem*>, not_null<Element*>, std::less<>> _itemsByData;
|
std::map<not_null<const HistoryItem*>, not_null<Element*>> _itemsByData;
|
||||||
int _itemsTop = 0;
|
int _itemsTop = 0;
|
||||||
int _itemsWidth = 0;
|
int _itemsWidth = 0;
|
||||||
int _itemsHeight = 0;
|
int _itemsHeight = 0;
|
||||||
|
@ -150,11 +150,11 @@ public:
|
|||||||
|
|
||||||
void setItems(
|
void setItems(
|
||||||
std::vector<OwnedItem> &&items,
|
std::vector<OwnedItem> &&items,
|
||||||
std::map<uint64, not_null<Element*>> &&itemsByIds,
|
std::set<uint64> &&eventIds,
|
||||||
bool upLoaded,
|
bool upLoaded,
|
||||||
bool downLoaded) {
|
bool downLoaded) {
|
||||||
_items = std::move(items);
|
_items = std::move(items);
|
||||||
_itemsByIds = std::move(itemsByIds);
|
_eventIds = std::move(eventIds);
|
||||||
_upLoaded = upLoaded;
|
_upLoaded = upLoaded;
|
||||||
_downLoaded = downLoaded;
|
_downLoaded = downLoaded;
|
||||||
}
|
}
|
||||||
@ -170,8 +170,8 @@ public:
|
|||||||
std::vector<OwnedItem> takeItems() {
|
std::vector<OwnedItem> takeItems() {
|
||||||
return std::move(_items);
|
return std::move(_items);
|
||||||
}
|
}
|
||||||
std::map<uint64, not_null<Element*>> takeItemsByIds() {
|
std::set<uint64> takeEventIds() {
|
||||||
return std::move(_itemsByIds);
|
return std::move(_eventIds);
|
||||||
}
|
}
|
||||||
std::shared_ptr<LocalIdManager> takeIdManager() {
|
std::shared_ptr<LocalIdManager> takeIdManager() {
|
||||||
return std::move(_idManager);
|
return std::move(_idManager);
|
||||||
@ -195,7 +195,7 @@ private:
|
|||||||
std::vector<not_null<UserData*>> _admins;
|
std::vector<not_null<UserData*>> _admins;
|
||||||
std::vector<not_null<UserData*>> _adminsCanEdit;
|
std::vector<not_null<UserData*>> _adminsCanEdit;
|
||||||
std::vector<OwnedItem> _items;
|
std::vector<OwnedItem> _items;
|
||||||
std::map<uint64, not_null<Element*>> _itemsByIds;
|
std::set<uint64> _eventIds;
|
||||||
bool _upLoaded = false;
|
bool _upLoaded = false;
|
||||||
bool _downLoaded = true;
|
bool _downLoaded = true;
|
||||||
std::shared_ptr<LocalIdManager> _idManager;
|
std::shared_ptr<LocalIdManager> _idManager;
|
||||||
|
Loading…
Reference in New Issue
Block a user