mirror of https://github.com/procxx/kepka.git
removed history resize when adding items, simplified adding items, maintaining item and block indices, history scroll management broken when history changes
This commit is contained in:
parent
2ef8c44445
commit
2cbda4e1e5
|
@ -599,25 +599,24 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
||||||
return _joinedMessage;
|
return _joinedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
UserData *inviter = (peer->asChannel()->inviter > 0) ? App::userLoaded(peer->asChannel()->inviter) : 0;
|
UserData *inviter = (peer->asChannel()->inviter > 0) ? App::userLoaded(peer->asChannel()->inviter) : nullptr;
|
||||||
if (!inviter) return 0;
|
if (!inviter) return nullptr;
|
||||||
|
|
||||||
if (peerToUser(inviter->id) == MTP::authedId()) unread = false;
|
|
||||||
MTPDmessage::Flags flags = 0;
|
MTPDmessage::Flags flags = 0;
|
||||||
if (unread) {
|
if (peerToUser(inviter->id) == MTP::authedId()) {
|
||||||
|
unread = false;
|
||||||
|
} else if (unread) {
|
||||||
flags |= MTPDmessage::Flag::f_unread;
|
flags |= MTPDmessage::Flag::f_unread;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDateTime inviteDate = peer->asChannel()->inviteDate;
|
QDateTime inviteDate = peer->asChannel()->inviteDate;
|
||||||
if (unread) _maxReadMessageDate = inviteDate;
|
if (unread) _maxReadMessageDate = inviteDate;
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
HistoryBlock *to = new HistoryBlock(this);
|
|
||||||
bool newBlock = true;
|
|
||||||
_joinedMessage = HistoryJoined::create(this, inviteDate, inviter, flags);
|
_joinedMessage = HistoryJoined::create(this, inviteDate, inviter, flags);
|
||||||
if (!addNewItem(to, newBlock, _joinedMessage, unread)) {
|
addNewItem(_joinedMessage, unread);
|
||||||
_joinedMessage = 0;
|
|
||||||
}
|
|
||||||
return _joinedMessage;
|
return _joinedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32 blockIndex = blocks.size(); blockIndex > 1;) {
|
for (int32 blockIndex = blocks.size(); blockIndex > 1;) {
|
||||||
HistoryBlock *block = blocks.at(--blockIndex);
|
HistoryBlock *block = blocks.at(--blockIndex);
|
||||||
for (int32 itemIndex = block->items.size(); itemIndex > 0;) {
|
for (int32 itemIndex = block->items.size(); itemIndex > 0;) {
|
||||||
|
@ -627,13 +626,13 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
||||||
if (item->date <= inviteDate) {
|
if (item->date <= inviteDate) {
|
||||||
if (peer->isMegagroup() && peer->migrateFrom() && item->isGroupMigrate()) {
|
if (peer->isMegagroup() && peer->migrateFrom() && item->isGroupMigrate()) {
|
||||||
peer->asChannel()->mgInfo->joinedMessageFound = true;
|
peer->asChannel()->mgInfo->joinedMessageFound = true;
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
++itemIndex;
|
++itemIndex;
|
||||||
_joinedMessage = HistoryJoined::create(this, inviteDate, inviter, flags);
|
_joinedMessage = HistoryJoined::create(this, inviteDate, inviter, flags);
|
||||||
if (!addNewInTheMiddle(_joinedMessage, blockIndex, itemIndex)) {
|
if (!addNewInTheMiddle(_joinedMessage, blockIndex, itemIndex)) {
|
||||||
_joinedMessage = 0;
|
_joinedMessage = nullptr;
|
||||||
}
|
}
|
||||||
if (lastMsgDate.isNull() || inviteDate >= lastMsgDate) {
|
if (lastMsgDate.isNull() || inviteDate >= lastMsgDate) {
|
||||||
setLastMessage(_joinedMessage);
|
setLastMessage(_joinedMessage);
|
||||||
|
@ -648,38 +647,19 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// adding new item to new block
|
// adding new item to new block
|
||||||
int32 addToH = 0, skip = 0;
|
|
||||||
HistoryItem *till = blocks.isEmpty() ? 0 : blocks.front()->items.front();
|
|
||||||
|
|
||||||
HistoryBlock *block = new HistoryBlock(this);
|
HistoryBlock *block = new HistoryBlock(this);
|
||||||
|
block->setIndexInHistory(0);
|
||||||
|
blocks.push_front(block);
|
||||||
|
for (int i = 1, l = blocks.size(); i < l; ++i) {
|
||||||
|
blocks.at(i)->setIndexInHistory(i);
|
||||||
|
}
|
||||||
|
|
||||||
_joinedMessage = HistoryJoined::create(this, inviteDate, inviter, flags);
|
_joinedMessage = HistoryJoined::create(this, inviteDate, inviter, flags);
|
||||||
addItemAfterPrevToBlock(_joinedMessage, 0, block);
|
addItemAfterPrevToBlock(_joinedMessage, nullptr, block);
|
||||||
if (!block->items.isEmpty()) {
|
|
||||||
blocks.push_front(block);
|
t_assert(blocks.size() > 1);
|
||||||
if (width) {
|
blocks.at(1)->items.front()->previousItemChanged();
|
||||||
addToH += block->height;
|
|
||||||
++skip;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
delete block;
|
|
||||||
}
|
|
||||||
if (width && addToH) {
|
|
||||||
for (Blocks::iterator i = blocks.begin(), e = blocks.end(); i != e; ++i) {
|
|
||||||
if (skip) {
|
|
||||||
--skip;
|
|
||||||
} else {
|
|
||||||
(*i)->y += addToH;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
height += addToH;
|
|
||||||
}
|
|
||||||
if (!lastMsgDate.isNull() && inviteDate >= lastMsgDate) {
|
|
||||||
setLastMessage(_joinedMessage);
|
|
||||||
if (unread) {
|
|
||||||
newItemAdded(_joinedMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _joinedMessage;
|
return _joinedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,23 +779,7 @@ HistoryItem *ChannelHistory::addNewToBlocks(const MTPMessage &msg, NewMessageTyp
|
||||||
clear(true);
|
clear(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryBlock *to = nullptr;
|
return addNewToLastBlock(msg, type);
|
||||||
bool newBlock = blocks.isEmpty();
|
|
||||||
if (newBlock) {
|
|
||||||
to = new HistoryBlock(this);
|
|
||||||
} else {
|
|
||||||
to = blocks.back();
|
|
||||||
t_assert(!to->items.isEmpty());
|
|
||||||
t_assert(to->items.back() != nullptr);
|
|
||||||
}
|
|
||||||
HistoryItem *item = createItem((type == NewMessageLast) ? nullptr : to, msg, (type == NewMessageUnread));
|
|
||||||
if (type == NewMessageLast && item) {
|
|
||||||
if (!item->detached()) {
|
|
||||||
t_assert(!newBlock);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return addNewItem(to, newBlock, item, (type == NewMessageUnread));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChannelHistory::addNewToOther(HistoryItem *item, NewMessageType type) {
|
void ChannelHistory::addNewToOther(HistoryItem *item, NewMessageType type) {
|
||||||
|
@ -866,16 +830,16 @@ void ChannelHistory::switchMode() {
|
||||||
HistoryItem *prev = 0;
|
HistoryItem *prev = 0;
|
||||||
for (int32 i = 0; i < count;) {
|
for (int32 i = 0; i < count;) {
|
||||||
HistoryBlock *block = new HistoryBlock(this);
|
HistoryBlock *block = new HistoryBlock(this);
|
||||||
|
block->setIndexInHistory(blocks.size());
|
||||||
|
blocks.push_back(block);
|
||||||
|
|
||||||
int32 willAddToBlock = qMin(int32(MessagesPerPage), count - i);
|
int32 willAddToBlock = qMin(int32(MessagesPerPage), count - i);
|
||||||
block->items.reserve(willAddToBlock);
|
block->items.reserve(willAddToBlock);
|
||||||
for (int32 till = i + willAddToBlock; i < till; ++i) {
|
for (int32 till = i + willAddToBlock; i < till; ++i) {
|
||||||
prev = addItemAfterPrevToBlock(_otherList.at(i), prev, block);
|
prev = addItemAfterPrevToBlock(_otherList.at(i), prev, block);
|
||||||
}
|
}
|
||||||
blocks.push_back(block);
|
|
||||||
if (width) {
|
t_assert(!block->items.isEmpty());
|
||||||
block->y = height;
|
|
||||||
height += block->height;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1244,7 +1208,7 @@ HistoryItem *Histories::addNewMessage(const MTPMessage &msg, NewMessageType type
|
||||||
return findOrInsert(peer, 0, 0)->addNewMessage(msg, type);
|
return findOrInsert(peer, 0, 0)->addNewMessage(msg, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction) {
|
HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, bool detachExistingItem) {
|
||||||
MsgId msgId = 0;
|
MsgId msgId = 0;
|
||||||
switch (msg.type()) {
|
switch (msg.type()) {
|
||||||
case mtpc_messageEmpty: msgId = msg.c_messageEmpty().vid.v; break;
|
case mtpc_messageEmpty: msgId = msg.c_messageEmpty().vid.v; break;
|
||||||
|
@ -1255,10 +1219,8 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
|
||||||
|
|
||||||
HistoryItem *result = App::histItemById(channelId(), msgId);
|
HistoryItem *result = App::histItemById(channelId(), msgId);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (block) {
|
if (!result->detached() && detachExistingItem) {
|
||||||
if (!result->detached()) {
|
result->detach();
|
||||||
result->detach();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (msg.type() == mtpc_message) {
|
if (msg.type() == mtpc_message) {
|
||||||
result->updateMedia(msg.c_message().has_media() ? (&msg.c_message().vmedia) : 0);
|
result->updateMedia(msg.c_message().has_media() ? (&msg.c_message().vmedia) : 0);
|
||||||
|
@ -1505,18 +1467,7 @@ HistoryItem *History::createItemPhoto(MsgId id, MTPDmessage::Flags flags, int32
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::addNewService(MsgId msgId, QDateTime date, const QString &text, MTPDmessage::Flags flags, HistoryMedia *media, bool newMsg) {
|
HistoryItem *History::addNewService(MsgId msgId, QDateTime date, const QString &text, MTPDmessage::Flags flags, HistoryMedia *media, bool newMsg) {
|
||||||
HistoryBlock *to = 0;
|
return addNewItem(HistoryServiceMsg::create(this, msgId, date, text, flags, media), newMsg);
|
||||||
bool newBlock = blocks.isEmpty();
|
|
||||||
if (newBlock) {
|
|
||||||
to = new HistoryBlock(this);
|
|
||||||
} else {
|
|
||||||
to = blocks.back();
|
|
||||||
t_assert(!to->items.isEmpty());
|
|
||||||
t_assert(to->items.back() != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
HistoryItem *result = HistoryServiceMsg::create(this, msgId, date, text, flags, media);
|
|
||||||
return addNewItem(to, newBlock, result, newMsg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::addNewMessage(const MTPMessage &msg, NewMessageType type) {
|
HistoryItem *History::addNewMessage(const MTPMessage &msg, NewMessageType type) {
|
||||||
|
@ -1534,66 +1485,32 @@ HistoryItem *History::addNewMessage(const MTPMessage &msg, NewMessageType type)
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryBlock *to = nullptr;
|
return addNewToLastBlock(msg, type);
|
||||||
bool newBlock = blocks.isEmpty();
|
}
|
||||||
if (newBlock) {
|
|
||||||
to = new HistoryBlock(this);
|
HistoryItem *History::addNewToLastBlock(const MTPMessage &msg, NewMessageType type) {
|
||||||
} else {
|
bool applyServiceAction = (type == NewMessageUnread), detachExistingItem = (type != NewMessageLast);
|
||||||
to = blocks.back();
|
HistoryItem *item = createItem(msg, applyServiceAction, detachExistingItem);
|
||||||
t_assert(!to->items.isEmpty());
|
if (!item || !item->detached()) {
|
||||||
t_assert(to->items.back() != nullptr);
|
return item;
|
||||||
}
|
}
|
||||||
HistoryItem *item = createItem((type == NewMessageLast) ? nullptr : to, msg, (type == NewMessageUnread));
|
return addNewItem(item, (type == NewMessageUnread));
|
||||||
if (type == NewMessageLast && item) {
|
|
||||||
if (!item->detached()) {
|
|
||||||
t_assert(!newBlock);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return addNewItem(to, newBlock, item, (type == NewMessageUnread));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::addToHistory(const MTPMessage &msg) {
|
HistoryItem *History::addToHistory(const MTPMessage &msg) {
|
||||||
return createItem(nullptr, msg, false);
|
return createItem(msg, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::addNewForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *item) {
|
HistoryItem *History::addNewForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *item) {
|
||||||
HistoryBlock *to = nullptr;
|
return addNewItem(createItemForwarded(id, flags, date, from, item), true);
|
||||||
bool newBlock = blocks.isEmpty();
|
|
||||||
if (newBlock) {
|
|
||||||
to = new HistoryBlock(this);
|
|
||||||
} else {
|
|
||||||
to = blocks.back();
|
|
||||||
t_assert(!to->items.isEmpty());
|
|
||||||
t_assert(to->items.back() != nullptr);
|
|
||||||
}
|
|
||||||
return addNewItem(to, newBlock, createItemForwarded(id, flags, date, from, item), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::addNewDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) {
|
HistoryItem *History::addNewDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption) {
|
||||||
HistoryBlock *to = 0;
|
return addNewItem(createItemDocument(id, flags, viaBotId, replyTo, date, from, doc, caption), true);
|
||||||
bool newBlock = blocks.isEmpty();
|
|
||||||
if (newBlock) {
|
|
||||||
to = new HistoryBlock(this);
|
|
||||||
} else {
|
|
||||||
to = blocks.back();
|
|
||||||
t_assert(!to->items.isEmpty());
|
|
||||||
t_assert(to->items.back() != nullptr);
|
|
||||||
}
|
|
||||||
return addNewItem(to, newBlock, createItemDocument(id, flags, viaBotId, replyTo, date, from, doc, caption), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::addNewPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
|
HistoryItem *History::addNewPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption) {
|
||||||
HistoryBlock *to = 0;
|
return addNewItem(createItemPhoto(id, flags, viaBotId, replyTo, date, from, photo, caption), true);
|
||||||
bool newBlock = blocks.isEmpty();
|
|
||||||
if (newBlock) {
|
|
||||||
to = new HistoryBlock(this);
|
|
||||||
} else {
|
|
||||||
to = blocks.back();
|
|
||||||
t_assert(!to->items.isEmpty());
|
|
||||||
t_assert(to->items.back() != nullptr);
|
|
||||||
}
|
|
||||||
return addNewItem(to, newBlock, createItemPhoto(id, flags, viaBotId, replyTo, date, from, photo, caption), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool History::addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMethod method) {
|
bool History::addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMethod method) {
|
||||||
|
@ -1639,27 +1556,21 @@ void History::eraseFromOverview(MediaOverviewType type, MsgId msgId) {
|
||||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, type);
|
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg) {
|
HistoryItem *History::addNewItem(HistoryItem *adding, bool newMsg) {
|
||||||
if (!adding) {
|
t_assert(adding != nullptr);
|
||||||
if (newBlock) delete to;
|
t_assert(adding->detached());
|
||||||
return adding;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newBlock) {
|
if (blocks.isEmpty()) {
|
||||||
to->y = height;
|
blocks.push_back(new HistoryBlock(this));
|
||||||
blocks.push_back(to);
|
blocks.back()->setIndexInHistory(blocks.size());
|
||||||
}
|
}
|
||||||
adding->attachToBlock(to, to->items.size());
|
HistoryBlock *block = blocks.back();
|
||||||
to->items.push_back(adding);
|
|
||||||
|
adding->attachToBlock(block, block->items.size());
|
||||||
|
block->items.push_back(adding);
|
||||||
adding->previousItemChanged();
|
adding->previousItemChanged();
|
||||||
setLastMessage(adding);
|
setLastMessage(adding);
|
||||||
|
|
||||||
adding->y = to->height;
|
|
||||||
if (width) {
|
|
||||||
int32 dh = adding->resize(width);
|
|
||||||
to->height += dh;
|
|
||||||
height += dh;
|
|
||||||
}
|
|
||||||
if (newMsg) {
|
if (newMsg) {
|
||||||
newItemAdded(adding);
|
newItemAdded(adding);
|
||||||
}
|
}
|
||||||
|
@ -1775,10 +1686,6 @@ HistoryItem *History::addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *pr
|
||||||
item->attachToBlock(block, block->items.size());
|
item->attachToBlock(block, block->items.size());
|
||||||
block->items.push_back(item);
|
block->items.push_back(item);
|
||||||
item->previousItemChanged();
|
item->previousItemChanged();
|
||||||
if (width) {
|
|
||||||
item->y = block->height;
|
|
||||||
block->height += item->resize(width);
|
|
||||||
}
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1824,10 +1731,16 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
||||||
|
|
||||||
HistoryItem *last = nullptr;
|
HistoryItem *last = nullptr;
|
||||||
HistoryBlock *block = new HistoryBlock(this);
|
HistoryBlock *block = new HistoryBlock(this);
|
||||||
|
block->setIndexInHistory(0);
|
||||||
|
blocks.push_front(block);
|
||||||
|
for (int i = 1, l = blocks.size(); i < l; ++i) {
|
||||||
|
blocks.at(i)->setIndexInHistory(i);
|
||||||
|
}
|
||||||
|
|
||||||
block->items.reserve(slice.size() + (collapsed ? collapsed->size() : 0));
|
block->items.reserve(slice.size() + (collapsed ? collapsed->size() : 0));
|
||||||
for (auto i = slice.cend(), e = slice.cbegin(); i != e;) {
|
for (auto i = slice.cend(), e = slice.cbegin(); i != e;) {
|
||||||
--i;
|
--i;
|
||||||
HistoryItem *adding = createItem(block, *i, false);
|
HistoryItem *adding = createItem(*i, false, true);
|
||||||
if (!adding) continue;
|
if (!adding) continue;
|
||||||
|
|
||||||
for (; groupsIt != groupsEnd; ++groupsIt) {
|
for (; groupsIt != groupsEnd; ++groupsIt) {
|
||||||
|
@ -1847,112 +1760,99 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
||||||
last = addMessageGroupAfterPrevToBlock(group, last, block);
|
last = addMessageGroupAfterPrevToBlock(group, last, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryItem *oldFirst = blocks.isEmpty() ? nullptr : blocks.front()->items.front();
|
|
||||||
while (oldFirst && last && oldFirst->type() == HistoryItemGroup && last->type() == HistoryItemGroup) {
|
|
||||||
static_cast<HistoryGroup*>(last)->uniteWith(static_cast<HistoryGroup*>(oldFirst));
|
|
||||||
oldFirst->destroy();
|
|
||||||
if (blocks.isEmpty()) {
|
|
||||||
oldFirst = 0;
|
|
||||||
} else {
|
|
||||||
t_assert(blocks.size() > 1);
|
|
||||||
oldFirst = blocks.at(1)->items.front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (block->items.isEmpty()) {
|
if (block->items.isEmpty()) {
|
||||||
oldLoaded = true;
|
blocks.pop_front();
|
||||||
delete block;
|
delete block;
|
||||||
} else {
|
block = nullptr;
|
||||||
if (oldFirst) {
|
|
||||||
blocks.push_front(block);
|
|
||||||
if (width) {
|
|
||||||
block->y = 0;
|
|
||||||
for (int32 i = 1, l = blocks.size(); i < l; ++i) {
|
|
||||||
blocks.at(i)->y += block->height;
|
|
||||||
}
|
|
||||||
height += block->height;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
blocks.push_front(block);
|
|
||||||
if (width) {
|
|
||||||
height = block->height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (loadedAtBottom()) { // add photos to overview and authors to lastAuthors / lastParticipants
|
oldLoaded = true;
|
||||||
bool channel = isChannel();
|
} else if (loadedAtBottom()) { // add photos to overview and authors to lastAuthors / lastParticipants
|
||||||
int32 mask = 0;
|
bool channel = isChannel();
|
||||||
QList<UserData*> *lastAuthors = 0;
|
int32 mask = 0;
|
||||||
OrderedSet<PeerData*> *markupSenders = 0;
|
QList<UserData*> *lastAuthors = 0;
|
||||||
if (peer->isChat()) {
|
OrderedSet<PeerData*> *markupSenders = 0;
|
||||||
lastAuthors = &peer->asChat()->lastAuthors;
|
if (peer->isChat()) {
|
||||||
markupSenders = &peer->asChat()->markupSenders;
|
lastAuthors = &peer->asChat()->lastAuthors;
|
||||||
} else if (peer->isMegagroup()) {
|
markupSenders = &peer->asChat()->markupSenders;
|
||||||
lastAuthors = &peer->asChannel()->mgInfo->lastParticipants;
|
} else if (peer->isMegagroup()) {
|
||||||
markupSenders = &peer->asChannel()->mgInfo->markupSenders;
|
lastAuthors = &peer->asChannel()->mgInfo->lastParticipants;
|
||||||
}
|
markupSenders = &peer->asChannel()->mgInfo->markupSenders;
|
||||||
for (int32 i = block->items.size(); i > 0; --i) {
|
}
|
||||||
HistoryItem *item = block->items[i - 1];
|
for (int32 i = block->items.size(); i > 0; --i) {
|
||||||
mask |= item->addToOverview(AddToOverviewFront);
|
HistoryItem *item = block->items[i - 1];
|
||||||
if (item->from()->id) {
|
mask |= item->addToOverview(AddToOverviewFront);
|
||||||
if (lastAuthors) { // chats
|
if (item->from()->id) {
|
||||||
if (item->from()->isUser()) {
|
if (lastAuthors) { // chats
|
||||||
if (!lastAuthors->contains(item->from()->asUser())) {
|
if (item->from()->isUser()) {
|
||||||
lastAuthors->push_back(item->from()->asUser());
|
if (!lastAuthors->contains(item->from()->asUser())) {
|
||||||
if (peer->isMegagroup()) {
|
lastAuthors->push_back(item->from()->asUser());
|
||||||
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated;
|
if (peer->isMegagroup()) {
|
||||||
}
|
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item->author()->id) {
|
}
|
||||||
if (markupSenders) { // chats with bots
|
if (item->author()->id) {
|
||||||
if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) {
|
if (markupSenders) { // chats with bots
|
||||||
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
|
if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) {
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
|
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
|
||||||
bool wasKeyboardHide = markupSenders->contains(item->author());
|
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
|
||||||
if (!wasKeyboardHide) {
|
bool wasKeyboardHide = markupSenders->contains(item->author());
|
||||||
markupSenders->insert(item->author());
|
if (!wasKeyboardHide) {
|
||||||
}
|
markupSenders->insert(item->author());
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero)) {
|
}
|
||||||
if (!lastKeyboardInited) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero)) {
|
||||||
bool botNotInChat = false;
|
if (!lastKeyboardInited) {
|
||||||
if (peer->isChat()) {
|
bool botNotInChat = false;
|
||||||
botNotInChat = (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && item->author()->isUser() && !peer->asChat()->participants.contains(item->author()->asUser());
|
if (peer->isChat()) {
|
||||||
} else if (peer->isMegagroup()) {
|
botNotInChat = (!peer->canWrite() || !peer->asChat()->participants.isEmpty()) && item->author()->isUser() && !peer->asChat()->participants.contains(item->author()->asUser());
|
||||||
botNotInChat = (!peer->canWrite() || peer->asChannel()->mgInfo->botStatus != 0) && item->author()->isUser() && !peer->asChannel()->mgInfo->bots.contains(item->author()->asUser());
|
} else if (peer->isMegagroup()) {
|
||||||
}
|
botNotInChat = (!peer->canWrite() || peer->asChannel()->mgInfo->botStatus != 0) && item->author()->isUser() && !peer->asChannel()->mgInfo->bots.contains(item->author()->asUser());
|
||||||
if (wasKeyboardHide || botNotInChat) {
|
}
|
||||||
clearLastKeyboard();
|
if (wasKeyboardHide || botNotInChat) {
|
||||||
} else {
|
clearLastKeyboard();
|
||||||
lastKeyboardInited = true;
|
} else {
|
||||||
lastKeyboardId = item->id;
|
lastKeyboardInited = true;
|
||||||
lastKeyboardFrom = item->author()->id;
|
lastKeyboardId = item->id;
|
||||||
lastKeyboardUsed = false;
|
lastKeyboardFrom = item->author()->id;
|
||||||
}
|
lastKeyboardUsed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // conversations with bots
|
}
|
||||||
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
|
} else if (!lastKeyboardInited && item->hasReplyMarkup() && !item->out()) { // conversations with bots
|
||||||
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
|
MTPDreplyKeyboardMarkup::Flags markupFlags = App::replyMarkup(channelId(), item->id).flags;
|
||||||
if (markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero) {
|
if (!(markupFlags & MTPDreplyKeyboardMarkup::Flag::f_selective) || item->mentionsMe()) {
|
||||||
clearLastKeyboard();
|
if (markupFlags & MTPDreplyKeyboardMarkup_ClientFlag::f_zero) {
|
||||||
} else {
|
clearLastKeyboard();
|
||||||
lastKeyboardInited = true;
|
} else {
|
||||||
lastKeyboardId = item->id;
|
lastKeyboardInited = true;
|
||||||
lastKeyboardFrom = item->author()->id;
|
lastKeyboardId = item->id;
|
||||||
lastKeyboardUsed = false;
|
lastKeyboardFrom = item->author()->id;
|
||||||
}
|
lastKeyboardUsed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int32 t = 0; t < OverviewCount; ++t) {
|
|
||||||
if ((mask & (1 << t)) && App::wnd()) App::wnd()->mediaOverviewUpdated(peer, MediaOverviewType(t));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for (int32 t = 0; t < OverviewCount; ++t) {
|
||||||
|
if ((mask & (1 << t)) && App::wnd()) App::wnd()->mediaOverviewUpdated(peer, MediaOverviewType(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we've added a new front block, now we check if both
|
||||||
|
// last message of the first block and first message of
|
||||||
|
// the last block are groups, if they are - unite them
|
||||||
|
HistoryItem *first = (block && blocks.size() > 1) ? blocks.at(1)->items.front() : nullptr;
|
||||||
|
if (first && last && first->type() == HistoryItemGroup && last->type() == HistoryItemGroup) {
|
||||||
|
static_cast<HistoryGroup*>(first)->uniteWith(static_cast<HistoryGroup*>(last));
|
||||||
|
last->destroy();
|
||||||
|
|
||||||
|
// last->destroy() could've destroyed this new block
|
||||||
|
// so we can't rely on this pointer any more
|
||||||
|
block = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isChannel()) {
|
if (isChannel()) {
|
||||||
|
@ -1976,10 +1876,13 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
||||||
HistoryItem *prev = blocks.isEmpty() ? nullptr : blocks.back()->items.back();
|
HistoryItem *prev = blocks.isEmpty() ? nullptr : blocks.back()->items.back();
|
||||||
|
|
||||||
HistoryBlock *block = new HistoryBlock(this);
|
HistoryBlock *block = new HistoryBlock(this);
|
||||||
|
block->setIndexInHistory(blocks.size());
|
||||||
|
blocks.push_back(block);
|
||||||
|
|
||||||
block->items.reserve(slice.size() + (collapsed ? collapsed->size() : 0));
|
block->items.reserve(slice.size() + (collapsed ? collapsed->size() : 0));
|
||||||
for (auto i = slice.cend(), e = slice.cbegin(); i != e;) {
|
for (auto i = slice.cend(), e = slice.cbegin(); i != e;) {
|
||||||
--i;
|
--i;
|
||||||
HistoryItem *adding = createItem(block, *i, false);
|
HistoryItem *adding = createItem(*i, false, true);
|
||||||
if (!adding) continue;
|
if (!adding) continue;
|
||||||
|
|
||||||
for (; groupsIt != groupsEnd; ++groupsIt) {
|
for (; groupsIt != groupsEnd; ++groupsIt) {
|
||||||
|
@ -2002,13 +1905,10 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
|
||||||
if (block->items.isEmpty()) {
|
if (block->items.isEmpty()) {
|
||||||
newLoaded = true;
|
newLoaded = true;
|
||||||
setLastMessage(lastImportantMessage());
|
setLastMessage(lastImportantMessage());
|
||||||
|
|
||||||
|
blocks.pop_back();
|
||||||
delete block;
|
delete block;
|
||||||
} else {
|
block = nullptr;
|
||||||
blocks.push_back(block);
|
|
||||||
if (width) {
|
|
||||||
block->y = height;
|
|
||||||
height += block->height;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2621,29 +2521,16 @@ void History::changeMsgId(MsgId oldId, MsgId newId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::blockResized(HistoryBlock *block, int32 dh) {
|
|
||||||
int32 i = blocks.indexOf(block), l = blocks.size();
|
|
||||||
if (i >= 0) {
|
|
||||||
for (++i; i < l; ++i) {
|
|
||||||
blocks[i]->y -= dh;
|
|
||||||
}
|
|
||||||
height -= dh;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void History::removeBlock(HistoryBlock *block) {
|
void History::removeBlock(HistoryBlock *block) {
|
||||||
int32 i = blocks.indexOf(block), h = block->height;
|
int index = blocks.indexOf(block);
|
||||||
if (i >= 0) {
|
if (index >= 0) {
|
||||||
blocks.removeAt(i);
|
setPendingResize();
|
||||||
int32 l = blocks.size();
|
blocks.removeAt(index);
|
||||||
if (i > 0 && l == 1) { // only fake block with date left
|
for (int i = index, l = blocks.size(); i < l; ++i) {
|
||||||
removeBlock(blocks[0]);
|
blocks.at(i)->setIndexInHistory(i);
|
||||||
height = 0;
|
}
|
||||||
} else if (h) {
|
if (index < blocks.size()) {
|
||||||
for (; i < l; ++i) {
|
blocks.at(index)->items.front()->previousItemChanged();
|
||||||
blocks[i]->y -= h;
|
|
||||||
}
|
|
||||||
height -= h;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete block;
|
delete block;
|
||||||
|
@ -2691,14 +2578,14 @@ void HistoryBlock::clear(bool leaveItems) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryBlock::removeItem(HistoryItem *item) {
|
void HistoryBlock::removeItem(HistoryItem *item) {
|
||||||
int32 i = items.indexOf(item), dh = 0;
|
int32 index = items.indexOf(item), dh = 0;
|
||||||
if (history->showFrom == item) {
|
if (history->showFrom == item) {
|
||||||
history->getNextShowFrom(this, i);
|
history->getNextShowFrom(this, index);
|
||||||
}
|
}
|
||||||
if (history->unreadBar == item) {
|
if (history->unreadBar == item) {
|
||||||
history->unreadBar = nullptr;
|
history->unreadBar = nullptr;
|
||||||
}
|
}
|
||||||
if (i < 0) {
|
if (index < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2708,7 +2595,7 @@ void HistoryBlock::removeItem(HistoryItem *item) {
|
||||||
HistoryGroup *nextGroup = 0, *prevGroup = 0;
|
HistoryGroup *nextGroup = 0, *prevGroup = 0;
|
||||||
HistoryCollapse *nextCollapse = 0;
|
HistoryCollapse *nextCollapse = 0;
|
||||||
HistoryItem *prevItem = 0;
|
HistoryItem *prevItem = 0;
|
||||||
for (int32 nextBlock = myIndex, nextIndex = qMin(items.size(), i + 1); nextBlock < history->blocks.size(); ++nextBlock) {
|
for (int32 nextBlock = myIndex, nextIndex = qMin(items.size(), index + 1); nextBlock < history->blocks.size(); ++nextBlock) {
|
||||||
HistoryBlock *block = history->blocks.at(nextBlock);
|
HistoryBlock *block = history->blocks.at(nextBlock);
|
||||||
for (; nextIndex < block->items.size(); ++nextIndex) {
|
for (; nextIndex < block->items.size(); ++nextIndex) {
|
||||||
HistoryItem *item = block->items.at(nextIndex);
|
HistoryItem *item = block->items.at(nextIndex);
|
||||||
|
@ -2728,7 +2615,7 @@ void HistoryBlock::removeItem(HistoryItem *item) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int32 prevBlock = myIndex + 1, prevIndex = qMax(1, i); prevBlock > 0;) {
|
for (int32 prevBlock = myIndex + 1, prevIndex = qMax(1, index); prevBlock > 0;) {
|
||||||
--prevBlock;
|
--prevBlock;
|
||||||
HistoryBlock *block = history->blocks.at(prevBlock);
|
HistoryBlock *block = history->blocks.at(prevBlock);
|
||||||
if (!prevIndex) prevIndex = block->items.size();
|
if (!prevIndex) prevIndex = block->items.size();
|
||||||
|
@ -2760,19 +2647,21 @@ void HistoryBlock::removeItem(HistoryItem *item) {
|
||||||
// myIndex can be invalid now, because of destroying previous blocks
|
// myIndex can be invalid now, because of destroying previous blocks
|
||||||
|
|
||||||
dh = item->height();
|
dh = item->height();
|
||||||
items.remove(i);
|
items.remove(index);
|
||||||
if ((!item->out() || item->isPost()) && item->unread() && history->unreadCount) {
|
if ((!item->out() || item->isPost()) && item->unread() && history->unreadCount) {
|
||||||
history->setUnreadCount(history->unreadCount - 1);
|
history->setUnreadCount(history->unreadCount - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
History *h = history;
|
History *h = history;
|
||||||
if (int32 l = items.size()) {
|
if (int l = items.size()) {
|
||||||
for (; i < l; ++i) {
|
for (int i = index; i < l; ++i) {
|
||||||
items.at(i)->y -= dh;
|
|
||||||
items.at(i)->setIndexInBlock(i);
|
items.at(i)->setIndexInBlock(i);
|
||||||
}
|
}
|
||||||
height -= dh;
|
if (index < items.size()) {
|
||||||
history->blockResized(this, dh);
|
items.at(index)->previousItemChanged();
|
||||||
|
} else if (_indexInHistory + 1 < history->blocks.size()) {
|
||||||
|
history->blocks.at(_indexInHistory + 1)->items.front()->previousItemChanged();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
history->removeBlock(this);
|
history->removeBlock(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,16 +236,10 @@ public:
|
||||||
return blocks.isEmpty();
|
return blocks.isEmpty();
|
||||||
}
|
}
|
||||||
void clear(bool leaveItems = false);
|
void clear(bool leaveItems = false);
|
||||||
void blockResized(HistoryBlock *block, int32 dh);
|
|
||||||
void removeBlock(HistoryBlock *block);
|
void removeBlock(HistoryBlock *block);
|
||||||
|
|
||||||
virtual ~History();
|
virtual ~History();
|
||||||
|
|
||||||
HistoryItem *createItem(HistoryBlock *block, const MTPMessage &msg, bool applyServiceAction);
|
|
||||||
HistoryItem *createItemForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *msg);
|
|
||||||
HistoryItem *createItemDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption);
|
|
||||||
HistoryItem *createItemPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
|
|
||||||
|
|
||||||
HistoryItem *addNewService(MsgId msgId, QDateTime date, const QString &text, MTPDmessage::Flags flags = 0, HistoryMedia *media = 0, bool newMsg = true);
|
HistoryItem *addNewService(MsgId msgId, QDateTime date, const QString &text, MTPDmessage::Flags flags = 0, HistoryMedia *media = 0, bool newMsg = true);
|
||||||
HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);
|
HistoryItem *addNewMessage(const MTPMessage &msg, NewMessageType type);
|
||||||
HistoryItem *addToHistory(const MTPMessage &msg);
|
HistoryItem *addToHistory(const MTPMessage &msg);
|
||||||
|
@ -439,6 +433,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void clearOnDestroy();
|
void clearOnDestroy();
|
||||||
|
HistoryItem *addNewToLastBlock(const MTPMessage &msg, NewMessageType type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -467,9 +462,14 @@ private:
|
||||||
friend class HistoryBlock;
|
friend class HistoryBlock;
|
||||||
friend class ChannelHistory;
|
friend class ChannelHistory;
|
||||||
|
|
||||||
|
HistoryItem *createItem(const MTPMessage &msg, bool applyServiceAction, bool detachExistingItem);
|
||||||
|
HistoryItem *createItemForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, int32 from, HistoryMessage *msg);
|
||||||
|
HistoryItem *createItemDocument(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, DocumentData *doc, const QString &caption);
|
||||||
|
HistoryItem *createItemPhoto(MsgId id, MTPDmessage::Flags flags, int32 viaBotId, MsgId replyTo, QDateTime date, int32 from, PhotoData *photo, const QString &caption);
|
||||||
|
|
||||||
HistoryItem *addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *prev, HistoryBlock *block);
|
HistoryItem *addItemAfterPrevToBlock(HistoryItem *item, HistoryItem *prev, HistoryBlock *block);
|
||||||
HistoryItem *addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex, int32 itemIndex);
|
HistoryItem *addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex, int32 itemIndex);
|
||||||
HistoryItem *addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg);
|
HistoryItem *addNewItem(HistoryItem *adding, bool newMsg);
|
||||||
HistoryItem *addMessageGroupAfterPrevToBlock(const MTPDmessageGroup &group, HistoryItem *prev, HistoryBlock *block);
|
HistoryItem *addMessageGroupAfterPrevToBlock(const MTPDmessageGroup &group, HistoryItem *prev, HistoryBlock *block);
|
||||||
HistoryItem *addMessageGroupAfterPrev(HistoryItem *newItem, HistoryItem *prev);
|
HistoryItem *addMessageGroupAfterPrev(HistoryItem *newItem, HistoryItem *prev);
|
||||||
|
|
||||||
|
@ -851,6 +851,9 @@ public:
|
||||||
HistoryBlock *previous() const {
|
HistoryBlock *previous() const {
|
||||||
return (_indexInHistory > 0) ? history->blocks.at(_indexInHistory - 1) : nullptr;
|
return (_indexInHistory > 0) ? history->blocks.at(_indexInHistory - 1) : nullptr;
|
||||||
}
|
}
|
||||||
|
void setIndexInHistory(int index) {
|
||||||
|
_indexInHistory = index;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -1346,7 +1349,7 @@ protected:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this should be used only in initDimensions()
|
// this should be used only in previousItemChanged()
|
||||||
// to add required bits to the Interfaces mask
|
// to add required bits to the Interfaces mask
|
||||||
// after that always use Is<HistoryMessageDate>()
|
// after that always use Is<HistoryMessageDate>()
|
||||||
bool displayDate() const {
|
bool displayDate() const {
|
||||||
|
|
Loading…
Reference in New Issue