mirror of https://github.com/procxx/kepka.git
				
				
				
			fixed history block index bug
This commit is contained in:
		
							parent
							
								
									fd7a30f143
								
							
						
					
					
						commit
						f662067a68
					
				| 
						 | 
				
			
			@ -208,7 +208,7 @@ class AnimationCreator {
 | 
			
		|||
public:
 | 
			
		||||
	AnimationCreator(AnimationImplementation *ptr) : _ptr(ptr) {}
 | 
			
		||||
	AnimationCreator(const AnimationCreator &other) : _ptr(other.create()) {}
 | 
			
		||||
	AnimationImplementation *create() const { return exchange(_ptr); }
 | 
			
		||||
	AnimationImplementation *create() const { return getPointerAndReset(_ptr); }
 | 
			
		||||
	~AnimationCreator() { deleteAndMark(_ptr); }
 | 
			
		||||
private:
 | 
			
		||||
	AnimationCreator &operator=(const AnimationCreator &other);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -572,15 +572,9 @@ void ChannelHistory::addNewGroup(const MTPMessageGroup &group) {
 | 
			
		|||
 | 
			
		||||
	if (onlyImportant()) {
 | 
			
		||||
		if (newLoaded) {
 | 
			
		||||
			HistoryBlock *block = blocks.isEmpty() ? nullptr : blocks.back();
 | 
			
		||||
			HistoryItem *prev = nullptr;
 | 
			
		||||
			if (block) {
 | 
			
		||||
				prev = block->items.back();
 | 
			
		||||
			} else {
 | 
			
		||||
				block = new HistoryBlock(this);
 | 
			
		||||
				block->setIndexInHistory(blocks.size());
 | 
			
		||||
				blocks.push_back(block);
 | 
			
		||||
			}
 | 
			
		||||
			HistoryBlock *block = blocks.isEmpty() ? addNewLastBlock() : blocks.back();
 | 
			
		||||
			HistoryItem *prev = block->items.isEmpty() ? nullptr : block->items.back();
 | 
			
		||||
 | 
			
		||||
			prev = addMessageGroupAfterPrevToBlock(d, prev, block);
 | 
			
		||||
			if (block->items.isEmpty()) {
 | 
			
		||||
				blocks.pop_back();
 | 
			
		||||
| 
						 | 
				
			
			@ -643,12 +637,7 @@ HistoryJoined *ChannelHistory::insertJoinedMessage(bool unread) {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// adding new item to new block
 | 
			
		||||
	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);
 | 
			
		||||
	}
 | 
			
		||||
	HistoryBlock *block = addNewFirstBlock();
 | 
			
		||||
 | 
			
		||||
	_joinedMessage = HistoryJoined::create(this, inviteDate, inviter, flags);
 | 
			
		||||
	addItemAfterPrevToBlock(_joinedMessage, nullptr, block);
 | 
			
		||||
| 
						 | 
				
			
			@ -827,9 +816,7 @@ void ChannelHistory::switchMode() {
 | 
			
		|||
 | 
			
		||||
		HistoryItem *prev = 0;
 | 
			
		||||
		for (int32 i = 0; i < count;) {
 | 
			
		||||
			HistoryBlock *block = new HistoryBlock(this);
 | 
			
		||||
			block->setIndexInHistory(blocks.size());
 | 
			
		||||
			blocks.push_back(block);
 | 
			
		||||
			HistoryBlock *block = addNewLastBlock();
 | 
			
		||||
 | 
			
		||||
			int32 willAddToBlock = qMin(int32(MessagesPerPage), count - i);
 | 
			
		||||
			block->items.reserve(willAddToBlock);
 | 
			
		||||
| 
						 | 
				
			
			@ -1560,11 +1547,7 @@ HistoryItem *History::addNewItem(HistoryItem *adding, bool newMsg) {
 | 
			
		|||
	t_assert(adding != nullptr);
 | 
			
		||||
	t_assert(adding->detached());
 | 
			
		||||
 | 
			
		||||
	if (blocks.isEmpty()) {
 | 
			
		||||
		blocks.push_back(new HistoryBlock(this));
 | 
			
		||||
		blocks.back()->setIndexInHistory(blocks.size());
 | 
			
		||||
	}
 | 
			
		||||
	HistoryBlock *block = blocks.back();
 | 
			
		||||
	HistoryBlock *block = blocks.isEmpty() ? addNewLastBlock() : blocks.back();
 | 
			
		||||
 | 
			
		||||
	adding->attachToBlock(block, block->items.size());
 | 
			
		||||
	block->items.push_back(adding);
 | 
			
		||||
| 
						 | 
				
			
			@ -1726,13 +1709,8 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
 | 
			
		|||
 | 
			
		||||
	const MTPMessageGroup *groupsBegin = (isChannel() && collapsed) ? collapsed->constData() : 0, *groupsIt = groupsBegin, *groupsEnd = (isChannel() && collapsed) ? (groupsBegin + collapsed->size()) : 0;
 | 
			
		||||
 | 
			
		||||
	HistoryItem *last = nullptr;
 | 
			
		||||
	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);
 | 
			
		||||
	}
 | 
			
		||||
	HistoryItem *prev = nullptr;
 | 
			
		||||
	HistoryBlock *block = addNewFirstBlock();
 | 
			
		||||
 | 
			
		||||
	block->items.reserve(slice.size() + (collapsed ? collapsed->size() : 0));
 | 
			
		||||
	for (auto i = slice.cend(), e = slice.cbegin(); i != e;) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1745,16 +1723,16 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
 | 
			
		|||
			const MTPDmessageGroup &group(groupsIt->c_messageGroup());
 | 
			
		||||
			if (group.vmin_id.v >= adding->id) break;
 | 
			
		||||
 | 
			
		||||
			last = addMessageGroupAfterPrevToBlock(group, last, block);
 | 
			
		||||
			prev = addMessageGroupAfterPrevToBlock(group, prev, block);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		last = addItemAfterPrevToBlock(adding, last, block);
 | 
			
		||||
		prev = addItemAfterPrevToBlock(adding, prev, block);
 | 
			
		||||
	}
 | 
			
		||||
	for (; groupsIt != groupsEnd; ++groupsIt) {
 | 
			
		||||
		if (groupsIt->type() != mtpc_messageGroup) continue;
 | 
			
		||||
		const MTPDmessageGroup &group(groupsIt->c_messageGroup());
 | 
			
		||||
 | 
			
		||||
		last = addMessageGroupAfterPrevToBlock(group, last, block);
 | 
			
		||||
		prev = addMessageGroupAfterPrevToBlock(group, prev, block);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (block->items.isEmpty()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1839,17 +1817,26 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 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();
 | 
			
		||||
	// some checks if there was some message history already
 | 
			
		||||
	if (block && blocks.size() > 1) {
 | 
			
		||||
		HistoryItem *last = block->items.back(); // .. item, item, item, last ], [ first, item, item ..
 | 
			
		||||
		HistoryItem *first = blocks.at(1)->items.front();
 | 
			
		||||
 | 
			
		||||
		// last->destroy() could've destroyed this new block
 | 
			
		||||
		// so we can't rely on this pointer any more
 | 
			
		||||
		block = nullptr;
 | 
			
		||||
		// we've added a new front block, so previous item for
 | 
			
		||||
		// the old first item of a first block was changed
 | 
			
		||||
		first->previousItemChanged();
 | 
			
		||||
 | 
			
		||||
		// we've added a new front block, now we check if both
 | 
			
		||||
		// last message of the first block and first message of
 | 
			
		||||
		// the second block are groups, if they are - unite them
 | 
			
		||||
		if (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()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1872,9 +1859,7 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
 | 
			
		|||
 | 
			
		||||
		HistoryItem *prev = blocks.isEmpty() ? nullptr : blocks.back()->items.back();
 | 
			
		||||
 | 
			
		||||
		HistoryBlock *block = new HistoryBlock(this);
 | 
			
		||||
		block->setIndexInHistory(blocks.size());
 | 
			
		||||
		blocks.push_back(block);
 | 
			
		||||
		HistoryBlock *block = addNewLastBlock();
 | 
			
		||||
 | 
			
		||||
		block->items.reserve(slice.size() + (collapsed ? collapsed->size() : 0));
 | 
			
		||||
		for (auto i = slice.cend(), e = slice.cbegin(); i != e;) {
 | 
			
		||||
| 
						 | 
				
			
			@ -2205,6 +2190,23 @@ HistoryItem *History::addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex,
 | 
			
		|||
	return newItem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HistoryBlock *History::addNewLastBlock() {
 | 
			
		||||
	HistoryBlock *result = new HistoryBlock(this);
 | 
			
		||||
	result->setIndexInHistory(blocks.size());
 | 
			
		||||
	blocks.push_back(result);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HistoryBlock *History::addNewFirstBlock() {
 | 
			
		||||
	HistoryBlock *result = new HistoryBlock(this);
 | 
			
		||||
	result->setIndexInHistory(0);
 | 
			
		||||
	blocks.push_front(result);
 | 
			
		||||
	for (int i = 1, l = blocks.size(); i < l; ++i) {
 | 
			
		||||
		blocks.at(i)->setIndexInHistory(i);
 | 
			
		||||
	}
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void History::clearNotifications() {
 | 
			
		||||
	notifies.clear();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -6605,8 +6607,12 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
 | 
			
		|||
	textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle));
 | 
			
		||||
 | 
			
		||||
	if (displayFromPhoto()) {
 | 
			
		||||
		int32 photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
 | 
			
		||||
		author()->paintUserpic(p, st::msgPhotoSize, photoleft, marginTop());
 | 
			
		||||
		int photoleft = left + ((outbg && !Adaptive::Wide()) ? (width + (st::msgPhotoSkip - st::msgPhotoSize)) : (-st::msgPhotoSkip));
 | 
			
		||||
		int phototop = marginTop();
 | 
			
		||||
//		if (history()->scrollTopItem == this) {
 | 
			
		||||
//			phototop = qMax(qMin(history()->scrollTopOffset, _height - marginBottom() - int(st::msgPhotoSize)), phototop);
 | 
			
		||||
//		}
 | 
			
		||||
		author()->paintUserpic(p, st::msgPhotoSize, photoleft, phototop);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (bubble) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -220,6 +220,9 @@ class History {
 | 
			
		|||
public:
 | 
			
		||||
 | 
			
		||||
	History(const PeerId &peerId);
 | 
			
		||||
	History(const History &) = delete;
 | 
			
		||||
	History &operator=(const History &) = delete;
 | 
			
		||||
 | 
			
		||||
	ChannelId channelId() const {
 | 
			
		||||
		return peerToChannel(peer->id);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -503,9 +506,10 @@ private:
 | 
			
		|||
	HistoryItem *addMessageGroupAfterPrev(HistoryItem *newItem, HistoryItem *prev);
 | 
			
		||||
	HistoryItem *addNewInTheMiddle(HistoryItem *newItem, int32 blockIndex, int32 itemIndex);
 | 
			
		||||
 | 
			
		||||
	History(const History &) = delete;
 | 
			
		||||
	History &operator=(const History &) = delete;
 | 
			
		||||
};
 | 
			
		||||
	HistoryBlock *addNewLastBlock();
 | 
			
		||||
	HistoryBlock *addNewFirstBlock();
 | 
			
		||||
 | 
			
		||||
 };
 | 
			
		||||
 | 
			
		||||
class HistoryGroup;
 | 
			
		||||
class HistoryCollapse;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,8 +27,8 @@ void deleteAndMark(T *&link) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
T *exchange(T *&ptr) {
 | 
			
		||||
	T *result = 0;
 | 
			
		||||
T *getPointerAndReset(T *&ptr) {
 | 
			
		||||
	T *result = nullptr;
 | 
			
		||||
	qSwap(result, ptr);
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -792,7 +792,7 @@ class FunctionCreator {
 | 
			
		|||
public:
 | 
			
		||||
	FunctionCreator(FunctionImplementation<R> *ptr) : _ptr(ptr) {}
 | 
			
		||||
	FunctionCreator(const FunctionCreator<R> &other) : _ptr(other.create()) {}
 | 
			
		||||
	FunctionImplementation<R> *create() const { return exchange(_ptr); }
 | 
			
		||||
	FunctionImplementation<R> *create() const { return getPointerAndReset(_ptr); }
 | 
			
		||||
	~FunctionCreator() { destroyImplementation(_ptr); }
 | 
			
		||||
private:
 | 
			
		||||
	FunctionCreator<R> &operator=(const FunctionCreator<R> &other);
 | 
			
		||||
| 
						 | 
				
			
			@ -861,7 +861,7 @@ class Function1Creator {
 | 
			
		|||
public:
 | 
			
		||||
	Function1Creator(Function1Implementation<R, A1> *ptr) : _ptr(ptr) {}
 | 
			
		||||
	Function1Creator(const Function1Creator<R, A1> &other) : _ptr(other.create()) {}
 | 
			
		||||
	Function1Implementation<R, A1> *create() const { return exchange(_ptr); }
 | 
			
		||||
	Function1Implementation<R, A1> *create() const { return getPointerAndReset(_ptr); }
 | 
			
		||||
	~Function1Creator() { destroyImplementation(_ptr); }
 | 
			
		||||
private:
 | 
			
		||||
	Function1Creator<R, A1> &operator=(const Function1Creator<R, A1> &other);
 | 
			
		||||
| 
						 | 
				
			
			@ -930,7 +930,7 @@ class Function2Creator {
 | 
			
		|||
public:
 | 
			
		||||
	Function2Creator(Function2Implementation<R, A1, A2> *ptr) : _ptr(ptr) {}
 | 
			
		||||
	Function2Creator(const Function2Creator<R, A1, A2> &other) : _ptr(other.create()) {}
 | 
			
		||||
	Function2Implementation<R, A1, A2> *create() const { return exchange(_ptr); }
 | 
			
		||||
	Function2Implementation<R, A1, A2> *create() const { return getPointerAndReset(_ptr); }
 | 
			
		||||
	~Function2Creator() { destroyImplementation(_ptr); }
 | 
			
		||||
private:
 | 
			
		||||
	Function2Creator<R, A1, A2> &operator=(const Function2Creator<R, A1, A2> &other);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue