mirror of https://github.com/procxx/kepka.git
optimized enumeration of userpics
This commit is contained in:
parent
e45de88bd6
commit
02ca81ac64
|
@ -293,8 +293,8 @@ History::History(const PeerId &peerId) : width(0), height(0)
|
||||||
if (peer->isChannel() || (peer->isUser() && peer->asUser()->botInfo)) {
|
if (peer->isChannel() || (peer->isUser() && peer->asUser()->botInfo)) {
|
||||||
outboxReadBefore = INT_MAX;
|
outboxReadBefore = INT_MAX;
|
||||||
}
|
}
|
||||||
for (int32 i = 0; i < OverviewCount; ++i) {
|
for (auto &countData : overviewCountData) {
|
||||||
overviewCountData[i] = -1; // not loaded yet
|
countData = -1; // not loaded yet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,6 +309,15 @@ void History::clearLastKeyboard() {
|
||||||
lastKeyboardFrom = 0;
|
lastKeyboardFrom = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool History::canHaveFromPhotos() const {
|
||||||
|
if (peer->isUser() && !Adaptive::Wide()) {
|
||||||
|
return false;
|
||||||
|
} else if (isChannel() && asChannelHistory()->onlyImportant()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void History::setHasPendingResizedItems() {
|
void History::setHasPendingResizedItems() {
|
||||||
_flags |= Flag::f_has_pending_resized_items;
|
_flags |= Flag::f_has_pending_resized_items;
|
||||||
Global::RefHandleHistoryUpdate().call();
|
Global::RefHandleHistoryUpdate().call();
|
||||||
|
@ -6030,8 +6039,7 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg) :
|
HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg) :
|
||||||
HistoryItem(history, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0)
|
HistoryItem(history, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) {
|
||||||
, _text(st::msgMinWidth) {
|
|
||||||
PeerId authorOriginalId = 0, fromOriginalId = 0;
|
PeerId authorOriginalId = 0, fromOriginalId = 0;
|
||||||
MsgId originalId = 0;
|
MsgId originalId = 0;
|
||||||
if (msg.has_fwd_from() && msg.vfwd_from.type() == mtpc_messageFwdHeader) {
|
if (msg.has_fwd_from() && msg.vfwd_from.type() == mtpc_messageFwdHeader) {
|
||||||
|
@ -7540,9 +7548,7 @@ bool HistoryServiceMessage::updatePinnedText(const QString *pfrom, QString *ptex
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryServiceMessage::HistoryServiceMessage(History *history, const MTPDmessageService &msg) :
|
HistoryServiceMessage::HistoryServiceMessage(History *history, const MTPDmessageService &msg) :
|
||||||
HistoryItem(history, msg.vid.v, mtpCastFlags(msg.vflags.v), ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0)
|
HistoryItem(history, msg.vid.v, mtpCastFlags(msg.vflags.v), ::date(msg.vdate), msg.has_from_id() ? msg.vfrom_id.v : 0) {
|
||||||
, _text(st::msgMinWidth)
|
|
||||||
, _media(0) {
|
|
||||||
if (msg.has_reply_to_msg_id()) {
|
if (msg.has_reply_to_msg_id()) {
|
||||||
UpdateInterfaces(HistoryServicePinned::Bit());
|
UpdateInterfaces(HistoryServicePinned::Bit());
|
||||||
MsgId pinnedMsgId = Get<HistoryServicePinned>()->msgId = msg.vreply_to_msg_id.v;
|
MsgId pinnedMsgId = Get<HistoryServicePinned>()->msgId = msg.vreply_to_msg_id.v;
|
||||||
|
|
|
@ -346,6 +346,10 @@ public:
|
||||||
bool updateTyping(uint64 ms, bool force = false);
|
bool updateTyping(uint64 ms, bool force = false);
|
||||||
void clearLastKeyboard();
|
void clearLastKeyboard();
|
||||||
|
|
||||||
|
// optimization for userpics displayed on the left
|
||||||
|
// if this returns false there is no need to even try to handle them
|
||||||
|
bool canHaveFromPhotos() const;
|
||||||
|
|
||||||
typedef QList<HistoryBlock*> Blocks;
|
typedef QList<HistoryBlock*> Blocks;
|
||||||
Blocks blocks;
|
Blocks blocks;
|
||||||
|
|
||||||
|
@ -2717,8 +2721,8 @@ protected:
|
||||||
bool updatePinned(bool force = false);
|
bool updatePinned(bool force = false);
|
||||||
bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr);
|
bool updatePinnedText(const QString *pfrom = nullptr, QString *ptext = nullptr);
|
||||||
|
|
||||||
Text _text;
|
Text _text = { int(st::msgMinWidth) };
|
||||||
HistoryMedia *_media;
|
HistoryMedia *_media = nullptr;
|
||||||
|
|
||||||
int32 _textWidth, _textHeight;
|
int32 _textWidth, _textHeight;
|
||||||
};
|
};
|
||||||
|
|
|
@ -94,32 +94,53 @@ void HistoryInner::repaintItem(const HistoryItem *item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// helper binary search for an item in a list that is not completely below the given bottom of the visible area
|
||||||
|
// is applied once for blocks list in a history and once for items list in the found block
|
||||||
|
template <typename T>
|
||||||
|
int binarySearchBlocksOrItems(const T &list, int bottom) {
|
||||||
|
int start = 0, end = list.size();
|
||||||
|
while (end - start > 1) {
|
||||||
|
int middle = (start + end) / 2;
|
||||||
|
if (list.at(middle)->y >= bottom) {
|
||||||
|
end = middle;
|
||||||
|
} else {
|
||||||
|
start = middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Method>
|
template <typename Method>
|
||||||
void HistoryInner::enumerateUserpicsInHistory(History *h, int htop, Method method) {
|
void HistoryInner::enumerateUserpicsInHistory(History *h, int htop, Method method) {
|
||||||
// no displayed messages in this history
|
// no displayed messages in this history
|
||||||
if (htop < 0) return;
|
if (htop < 0 || h->isEmpty() || !h->canHaveFromPhotos() || _visibleAreaBottom <= htop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// find and remember the bottom of an attached messages pack
|
// find and remember the bottom of an attached messages pack
|
||||||
// -1 means we didn't find an attached to previous message yet
|
// -1 means we didn't find an attached to previous message yet
|
||||||
int lowestAttachedItemBottom = -1;
|
int lowestAttachedItemBottom = -1;
|
||||||
|
|
||||||
int blockIndex = h->blocks.size();
|
// binary search for blockIndex of the first block that is not completely below the visible area
|
||||||
int itemIndex = 0;
|
int blockIndex = binarySearchBlocksOrItems(h->blocks, _visibleAreaBottom - htop);
|
||||||
while (blockIndex > 0) {
|
|
||||||
HistoryBlock *block = h->blocks.at(--blockIndex);
|
|
||||||
itemIndex = block->items.size();
|
|
||||||
|
|
||||||
int blocktop = htop + block->y;
|
// binary search for itemIndex of the first item that is not completely below the visible area
|
||||||
while (itemIndex > 0) {
|
HistoryBlock *block = h->blocks.at(blockIndex);
|
||||||
HistoryItem *item = block->items.at(--itemIndex);
|
int blocktop = htop + block->y;
|
||||||
|
int itemIndex = binarySearchBlocksOrItems(block->items, _visibleAreaBottom - blocktop);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
while (itemIndex >= 0) {
|
||||||
|
HistoryItem *item = block->items.at(itemIndex--);
|
||||||
int itemtop = blocktop + item->y;
|
int itemtop = blocktop + item->y;
|
||||||
int itembottom = itemtop + item->height();
|
int itembottom = itemtop + item->height();
|
||||||
|
|
||||||
// skip items that are below the visible area
|
// binary search should've skipped all the items that are below the visible area
|
||||||
if (itemtop >= _visibleAreaBottom) {
|
t_assert(itemtop < _visibleAreaBottom);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// skip all service messages
|
||||||
if (HistoryMessage *message = item->toHistoryMessage()) {
|
if (HistoryMessage *message = item->toHistoryMessage()) {
|
||||||
if (lowestAttachedItemBottom < 0 && message->isAttachedToPrevious()) {
|
if (lowestAttachedItemBottom < 0 && message->isAttachedToPrevious()) {
|
||||||
lowestAttachedItemBottom = itembottom - message->marginBottom();
|
lowestAttachedItemBottom = itembottom - message->marginBottom();
|
||||||
|
@ -131,15 +152,21 @@ void HistoryInner::enumerateUserpicsInHistory(History *h, int htop, Method metho
|
||||||
if (lowestAttachedItemBottom < 0) {
|
if (lowestAttachedItemBottom < 0) {
|
||||||
lowestAttachedItemBottom = itembottom - message->marginBottom();
|
lowestAttachedItemBottom = itembottom - message->marginBottom();
|
||||||
}
|
}
|
||||||
int userpicTop = qMin(qMax(itemtop + message->marginTop(), _visibleAreaTop + st::msgMargin.left()), lowestAttachedItemBottom - int(st::msgPhotoSize));
|
// attach userpic to the top of the visible area with the same margin as it is from the left side
|
||||||
|
int userpicTop = qMax(itemtop + message->marginTop(), _visibleAreaTop + st::msgMargin.left());
|
||||||
|
|
||||||
|
// do not let the userpic go below the attached messages pack bottom line
|
||||||
|
userpicTop = qMin(userpicTop, lowestAttachedItemBottom - int(st::msgPhotoSize));
|
||||||
|
|
||||||
// call the template callback function that was passed
|
// call the template callback function that was passed
|
||||||
// and return if it finished everything it needed
|
// and return if it finished everything it needed
|
||||||
if (!method(message, userpicTop)) {
|
if (!method(message, userpicTop)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// forget the found bottom of the pack, search for the next one from scratch
|
// forget the found bottom of the pack, search for the next one from scratch
|
||||||
|
if (!message->isAttachedToPrevious()) {
|
||||||
lowestAttachedItemBottom = -1;
|
lowestAttachedItemBottom = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -154,6 +181,14 @@ void HistoryInner::enumerateUserpicsInHistory(History *h, int htop, Method metho
|
||||||
if (blocktop <= _visibleAreaTop) {
|
if (blocktop <= _visibleAreaTop) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (--blockIndex < 0) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
block = h->blocks.at(blockIndex);
|
||||||
|
blocktop = htop + block->y;
|
||||||
|
itemIndex = block->items.size() - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1066,12 +1066,7 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutOverviewLink::LayoutOverviewLink(HistoryMedia *media, HistoryItem *parent) : LayoutMediaItem(OverviewItemInfo::Bit(), parent)
|
LayoutOverviewLink::LayoutOverviewLink(HistoryMedia *media, HistoryItem *parent) : LayoutMediaItem(OverviewItemInfo::Bit(), parent) {
|
||||||
, _titlew(0)
|
|
||||||
, _page(0)
|
|
||||||
, _pixw(0)
|
|
||||||
, _pixh(0)
|
|
||||||
, _text(st::msgMinWidth) {
|
|
||||||
QString text = _parent->originalText();
|
QString text = _parent->originalText();
|
||||||
EntitiesInText entities = _parent->originalEntities();
|
EntitiesInText entities = _parent->originalEntities();
|
||||||
|
|
||||||
|
|
|
@ -440,10 +440,11 @@ private:
|
||||||
TextLinkPtr _photol;
|
TextLinkPtr _photol;
|
||||||
|
|
||||||
QString _title, _letter;
|
QString _title, _letter;
|
||||||
int32 _titlew;
|
int _titlew = 0;
|
||||||
WebPageData *_page;
|
WebPageData *_page = nullptr;
|
||||||
int32 _pixw, _pixh;
|
int _pixw = 0;
|
||||||
Text _text;
|
int _pixh = 0;
|
||||||
|
Text _text = { int(st::msgMinWidth) };
|
||||||
|
|
||||||
struct Link {
|
struct Link {
|
||||||
Link() : width(0) {
|
Link() : width(0) {
|
||||||
|
|
|
@ -89,6 +89,7 @@
|
||||||
<ImageHasSafeExceptionHandlers />
|
<ImageHasSafeExceptionHandlers />
|
||||||
<IgnoreSpecificDefaultLibraries>LIBCMT</IgnoreSpecificDefaultLibraries>
|
<IgnoreSpecificDefaultLibraries>LIBCMT</IgnoreSpecificDefaultLibraries>
|
||||||
<ImportLibrary>$(SolutionDir)$(Platform)\$(Configuration)Intermediate\$(TargetName).lib</ImportLibrary>
|
<ImportLibrary>$(SolutionDir)$(Platform)\$(Configuration)Intermediate\$(TargetName).lib</ImportLibrary>
|
||||||
|
<AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
|
||||||
</Link>
|
</Link>
|
||||||
<CustomBuildStep>
|
<CustomBuildStep>
|
||||||
</CustomBuildStep>
|
</CustomBuildStep>
|
||||||
|
|
Loading…
Reference in New Issue