mirror of https://github.com/procxx/kepka.git
Improve history items management.
Encapsulate HistoryBlock::y and HistoryBlock::height.
This commit is contained in:
parent
3f2bed8a92
commit
d581e00299
|
@ -312,9 +312,6 @@ enum {
|
||||||
DialogsFirstLoad = 20, // first dialogs part size requested
|
DialogsFirstLoad = 20, // first dialogs part size requested
|
||||||
DialogsPerPage = 500, // next dialogs part size
|
DialogsPerPage = 500, // next dialogs part size
|
||||||
|
|
||||||
MessagesFirstLoad = 30, // first history part size requested
|
|
||||||
MessagesPerPage = 50, // next history part size
|
|
||||||
|
|
||||||
FileLoaderQueueStopTimeout = 5000,
|
FileLoaderQueueStopTimeout = 5000,
|
||||||
|
|
||||||
UseBigFilesFrom = 10 * 1024 * 1024, // mtp big files methods used for files greater than 10mb
|
UseBigFilesFrom = 10 * 1024 * 1024, // mtp big files methods used for files greater than 10mb
|
||||||
|
|
|
@ -36,19 +36,20 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr int kStatusShowClientsideTyping = 6000;
|
constexpr auto kStatusShowClientsideTyping = 6000;
|
||||||
constexpr int kStatusShowClientsideRecordVideo = 6000;
|
constexpr auto kStatusShowClientsideRecordVideo = 6000;
|
||||||
constexpr int kStatusShowClientsideUploadVideo = 6000;
|
constexpr auto kStatusShowClientsideUploadVideo = 6000;
|
||||||
constexpr int kStatusShowClientsideRecordVoice = 6000;
|
constexpr auto kStatusShowClientsideRecordVoice = 6000;
|
||||||
constexpr int kStatusShowClientsideUploadVoice = 6000;
|
constexpr auto kStatusShowClientsideUploadVoice = 6000;
|
||||||
constexpr int kStatusShowClientsideRecordRound = 6000;
|
constexpr auto kStatusShowClientsideRecordRound = 6000;
|
||||||
constexpr int kStatusShowClientsideUploadRound = 6000;
|
constexpr auto kStatusShowClientsideUploadRound = 6000;
|
||||||
constexpr int kStatusShowClientsideUploadPhoto = 6000;
|
constexpr auto kStatusShowClientsideUploadPhoto = 6000;
|
||||||
constexpr int kStatusShowClientsideUploadFile = 6000;
|
constexpr auto kStatusShowClientsideUploadFile = 6000;
|
||||||
constexpr int kStatusShowClientsideChooseLocation = 6000;
|
constexpr auto kStatusShowClientsideChooseLocation = 6000;
|
||||||
constexpr int kStatusShowClientsideChooseContact = 6000;
|
constexpr auto kStatusShowClientsideChooseContact = 6000;
|
||||||
constexpr int kStatusShowClientsidePlayGame = 10000;
|
constexpr auto kStatusShowClientsidePlayGame = 10000;
|
||||||
constexpr int kSetMyActionForMs = 10000;
|
constexpr auto kSetMyActionForMs = 10000;
|
||||||
|
constexpr auto kNewBlockEachMessage = 50;
|
||||||
|
|
||||||
auto GlobalPinnedIndex = 0;
|
auto GlobalPinnedIndex = 0;
|
||||||
|
|
||||||
|
@ -357,11 +358,12 @@ bool History::updateSendActionNeedsAnimating(TimeMs ms, bool force) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelHistory::getRangeDifference() {
|
void ChannelHistory::getRangeDifference() {
|
||||||
auto fromId = MsgId(0), toId = MsgId(0);
|
auto fromId = MsgId(0);
|
||||||
|
auto toId = MsgId(0);
|
||||||
for (auto blockIndex = 0, blocksCount = blocks.size(); blockIndex < blocksCount; ++blockIndex) {
|
for (auto blockIndex = 0, blocksCount = blocks.size(); blockIndex < blocksCount; ++blockIndex) {
|
||||||
auto block = blocks.at(blockIndex);
|
auto block = blocks[blockIndex];
|
||||||
for (auto itemIndex = 0, itemsCount = block->items.size(); itemIndex < itemsCount; ++itemIndex) {
|
for (auto itemIndex = 0, itemsCount = block->items.size(); itemIndex < itemsCount; ++itemIndex) {
|
||||||
auto item = block->items.at(itemIndex);
|
auto item = block->items[itemIndex];
|
||||||
if (item->id > 0) {
|
if (item->id > 0) {
|
||||||
fromId = item->id;
|
fromId = item->id;
|
||||||
break;
|
break;
|
||||||
|
@ -372,9 +374,9 @@ void ChannelHistory::getRangeDifference() {
|
||||||
if (!fromId) return;
|
if (!fromId) return;
|
||||||
|
|
||||||
for (auto blockIndex = blocks.size(); blockIndex > 0;) {
|
for (auto blockIndex = blocks.size(); blockIndex > 0;) {
|
||||||
auto block = blocks.at(--blockIndex);
|
auto block = blocks[--blockIndex];
|
||||||
for (auto itemIndex = block->items.size(); itemIndex > 0;) {
|
for (auto itemIndex = block->items.size(); itemIndex > 0;) {
|
||||||
auto item = block->items.at(--itemIndex);
|
auto item = block->items[--itemIndex];
|
||||||
if (item->id > 0) {
|
if (item->id > 0) {
|
||||||
toId = item->id;
|
toId = item->id;
|
||||||
break;
|
break;
|
||||||
|
@ -428,9 +430,9 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto blockIndex = blocks.size(); blockIndex > 0;) {
|
for (auto blockIndex = blocks.size(); blockIndex > 0;) {
|
||||||
auto block = blocks.at(--blockIndex);
|
auto block = blocks[--blockIndex];
|
||||||
for (auto itemIndex = block->items.size(); itemIndex > 0;) {
|
for (auto itemIndex = block->items.size(); itemIndex > 0;) {
|
||||||
auto item = block->items.at(--itemIndex);
|
auto item = block->items[--itemIndex];
|
||||||
|
|
||||||
// Due to a server bug sometimes inviteDate is less (before) than the
|
// Due to a server bug sometimes inviteDate is less (before) than the
|
||||||
// first message in the megagroup (message about migration), let us
|
// first message in the megagroup (message about migration), let us
|
||||||
|
@ -498,10 +500,10 @@ void ChannelHistory::checkJoinedMessage(bool createUnread) {
|
||||||
void ChannelHistory::checkMaxReadMessageDate() {
|
void ChannelHistory::checkMaxReadMessageDate() {
|
||||||
if (_maxReadMessageDate.isValid()) return;
|
if (_maxReadMessageDate.isValid()) return;
|
||||||
|
|
||||||
for (int blockIndex = blocks.size(); blockIndex > 0;) {
|
for (auto blockIndex = blocks.size(); blockIndex > 0;) {
|
||||||
HistoryBlock *block = blocks.at(--blockIndex);
|
auto block = blocks[--blockIndex];
|
||||||
for (int itemIndex = block->items.size(); itemIndex > 0;) {
|
for (auto itemIndex = block->items.size(); itemIndex > 0;) {
|
||||||
HistoryItem *item = block->items.at(--itemIndex);
|
auto item = block->items[--itemIndex];
|
||||||
if (!item->unread()) {
|
if (!item->unread()) {
|
||||||
_maxReadMessageDate = item->date;
|
_maxReadMessageDate = item->date;
|
||||||
if (item->isGroupMigrate() && isMegagroup() && peer->migrateFrom()) {
|
if (item->isGroupMigrate() && isMegagroup() && peer->migrateFrom()) {
|
||||||
|
@ -1105,7 +1107,7 @@ void History::eraseFromOverview(MediaOverviewType type, MsgId msgId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::addNewItem(HistoryItem *adding, bool newMsg) {
|
HistoryItem *History::addNewItem(HistoryItem *adding, bool newMsg) {
|
||||||
t_assert(!isBuildingFrontBlock());
|
Expects(!isBuildingFrontBlock());
|
||||||
addItemToBlock(adding);
|
addItemToBlock(adding);
|
||||||
|
|
||||||
setLastMessage(adding);
|
setLastMessage(adding);
|
||||||
|
@ -1237,12 +1239,12 @@ HistoryBlock *History::prepareBlockForAddingItem() {
|
||||||
result->setIndexInHistory(0);
|
result->setIndexInHistory(0);
|
||||||
blocks.push_front(result);
|
blocks.push_front(result);
|
||||||
for (int i = 1, l = blocks.size(); i < l; ++i) {
|
for (int i = 1, l = blocks.size(); i < l; ++i) {
|
||||||
blocks.at(i)->setIndexInHistory(i);
|
blocks[i]->setIndexInHistory(i);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addNewBlock = blocks.isEmpty() || (blocks.back()->items.size() >= MessagesPerPage);
|
auto addNewBlock = blocks.isEmpty() || (blocks.back()->items.size() >= kNewBlockEachMessage);
|
||||||
if (!addNewBlock) {
|
if (!addNewBlock) {
|
||||||
return blocks.back();
|
return blocks.back();
|
||||||
}
|
}
|
||||||
|
@ -1251,13 +1253,13 @@ HistoryBlock *History::prepareBlockForAddingItem() {
|
||||||
result->setIndexInHistory(blocks.size());
|
result->setIndexInHistory(blocks.size());
|
||||||
blocks.push_back(result);
|
blocks.push_back(result);
|
||||||
|
|
||||||
result->items.reserve(MessagesPerPage);
|
result->items.reserve(kNewBlockEachMessage);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
void History::addItemToBlock(HistoryItem *item) {
|
void History::addItemToBlock(HistoryItem *item) {
|
||||||
t_assert(item != nullptr);
|
Expects(item != nullptr);
|
||||||
t_assert(item->detached());
|
Expects(item->detached());
|
||||||
|
|
||||||
auto block = prepareBlockForAddingItem();
|
auto block = prepareBlockForAddingItem();
|
||||||
|
|
||||||
|
@ -1311,7 +1313,7 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice) {
|
||||||
// lastParticipants are displayed in Profile as members list.
|
// lastParticipants are displayed in Profile as members list.
|
||||||
markupSenders = &peer->asChannel()->mgInfo->markupSenders;
|
markupSenders = &peer->asChannel()->mgInfo->markupSenders;
|
||||||
}
|
}
|
||||||
for (int32 i = block->items.size(); i > 0; --i) {
|
for (auto i = block->items.size(); i > 0; --i) {
|
||||||
auto item = block->items[i - 1];
|
auto item = block->items[i - 1];
|
||||||
mask |= item->addToOverview(AddToOverviewFront);
|
mask |= item->addToOverview(AddToOverviewFront);
|
||||||
if (item->from()->id) {
|
if (item->from()->id) {
|
||||||
|
@ -1593,14 +1595,14 @@ void History::getNextShowFrom(HistoryBlock *block, int i) {
|
||||||
auto l = block->items.size();
|
auto l = block->items.size();
|
||||||
for (++i; i < l; ++i) {
|
for (++i; i < l; ++i) {
|
||||||
if (block->items[i]->id > 0) {
|
if (block->items[i]->id > 0) {
|
||||||
showFrom = block->items.at(i);
|
showFrom = block->items[i];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto j = block->indexInHistory() + 1, s = blocks.size(); j < s; ++j) {
|
for (auto j = block->indexInHistory() + 1, s = blocks.size(); j < s; ++j) {
|
||||||
block = blocks.at(j);
|
block = blocks[j];
|
||||||
for_const (auto item, block->items) {
|
for_const (auto item, block->items) {
|
||||||
if (item->id > 0) {
|
if (item->id > 0) {
|
||||||
showFrom = item;
|
showFrom = item;
|
||||||
|
@ -1614,7 +1616,7 @@ void History::getNextShowFrom(HistoryBlock *block, int i) {
|
||||||
void History::countScrollState(int top) {
|
void History::countScrollState(int top) {
|
||||||
countScrollTopItem(top);
|
countScrollTopItem(top);
|
||||||
if (scrollTopItem) {
|
if (scrollTopItem) {
|
||||||
scrollTopOffset = (top - scrollTopItem->block()->y - scrollTopItem->y);
|
scrollTopOffset = (top - scrollTopItem->block()->y() - scrollTopItem->y());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1628,22 +1630,22 @@ void History::countScrollTopItem(int top) {
|
||||||
if (scrollTopItem && !scrollTopItem->detached()) {
|
if (scrollTopItem && !scrollTopItem->detached()) {
|
||||||
itemIndex = scrollTopItem->indexInBlock();
|
itemIndex = scrollTopItem->indexInBlock();
|
||||||
blockIndex = scrollTopItem->block()->indexInHistory();
|
blockIndex = scrollTopItem->block()->indexInHistory();
|
||||||
itemTop = blocks.at(blockIndex)->y + scrollTopItem->y;
|
itemTop = blocks[blockIndex]->y() + scrollTopItem->y();
|
||||||
}
|
}
|
||||||
if (itemTop > top) {
|
if (itemTop > top) {
|
||||||
// go backward through history while we don't find an item that starts above
|
// go backward through history while we don't find an item that starts above
|
||||||
do {
|
do {
|
||||||
HistoryBlock *block = blocks.at(blockIndex);
|
auto block = blocks[blockIndex];
|
||||||
for (--itemIndex; itemIndex >= 0; --itemIndex) {
|
for (--itemIndex; itemIndex >= 0; --itemIndex) {
|
||||||
HistoryItem *item = block->items.at(itemIndex);
|
auto item = block->items[itemIndex];
|
||||||
itemTop = block->y + item->y;
|
itemTop = block->y() + item->y();
|
||||||
if (itemTop <= top) {
|
if (itemTop <= top) {
|
||||||
scrollTopItem = item;
|
scrollTopItem = item;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (--blockIndex >= 0) {
|
if (--blockIndex >= 0) {
|
||||||
itemIndex = blocks.at(blockIndex)->items.size();
|
itemIndex = blocks[blockIndex]->items.size();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1653,16 +1655,16 @@ void History::countScrollTopItem(int top) {
|
||||||
} else {
|
} else {
|
||||||
// go forward through history while we don't find the last item that starts above
|
// go forward through history while we don't find the last item that starts above
|
||||||
for (int blocksCount = blocks.size(); blockIndex < blocksCount; ++blockIndex) {
|
for (int blocksCount = blocks.size(); blockIndex < blocksCount; ++blockIndex) {
|
||||||
HistoryBlock *block = blocks.at(blockIndex);
|
auto block = blocks[blockIndex];
|
||||||
for (int itemsCount = block->items.size(); itemIndex < itemsCount; ++itemIndex) {
|
for (int itemsCount = block->items.size(); itemIndex < itemsCount; ++itemIndex) {
|
||||||
HistoryItem *item = block->items.at(itemIndex);
|
auto item = block->items[itemIndex];
|
||||||
itemTop = block->y + item->y;
|
itemTop = block->y() + item->y();
|
||||||
if (itemTop > top) {
|
if (itemTop > top) {
|
||||||
t_assert(itemIndex > 0 || blockIndex > 0);
|
t_assert(itemIndex > 0 || blockIndex > 0);
|
||||||
if (itemIndex > 0) {
|
if (itemIndex > 0) {
|
||||||
scrollTopItem = block->items.at(itemIndex - 1);
|
scrollTopItem = block->items[itemIndex - 1];
|
||||||
} else {
|
} else {
|
||||||
scrollTopItem = blocks.at(blockIndex - 1)->items.back();
|
scrollTopItem = blocks[blockIndex - 1]->items.back();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1676,12 +1678,12 @@ void History::countScrollTopItem(int top) {
|
||||||
void History::getNextScrollTopItem(HistoryBlock *block, int32 i) {
|
void History::getNextScrollTopItem(HistoryBlock *block, int32 i) {
|
||||||
++i;
|
++i;
|
||||||
if (i > 0 && i < block->items.size()) {
|
if (i > 0 && i < block->items.size()) {
|
||||||
scrollTopItem = block->items.at(i);
|
scrollTopItem = block->items[i];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int j = block->indexInHistory() + 1;
|
int j = block->indexInHistory() + 1;
|
||||||
if (j > 0 && j < blocks.size()) {
|
if (j > 0 && j < blocks.size()) {
|
||||||
scrollTopItem = blocks.at(j)->items.front();
|
scrollTopItem = blocks[j]->items.front();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scrollTopItem = nullptr;
|
scrollTopItem = nullptr;
|
||||||
|
@ -1707,12 +1709,12 @@ void History::destroyUnreadBar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex, int32 itemIndex) {
|
HistoryItem *History::addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex, int32 itemIndex) {
|
||||||
t_assert(blockIndex >= 0);
|
Expects(blockIndex >= 0);
|
||||||
t_assert(blockIndex < blocks.size());
|
Expects(blockIndex < blocks.size());
|
||||||
t_assert(itemIndex >= 0);
|
Expects(itemIndex >= 0);
|
||||||
t_assert(itemIndex <= blocks[blockIndex]->items.size());
|
Expects(itemIndex <= blocks[blockIndex]->items.size());
|
||||||
|
|
||||||
auto block = blocks.at(blockIndex);
|
auto block = blocks[blockIndex];
|
||||||
|
|
||||||
newItem->attachToBlock(block, itemIndex);
|
newItem->attachToBlock(block, itemIndex);
|
||||||
block->items.insert(itemIndex, newItem);
|
block->items.insert(itemIndex, newItem);
|
||||||
|
@ -1747,7 +1749,7 @@ HistoryBlock *History::finishBuildingFrontBlock() {
|
||||||
if (block) {
|
if (block) {
|
||||||
if (blocks.size() > 1) {
|
if (blocks.size() > 1) {
|
||||||
auto last = block->items.back(); // ... item, item, item, last ], [ first, item, item ...
|
auto last = block->items.back(); // ... item, item, item, last ], [ first, item, item ...
|
||||||
auto first = blocks.at(1)->items.front();
|
auto first = blocks[1]->items.front();
|
||||||
|
|
||||||
// we've added a new front block, so previous item for
|
// we've added a new front block, so previous item for
|
||||||
// the old first item of a first block was changed
|
// the old first item of a first block was changed
|
||||||
|
@ -1942,8 +1944,8 @@ int History::resizeGetHeight(int newWidth) {
|
||||||
|
|
||||||
width = newWidth;
|
width = newWidth;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
for_const (HistoryBlock *block, blocks) {
|
for_const (auto block, blocks) {
|
||||||
block->y = y;
|
block->setY(y);
|
||||||
y += block->resizeGetHeight(newWidth, resizeAllItems);
|
y += block->resizeGetHeight(newWidth, resizeAllItems);
|
||||||
}
|
}
|
||||||
height = y;
|
height = y;
|
||||||
|
@ -2179,11 +2181,11 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::changeMsgId(MsgId oldId, MsgId newId) {
|
void History::changeMsgId(MsgId oldId, MsgId newId) {
|
||||||
for (int32 i = 0; i < OverviewCount; ++i) {
|
for (auto i = 0; i < OverviewCount; ++i) {
|
||||||
auto j = overviewIds[i].find(oldId);
|
auto j = overviewIds[i].find(oldId);
|
||||||
if (j != overviewIds[i].cend()) {
|
if (j != overviewIds[i].cend()) {
|
||||||
overviewIds[i].erase(j);
|
overviewIds[i].erase(j);
|
||||||
int32 index = overview[i].indexOf(oldId);
|
auto index = overview[i].indexOf(oldId);
|
||||||
if (overviewIds[i].constFind(newId) == overviewIds[i].cend()) {
|
if (overviewIds[i].constFind(newId) == overviewIds[i].cend()) {
|
||||||
overviewIds[i].insert(newId);
|
overviewIds[i].insert(newId);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
|
@ -2199,7 +2201,7 @@ void History::changeMsgId(MsgId oldId, MsgId newId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::removeBlock(HistoryBlock *block) {
|
void History::removeBlock(HistoryBlock *block) {
|
||||||
t_assert(block->items.isEmpty());
|
Expects(block->items.isEmpty());
|
||||||
|
|
||||||
if (_buildingFrontBlock && block == _buildingFrontBlock->block) {
|
if (_buildingFrontBlock && block == _buildingFrontBlock->block) {
|
||||||
_buildingFrontBlock->block = nullptr;
|
_buildingFrontBlock->block = nullptr;
|
||||||
|
@ -2209,9 +2211,9 @@ void History::removeBlock(HistoryBlock *block) {
|
||||||
blocks.removeAt(index);
|
blocks.removeAt(index);
|
||||||
if (index < blocks.size()) {
|
if (index < blocks.size()) {
|
||||||
for (int i = index, l = blocks.size(); i < l; ++i) {
|
for (int i = index, l = blocks.size(); i < l; ++i) {
|
||||||
blocks.at(i)->setIndexInHistory(i);
|
blocks[i]->setIndexInHistory(i);
|
||||||
}
|
}
|
||||||
blocks.at(index)->items.front()->previousItemChanged();
|
blocks[index]->items.front()->previousItemChanged();
|
||||||
} else if (!blocks.empty() && !blocks.back()->items.empty()) {
|
} else if (!blocks.empty() && !blocks.back()->items.empty()) {
|
||||||
blocks.back()->items.back()->nextItemChanged();
|
blocks.back()->items.back()->nextItemChanged();
|
||||||
}
|
}
|
||||||
|
@ -2222,65 +2224,64 @@ History::~History() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int HistoryBlock::resizeGetHeight(int newWidth, bool resizeAllItems) {
|
int HistoryBlock::resizeGetHeight(int newWidth, bool resizeAllItems) {
|
||||||
int y = 0;
|
auto y = 0;
|
||||||
for_const (HistoryItem *item, items) {
|
for_const (auto item, items) {
|
||||||
item->y = y;
|
item->setY(y);
|
||||||
if (resizeAllItems || item->pendingResize()) {
|
if (resizeAllItems || item->pendingResize()) {
|
||||||
y += item->resizeGetHeight(newWidth);
|
y += item->resizeGetHeight(newWidth);
|
||||||
} else {
|
} else {
|
||||||
y += item->height();
|
y += item->height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
height = y;
|
_height = y;
|
||||||
return height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryBlock::clear(bool leaveItems) {
|
void HistoryBlock::clear(bool leaveItems) {
|
||||||
Items lst;
|
auto itemsList = base::take(items);
|
||||||
std::swap(lst, items);
|
|
||||||
|
|
||||||
if (leaveItems) {
|
if (leaveItems) {
|
||||||
for_const (HistoryItem *item, lst) {
|
for_const (auto item, itemsList) {
|
||||||
item->detachFast();
|
item->detachFast();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for_const (HistoryItem *item, lst) {
|
for_const (auto item, itemsList) {
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryBlock::removeItem(HistoryItem *item) {
|
void HistoryBlock::removeItem(HistoryItem *item) {
|
||||||
t_assert(item->block() == this);
|
Expects(item->block() == this);
|
||||||
|
|
||||||
int blockIndex = indexInHistory();
|
auto blockIndex = indexInHistory();
|
||||||
int itemIndex = item->indexInBlock();
|
auto itemIndex = item->indexInBlock();
|
||||||
if (history->showFrom == item) {
|
if (_history->showFrom == item) {
|
||||||
history->getNextShowFrom(this, itemIndex);
|
_history->getNextShowFrom(this, itemIndex);
|
||||||
}
|
}
|
||||||
if (history->lastSentMsg == item) {
|
if (_history->lastSentMsg == item) {
|
||||||
history->lastSentMsg = nullptr;
|
_history->lastSentMsg = nullptr;
|
||||||
}
|
}
|
||||||
if (history->unreadBar == item) {
|
if (_history->unreadBar == item) {
|
||||||
history->unreadBar = nullptr;
|
_history->unreadBar = nullptr;
|
||||||
}
|
}
|
||||||
if (history->scrollTopItem == item) {
|
if (_history->scrollTopItem == item) {
|
||||||
history->getNextScrollTopItem(this, itemIndex);
|
_history->getNextScrollTopItem(this, itemIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
item->detachFast();
|
item->detachFast();
|
||||||
items.remove(itemIndex);
|
items.remove(itemIndex);
|
||||||
for (int i = itemIndex, l = items.size(); i < l; ++i) {
|
for (auto i = itemIndex, l = items.size(); i < l; ++i) {
|
||||||
items.at(i)->setIndexInBlock(i);
|
items[i]->setIndexInBlock(i);
|
||||||
}
|
}
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
history->removeBlock(this);
|
_history->removeBlock(this);
|
||||||
} else if (itemIndex < items.size()) {
|
} else if (itemIndex < items.size()) {
|
||||||
items.at(itemIndex)->previousItemChanged();
|
items[itemIndex]->previousItemChanged();
|
||||||
} else if (blockIndex + 1 < history->blocks.size()) {
|
} else if (blockIndex + 1 < _history->blocks.size()) {
|
||||||
history->blocks.at(blockIndex + 1)->items.front()->previousItemChanged();
|
_history->blocks[blockIndex + 1]->items.front()->previousItemChanged();
|
||||||
} else if (!history->blocks.empty() && !history->blocks.back()->items.empty()) {
|
} else if (!_history->blocks.empty() && !_history->blocks.back()->items.empty()) {
|
||||||
history->blocks.back()->items.back()->nextItemChanged();
|
_history->blocks.back()->items.back()->nextItemChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
|
|
|
@ -622,14 +622,13 @@ private:
|
||||||
|
|
||||||
class HistoryBlock {
|
class HistoryBlock {
|
||||||
public:
|
public:
|
||||||
HistoryBlock(History *hist) : history(hist), _indexInHistory(-1) {
|
HistoryBlock(gsl::not_null<History*> history) : _history(history) {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryBlock(const HistoryBlock &) = delete;
|
HistoryBlock(const HistoryBlock &) = delete;
|
||||||
HistoryBlock &operator=(const HistoryBlock &) = delete;
|
HistoryBlock &operator=(const HistoryBlock &) = delete;
|
||||||
|
|
||||||
typedef QVector<HistoryItem*> Items;
|
QVector<HistoryItem*> items;
|
||||||
Items items;
|
|
||||||
|
|
||||||
void clear(bool leaveItems = false);
|
void clear(bool leaveItems = false);
|
||||||
~HistoryBlock() {
|
~HistoryBlock() {
|
||||||
|
@ -638,31 +637,45 @@ public:
|
||||||
void removeItem(HistoryItem *item);
|
void removeItem(HistoryItem *item);
|
||||||
|
|
||||||
int resizeGetHeight(int newWidth, bool resizeAllItems);
|
int resizeGetHeight(int newWidth, bool resizeAllItems);
|
||||||
int y = 0;
|
int y() const {
|
||||||
int height = 0;
|
return _y;
|
||||||
History *history;
|
}
|
||||||
|
void setY(int y) {
|
||||||
|
_y = y;
|
||||||
|
}
|
||||||
|
int height() const {
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
gsl::not_null<History*> history() const {
|
||||||
|
return _history;
|
||||||
|
}
|
||||||
|
|
||||||
HistoryBlock *previousBlock() const {
|
HistoryBlock *previousBlock() const {
|
||||||
t_assert(_indexInHistory >= 0);
|
Expects(_indexInHistory >= 0);
|
||||||
|
|
||||||
return (_indexInHistory > 0) ? history->blocks.at(_indexInHistory - 1) : nullptr;
|
return (_indexInHistory > 0) ? _history->blocks.at(_indexInHistory - 1) : nullptr;
|
||||||
}
|
}
|
||||||
HistoryBlock *nextBlock() const {
|
HistoryBlock *nextBlock() const {
|
||||||
t_assert(_indexInHistory >= 0);
|
Expects(_indexInHistory >= 0);
|
||||||
|
|
||||||
return (_indexInHistory + 1 < history->blocks.size()) ? history->blocks.at(_indexInHistory + 1) : nullptr;
|
return (_indexInHistory + 1 < _history->blocks.size()) ? _history->blocks.at(_indexInHistory + 1) : nullptr;
|
||||||
}
|
}
|
||||||
void setIndexInHistory(int index) {
|
void setIndexInHistory(int index) {
|
||||||
_indexInHistory = index;
|
_indexInHistory = index;
|
||||||
}
|
}
|
||||||
int indexInHistory() const {
|
int indexInHistory() const {
|
||||||
t_assert(_indexInHistory >= 0);
|
Expects(_indexInHistory >= 0);
|
||||||
t_assert(history->blocks.at(_indexInHistory) == this);
|
Expects(_indexInHistory < _history->blocks.size());
|
||||||
|
Expects(_history->blocks[_indexInHistory] == this);
|
||||||
|
|
||||||
return _indexInHistory;
|
return _indexInHistory;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int _indexInHistory;
|
const gsl::not_null<History*> _history;
|
||||||
|
|
||||||
|
int _y = 0;
|
||||||
|
int _height = 0;
|
||||||
|
int _indexInHistory = -1;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -152,7 +152,7 @@ int binarySearchBlocksOrItems(const T &list, int edge) {
|
||||||
auto start = 0, end = static_cast<int>(list.size());
|
auto start = 0, end = static_cast<int>(list.size());
|
||||||
while (end - start > 1) {
|
while (end - start > 1) {
|
||||||
auto middle = (start + end) / 2;
|
auto middle = (start + end) / 2;
|
||||||
auto top = list[middle]->y;
|
auto top = list[middle]->y();
|
||||||
auto chooseLeft = (TopToBottom ? (top <= edge) : (top < edge));
|
auto chooseLeft = (TopToBottom ? (top <= edge) : (top < edge));
|
||||||
if (chooseLeft) {
|
if (chooseLeft) {
|
||||||
start = middle;
|
start = middle;
|
||||||
|
@ -182,14 +182,14 @@ void HistoryInner::enumerateItemsInHistory(History *history, int historytop, Met
|
||||||
|
|
||||||
// binary search for itemIndex of the first item that is not completely below the visible area
|
// binary search for itemIndex of the first item that is not completely below the visible area
|
||||||
auto block = history->blocks.at(blockIndex);
|
auto block = history->blocks.at(blockIndex);
|
||||||
auto blocktop = historytop + block->y;
|
auto blocktop = historytop + block->y();
|
||||||
auto blockbottom = blocktop + block->height;
|
auto blockbottom = blocktop + block->height();
|
||||||
auto itemIndex = binarySearchBlocksOrItems<TopToBottom>(block->items, searchEdge - blocktop);
|
auto itemIndex = binarySearchBlocksOrItems<TopToBottom>(block->items, searchEdge - blocktop);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
while (true) {
|
while (true) {
|
||||||
auto item = block->items.at(itemIndex);
|
auto item = block->items.at(itemIndex);
|
||||||
auto itemtop = blocktop + item->y;
|
auto itemtop = blocktop + item->y();
|
||||||
auto itembottom = itemtop + item->height();
|
auto itembottom = itemtop + item->height();
|
||||||
|
|
||||||
// binary search should've skipped all the items that are above / below the visible area
|
// binary search should've skipped all the items that are above / below the visible area
|
||||||
|
@ -205,7 +205,7 @@ void HistoryInner::enumerateItemsInHistory(History *history, int historytop, Met
|
||||||
debugValue("blockIndex", blockIndex);
|
debugValue("blockIndex", blockIndex);
|
||||||
debugValue("history->blocks.size()", history->blocks.size());
|
debugValue("history->blocks.size()", history->blocks.size());
|
||||||
debugValue("blocktop", blocktop);
|
debugValue("blocktop", blocktop);
|
||||||
debugValue("block->height", block->height);
|
debugValue("block->height", block->height());
|
||||||
debugValue("itemIndex", itemIndex);
|
debugValue("itemIndex", itemIndex);
|
||||||
debugValue("block->items.size()", block->items.size());
|
debugValue("block->items.size()", block->items.size());
|
||||||
debugValue("itemtop", itemtop);
|
debugValue("itemtop", itemtop);
|
||||||
|
@ -214,10 +214,10 @@ void HistoryInner::enumerateItemsInHistory(History *history, int historytop, Met
|
||||||
debugValue("_visibleAreaTop", _visibleAreaTop);
|
debugValue("_visibleAreaTop", _visibleAreaTop);
|
||||||
debugValue("_visibleAreaBottom", _visibleAreaBottom);
|
debugValue("_visibleAreaBottom", _visibleAreaBottom);
|
||||||
for (int i = 0; i != qMin(history->blocks.size(), 5); ++i) {
|
for (int i = 0; i != qMin(history->blocks.size(), 5); ++i) {
|
||||||
debugValue("y[" + QString::number(i) + "]", history->blocks[i]->y);
|
debugValue("y[" + QString::number(i) + "]", history->blocks[i]->y());
|
||||||
debugValue("h[" + QString::number(i) + "]", history->blocks[i]->height);
|
debugValue("h[" + QString::number(i) + "]", history->blocks[i]->height());
|
||||||
for (int j = 0; j != qMin(history->blocks[i]->items.size(), 5); ++j) {
|
for (int j = 0; j != qMin(history->blocks[i]->items.size(), 5); ++j) {
|
||||||
debugValue("y[" + QString::number(i) + "][" + QString::number(j) + "]", history->blocks[i]->items[j]->y);
|
debugValue("y[" + QString::number(i) + "][" + QString::number(j) + "]", history->blocks[i]->items[j]->y());
|
||||||
debugValue("h[" + QString::number(i) + "][" + QString::number(j) + "]", history->blocks[i]->items[j]->height());
|
debugValue("h[" + QString::number(i) + "][" + QString::number(j) + "]", history->blocks[i]->items[j]->height());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,8 +225,8 @@ void HistoryInner::enumerateItemsInHistory(History *history, int historytop, Met
|
||||||
auto y = 0;
|
auto y = 0;
|
||||||
for (int i = 0; i != history->blocks.size(); ++i) {
|
for (int i = 0; i != history->blocks.size(); ++i) {
|
||||||
auto innery = 0;
|
auto innery = 0;
|
||||||
if (history->blocks[i]->y != y) {
|
if (history->blocks[i]->y() != y) {
|
||||||
debugInfo.append("bad_block_y" + QString::number(i) + ":" + QString::number(history->blocks[i]->y) + "!=" + QString::number(y));
|
debugInfo.append("bad_block_y" + QString::number(i) + ":" + QString::number(history->blocks[i]->y()) + "!=" + QString::number(y));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int j = 0; j != history->blocks[i]->items.size(); ++j) {
|
for (int j = 0; j != history->blocks[i]->items.size(); ++j) {
|
||||||
|
@ -235,14 +235,14 @@ void HistoryInner::enumerateItemsInHistory(History *history, int historytop, Met
|
||||||
} else if (history->blocks[i]->items[j]->pendingResize()) {
|
} else if (history->blocks[i]->items[j]->pendingResize()) {
|
||||||
debugInfo.append("pending_resize" + QString::number(i) + "," + QString::number(j));
|
debugInfo.append("pending_resize" + QString::number(i) + "," + QString::number(j));
|
||||||
}
|
}
|
||||||
if (history->blocks[i]->items[j]->y != innery) {
|
if (history->blocks[i]->items[j]->y() != innery) {
|
||||||
debugInfo.append("bad_item_y" + QString::number(i) + "," + QString::number(j) + ":" + QString::number(history->blocks[i]->items[j]->y) + "!=" + QString::number(innery));
|
debugInfo.append("bad_item_y" + QString::number(i) + "," + QString::number(j) + ":" + QString::number(history->blocks[i]->items[j]->y()) + "!=" + QString::number(innery));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
innery += history->blocks[i]->items[j]->height();
|
innery += history->blocks[i]->items[j]->height();
|
||||||
}
|
}
|
||||||
if (history->blocks[i]->height != innery) {
|
if (history->blocks[i]->height() != innery) {
|
||||||
debugInfo.append("bad_block_height" + QString::number(i) + ":" + QString::number(history->blocks[i]->height) + "!=" + QString::number(innery));
|
debugInfo.append("bad_block_height" + QString::number(i) + ":" + QString::number(history->blocks[i]->height()) + "!=" + QString::number(innery));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
y += innery;
|
y += innery;
|
||||||
|
@ -305,9 +305,9 @@ void HistoryInner::enumerateItemsInHistory(History *history, int historytop, Met
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
block = history->blocks.at(blockIndex);
|
block = history->blocks[blockIndex];
|
||||||
blocktop = historytop + block->y;
|
blocktop = historytop + block->y();
|
||||||
blockbottom = blocktop + block->height;
|
blockbottom = blocktop + block->height();
|
||||||
if (TopToBottom) {
|
if (TopToBottom) {
|
||||||
itemIndex = 0;
|
itemIndex = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -472,14 +472,16 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
seltoy += _dragSelTo->height();
|
seltoy += _dragSelTo->height();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 mtop = migratedTop(), htop = historyTop(), hdrawtop = historyDrawTop();
|
auto mtop = migratedTop();
|
||||||
|
auto htop = historyTop();
|
||||||
|
auto hdrawtop = historyDrawTop();
|
||||||
if (mtop >= 0) {
|
if (mtop >= 0) {
|
||||||
int32 iBlock = (_curHistory == _migrated ? _curBlock : (_migrated->blocks.size() - 1));
|
auto iBlock = (_curHistory == _migrated ? _curBlock : (_migrated->blocks.size() - 1));
|
||||||
HistoryBlock *block = _migrated->blocks[iBlock];
|
auto block = _migrated->blocks[iBlock];
|
||||||
int32 iItem = (_curHistory == _migrated ? _curItem : (block->items.size() - 1));
|
auto iItem = (_curHistory == _migrated ? _curItem : (block->items.size() - 1));
|
||||||
HistoryItem *item = block->items[iItem];
|
auto item = block->items[iItem];
|
||||||
|
|
||||||
int32 y = mtop + block->y + item->y;
|
auto y = mtop + block->y() + item->y();
|
||||||
p.save();
|
p.save();
|
||||||
p.translate(0, y);
|
p.translate(0, y);
|
||||||
if (r.y() < y + item->height()) while (y < drawToY) {
|
if (r.y() < y + item->height()) while (y < drawToY) {
|
||||||
|
@ -518,17 +520,17 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
p.restore();
|
p.restore();
|
||||||
}
|
}
|
||||||
if (htop >= 0) {
|
if (htop >= 0) {
|
||||||
int32 iBlock = (_curHistory == _history ? _curBlock : 0);
|
auto iBlock = (_curHistory == _history ? _curBlock : 0);
|
||||||
HistoryBlock *block = _history->blocks[iBlock];
|
auto block = _history->blocks[iBlock];
|
||||||
int32 iItem = (_curHistory == _history ? _curItem : 0);
|
auto iItem = (_curHistory == _history ? _curItem : 0);
|
||||||
HistoryItem *item = block->items[iItem];
|
auto item = block->items[iItem];
|
||||||
|
|
||||||
QRect historyRect = r.intersected(QRect(0, hdrawtop, width(), r.top() + r.height()));
|
auto historyRect = r.intersected(QRect(0, hdrawtop, width(), r.top() + r.height()));
|
||||||
int32 y = htop + block->y + item->y;
|
auto y = htop + block->y() + item->y();
|
||||||
p.save();
|
p.save();
|
||||||
p.translate(0, y);
|
p.translate(0, y);
|
||||||
while (y < drawToY) {
|
while (y < drawToY) {
|
||||||
int32 h = item->height();
|
auto h = item->height();
|
||||||
if (historyRect.y() < y + h && hdrawtop < y + h) {
|
if (historyRect.y() < y + h && hdrawtop < y + h) {
|
||||||
TextSelection sel;
|
TextSelection sel;
|
||||||
if (y >= selfromy && y < seltoy) {
|
if (y >= selfromy && y < seltoy) {
|
||||||
|
@ -1902,23 +1904,23 @@ void HistoryInner::adjustCurrent(int32 y, History *history) const {
|
||||||
_curBlock = history->blocks.size() - 1;
|
_curBlock = history->blocks.size() - 1;
|
||||||
_curItem = 0;
|
_curItem = 0;
|
||||||
}
|
}
|
||||||
while (history->blocks.at(_curBlock)->y > y && _curBlock > 0) {
|
while (history->blocks[_curBlock]->y() > y && _curBlock > 0) {
|
||||||
--_curBlock;
|
--_curBlock;
|
||||||
_curItem = 0;
|
_curItem = 0;
|
||||||
}
|
}
|
||||||
while (history->blocks.at(_curBlock)->y + history->blocks.at(_curBlock)->height <= y && _curBlock + 1 < history->blocks.size()) {
|
while (history->blocks[_curBlock]->y() + history->blocks[_curBlock]->height() <= y && _curBlock + 1 < history->blocks.size()) {
|
||||||
++_curBlock;
|
++_curBlock;
|
||||||
_curItem = 0;
|
_curItem = 0;
|
||||||
}
|
}
|
||||||
HistoryBlock *block = history->blocks.at(_curBlock);
|
auto block = history->blocks[_curBlock];
|
||||||
if (_curItem >= block->items.size()) {
|
if (_curItem >= block->items.size()) {
|
||||||
_curItem = block->items.size() - 1;
|
_curItem = block->items.size() - 1;
|
||||||
}
|
}
|
||||||
int by = block->y;
|
auto by = block->y();
|
||||||
while (block->items.at(_curItem)->y + by > y && _curItem > 0) {
|
while (block->items[_curItem]->y() + by > y && _curItem > 0) {
|
||||||
--_curItem;
|
--_curItem;
|
||||||
}
|
}
|
||||||
while (block->items.at(_curItem)->y + block->items.at(_curItem)->height() + by <= y && _curItem + 1 < block->items.size()) {
|
while (block->items[_curItem]->y() + block->items[_curItem]->height() + by <= y && _curItem + 1 < block->items.size()) {
|
||||||
++_curItem;
|
++_curItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2300,14 +2302,15 @@ int HistoryInner::historyHeight() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
int HistoryInner::historyScrollTop() const {
|
int HistoryInner::historyScrollTop() const {
|
||||||
int htop = historyTop(), mtop = migratedTop();
|
auto htop = historyTop();
|
||||||
|
auto mtop = migratedTop();
|
||||||
if (htop >= 0 && _history->scrollTopItem) {
|
if (htop >= 0 && _history->scrollTopItem) {
|
||||||
t_assert(!_history->scrollTopItem->detached());
|
t_assert(!_history->scrollTopItem->detached());
|
||||||
return htop + _history->scrollTopItem->block()->y + _history->scrollTopItem->y + _history->scrollTopOffset;
|
return htop + _history->scrollTopItem->block()->y() + _history->scrollTopItem->y() + _history->scrollTopOffset;
|
||||||
}
|
}
|
||||||
if (mtop >= 0 && _migrated->scrollTopItem) {
|
if (mtop >= 0 && _migrated->scrollTopItem) {
|
||||||
t_assert(!_migrated->scrollTopItem->detached());
|
t_assert(!_migrated->scrollTopItem->detached());
|
||||||
return mtop + _migrated->scrollTopItem->block()->y + _migrated->scrollTopItem->y + _migrated->scrollTopOffset;
|
return mtop + _migrated->scrollTopItem->block()->y() + _migrated->scrollTopItem->y() + _migrated->scrollTopOffset;
|
||||||
}
|
}
|
||||||
return ScrollMax;
|
return ScrollMax;
|
||||||
}
|
}
|
||||||
|
@ -2331,7 +2334,7 @@ int HistoryInner::itemTop(const HistoryItem *item) const { // -1 if should not b
|
||||||
if (item->detached()) return -1;
|
if (item->detached()) return -1;
|
||||||
|
|
||||||
int top = (item->history() == _history) ? historyTop() : (item->history() == _migrated ? migratedTop() : -2);
|
int top = (item->history() == _history) ? historyTop() : (item->history() == _migrated ? migratedTop() : -2);
|
||||||
return (top < 0) ? top : (top + item->y + item->block()->y);
|
return (top < 0) ? top : (top + item->y() + item->block()->y());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::notifyIsBotChanged() {
|
void HistoryInner::notifyIsBotChanged() {
|
||||||
|
|
|
@ -578,7 +578,6 @@ TextSelection shiftSelection(TextSelection selection, const Text &byText) {
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
HistoryItem::HistoryItem(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime msgDate, int32 from) : HistoryElement()
|
HistoryItem::HistoryItem(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime msgDate, int32 from) : HistoryElement()
|
||||||
, y(0)
|
|
||||||
, id(msgId)
|
, id(msgId)
|
||||||
, date(msgDate)
|
, date(msgDate)
|
||||||
, _from(from ? App::user(from) : history->peer)
|
, _from(from ? App::user(from) : history->peer)
|
||||||
|
|
|
@ -156,8 +156,8 @@ struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply> {
|
||||||
}
|
}
|
||||||
~HistoryMessageReply() {
|
~HistoryMessageReply() {
|
||||||
// clearData() should be called by holder
|
// clearData() should be called by holder
|
||||||
t_assert(replyToMsg == nullptr);
|
Expects(replyToMsg == nullptr);
|
||||||
t_assert(_replyToVia == nullptr);
|
Expects(_replyToVia == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updateData(HistoryMessage *holder, bool force = false);
|
bool updateData(HistoryMessage *holder, bool force = false);
|
||||||
|
@ -438,7 +438,7 @@ public:
|
||||||
return get();
|
return get();
|
||||||
}
|
}
|
||||||
HistoryMedia &operator*() const {
|
HistoryMedia &operator*() const {
|
||||||
t_assert(!isNull());
|
Expects(!isNull());
|
||||||
return *get();
|
return *get();
|
||||||
}
|
}
|
||||||
explicit operator bool() const {
|
explicit operator bool() const {
|
||||||
|
@ -522,10 +522,10 @@ public:
|
||||||
return !_block;
|
return !_block;
|
||||||
}
|
}
|
||||||
void attachToBlock(HistoryBlock *block, int index) {
|
void attachToBlock(HistoryBlock *block, int index) {
|
||||||
t_assert(_block == nullptr);
|
Expects(_block == nullptr);
|
||||||
t_assert(_indexInBlock < 0);
|
Expects(_indexInBlock < 0);
|
||||||
t_assert(block != nullptr);
|
Expects(block != nullptr);
|
||||||
t_assert(index >= 0);
|
Expects(index >= 0);
|
||||||
|
|
||||||
_block = block;
|
_block = block;
|
||||||
_indexInBlock = index;
|
_indexInBlock = index;
|
||||||
|
@ -534,8 +534,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void setIndexInBlock(int index) {
|
void setIndexInBlock(int index) {
|
||||||
t_assert(_block != nullptr);
|
Expects(_block != nullptr);
|
||||||
t_assert(index >= 0);
|
Expects(index >= 0);
|
||||||
|
|
||||||
_indexInBlock = index;
|
_indexInBlock = index;
|
||||||
}
|
}
|
||||||
|
@ -575,7 +575,7 @@ public:
|
||||||
return (_flags & MTPDmessage::Flag::f_reply_markup);
|
return (_flags & MTPDmessage::Flag::f_reply_markup);
|
||||||
}
|
}
|
||||||
MTPDreplyKeyboardMarkup::Flags replyKeyboardFlags() const {
|
MTPDreplyKeyboardMarkup::Flags replyKeyboardFlags() const {
|
||||||
t_assert(definesReplyKeyboard());
|
Expects(definesReplyKeyboard());
|
||||||
if (auto markup = Get<HistoryMessageReplyMarkup>()) {
|
if (auto markup = Get<HistoryMessageReplyMarkup>()) {
|
||||||
return markup->flags;
|
return markup->flags;
|
||||||
}
|
}
|
||||||
|
@ -701,7 +701,12 @@ public:
|
||||||
}
|
}
|
||||||
QString directLink() const;
|
QString directLink() const;
|
||||||
|
|
||||||
int32 y;
|
int y() const {
|
||||||
|
return _y;
|
||||||
|
}
|
||||||
|
void setY(int y) {
|
||||||
|
_y = y;
|
||||||
|
}
|
||||||
MsgId id;
|
MsgId id;
|
||||||
QDateTime date;
|
QDateTime date;
|
||||||
|
|
||||||
|
@ -951,6 +956,9 @@ protected:
|
||||||
|
|
||||||
HistoryMediaPtr _media;
|
HistoryMediaPtr _media;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _y = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// make all the constructors in HistoryItem children protected
|
// make all the constructors in HistoryItem children protected
|
||||||
|
|
|
@ -75,6 +75,9 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kStickersUpdateTimeout = 3600000; // update not more than once in an hour
|
constexpr auto kStickersUpdateTimeout = 3600000; // update not more than once in an hour
|
||||||
constexpr auto kSaveTabbedSelectorSectionTimeout = 1000;
|
constexpr auto kSaveTabbedSelectorSectionTimeout = 1000;
|
||||||
|
constexpr auto kMessagesPerPageFirst = 30;
|
||||||
|
constexpr auto kMessagesPerPage = 50;
|
||||||
|
constexpr auto kPreloadHeightsCount = 3; // when 3 screens to scroll left make a preload request
|
||||||
|
|
||||||
ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
|
ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
|
||||||
return [](ChannelData *channel, MsgId msgId) {
|
return [](ChannelData *channel, MsgId msgId) {
|
||||||
|
@ -2255,7 +2258,7 @@ bool HistoryWidget::messagesFailed(const RPCError &error, mtpRequestId requestId
|
||||||
if (MTP::isDefaultHandledError(error)) return false;
|
if (MTP::isDefaultHandledError(error)) return false;
|
||||||
|
|
||||||
if (error.type() == qstr("CHANNEL_PRIVATE") || error.type() == qstr("CHANNEL_PUBLIC_GROUP_NA") || error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
|
if (error.type() == qstr("CHANNEL_PRIVATE") || error.type() == qstr("CHANNEL_PUBLIC_GROUP_NA") || error.type() == qstr("USER_BANNED_IN_CHANNEL")) {
|
||||||
PeerData *was = _peer;
|
auto was = _peer;
|
||||||
App::main()->showBackFromStack();
|
App::main()->showBackFromStack();
|
||||||
Ui::show(Box<InformBox>(lang((was && was->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
|
Ui::show(Box<InformBox>(lang((was && was->isMegagroup()) ? lng_group_not_accessible : lng_channel_not_accessible)));
|
||||||
return true;
|
return true;
|
||||||
|
@ -2437,8 +2440,10 @@ bool HistoryWidget::historyHasNotFreezedUnreadBar(History *history) const {
|
||||||
void HistoryWidget::firstLoadMessages() {
|
void HistoryWidget::firstLoadMessages() {
|
||||||
if (!_history || _firstLoadRequest) return;
|
if (!_history || _firstLoadRequest) return;
|
||||||
|
|
||||||
PeerData *from = _peer;
|
auto from = _peer;
|
||||||
int32 offset_id = 0, offset = 0, loadCount = MessagesPerPage;
|
auto offset_id = 0;
|
||||||
|
auto offset = 0;
|
||||||
|
auto loadCount = kMessagesPerPage;
|
||||||
if (_showAtMsgId == ShowAtUnreadMsgId) {
|
if (_showAtMsgId == ShowAtUnreadMsgId) {
|
||||||
if (_migrated && _migrated->unreadCount()) {
|
if (_migrated && _migrated->unreadCount()) {
|
||||||
_history->getReadyFor(_showAtMsgId);
|
_history->getReadyFor(_showAtMsgId);
|
||||||
|
@ -2454,7 +2459,7 @@ void HistoryWidget::firstLoadMessages() {
|
||||||
}
|
}
|
||||||
} else if (_showAtMsgId == ShowAtTheEndMsgId) {
|
} else if (_showAtMsgId == ShowAtTheEndMsgId) {
|
||||||
_history->getReadyFor(_showAtMsgId);
|
_history->getReadyFor(_showAtMsgId);
|
||||||
loadCount = MessagesFirstLoad;
|
loadCount = kMessagesPerPageFirst;
|
||||||
} else if (_showAtMsgId > 0) {
|
} else if (_showAtMsgId > 0) {
|
||||||
_history->getReadyFor(_showAtMsgId);
|
_history->getReadyFor(_showAtMsgId);
|
||||||
offset = -loadCount / 2;
|
offset = -loadCount / 2;
|
||||||
|
@ -2486,8 +2491,9 @@ void HistoryWidget::loadMessages() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MsgId offset_id = from->minMsgId();
|
auto offset_id = from->minMsgId();
|
||||||
int32 offset = 0, loadCount = offset_id ? MessagesPerPage : MessagesFirstLoad;
|
auto offset = 0;
|
||||||
|
auto loadCount = offset_id ? kMessagesPerPage : kMessagesPerPageFirst;
|
||||||
|
|
||||||
_preloadRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
_preloadRequest = MTP::send(MTPmessages_GetHistory(from->peer->input, MTP_int(offset_id), MTP_int(0), MTP_int(offset), MTP_int(loadCount), MTP_int(0), MTP_int(0)), rpcDone(&HistoryWidget::messagesReceived, from->peer), rpcFail(&HistoryWidget::messagesFailed));
|
||||||
}
|
}
|
||||||
|
@ -2505,9 +2511,9 @@ void HistoryWidget::loadMessagesDown() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 loadCount = MessagesPerPage, offset = -loadCount;
|
auto loadCount = kMessagesPerPage;
|
||||||
|
auto offset = -loadCount;
|
||||||
MsgId offset_id = from->maxMsgId();
|
auto offset_id = from->maxMsgId();
|
||||||
if (!offset_id) {
|
if (!offset_id) {
|
||||||
if (loadMigrated || !_migrated) return;
|
if (loadMigrated || !_migrated) return;
|
||||||
++offset_id;
|
++offset_id;
|
||||||
|
@ -2523,8 +2529,10 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
|
||||||
clearDelayedShowAt();
|
clearDelayedShowAt();
|
||||||
_delayedShowAtMsgId = showAtMsgId;
|
_delayedShowAtMsgId = showAtMsgId;
|
||||||
|
|
||||||
PeerData *from = _peer;
|
auto from = _peer;
|
||||||
int32 offset_id = 0, offset = 0, loadCount = MessagesPerPage;
|
auto offset_id = 0;
|
||||||
|
auto offset = 0;
|
||||||
|
auto loadCount = kMessagesPerPage;
|
||||||
if (_delayedShowAtMsgId == ShowAtUnreadMsgId) {
|
if (_delayedShowAtMsgId == ShowAtUnreadMsgId) {
|
||||||
if (_migrated && _migrated->unreadCount()) {
|
if (_migrated && _migrated->unreadCount()) {
|
||||||
from = _migrated->peer;
|
from = _migrated->peer;
|
||||||
|
@ -2534,10 +2542,10 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
|
||||||
offset = -loadCount / 2;
|
offset = -loadCount / 2;
|
||||||
offset_id = _history->inboxReadBefore;
|
offset_id = _history->inboxReadBefore;
|
||||||
} else {
|
} else {
|
||||||
loadCount = MessagesFirstLoad;
|
loadCount = kMessagesPerPageFirst;
|
||||||
}
|
}
|
||||||
} else if (_delayedShowAtMsgId == ShowAtTheEndMsgId) {
|
} else if (_delayedShowAtMsgId == ShowAtTheEndMsgId) {
|
||||||
loadCount = MessagesFirstLoad;
|
loadCount = kMessagesPerPageFirst;
|
||||||
} else if (_delayedShowAtMsgId > 0) {
|
} else if (_delayedShowAtMsgId > 0) {
|
||||||
offset = -loadCount / 2;
|
offset = -loadCount / 2;
|
||||||
offset_id = _delayedShowAtMsgId;
|
offset_id = _delayedShowAtMsgId;
|
||||||
|
@ -2578,11 +2586,11 @@ void HistoryWidget::preloadHistoryIfNeeded() {
|
||||||
updateHistoryDownVisibility();
|
updateHistoryDownVisibility();
|
||||||
|
|
||||||
int st = _scroll->scrollTop(), stm = _scroll->scrollTopMax(), sh = _scroll->height();
|
int st = _scroll->scrollTop(), stm = _scroll->scrollTopMax(), sh = _scroll->height();
|
||||||
if (st + PreloadHeightsCount * sh > stm) {
|
if (st + kPreloadHeightsCount * sh >= stm) {
|
||||||
loadMessagesDown();
|
loadMessagesDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st < PreloadHeightsCount * sh) {
|
if (st <= kPreloadHeightsCount * sh) {
|
||||||
loadMessages();
|
loadMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue