From 5a87bf41148cc1a5e538c4c786e6ae359b528512 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Sun, 3 Jan 2016 09:43:42 +0800
Subject: [PATCH] fixed inline results display lag, cancelling inline query by
 Escape, add/erase in overview refactored, animated gifv are not in shared
 files anymore

---
 Telegram/Build.bat                     |   7 +-
 Telegram/SourceFiles/app.cpp           |  44 +++---
 Telegram/SourceFiles/dropdown.cpp      |  11 +-
 Telegram/SourceFiles/dropdown.h        |   3 +
 Telegram/SourceFiles/history.cpp       | 190 ++++++++++---------------
 Telegram/SourceFiles/history.h         |  46 +++---
 Telegram/SourceFiles/historywidget.cpp |  11 +-
 Telegram/SourceFiles/mainwidget.cpp    |  14 +-
 8 files changed, 152 insertions(+), 174 deletions(-)

diff --git a/Telegram/Build.bat b/Telegram/Build.bat
index 7258be038..650a937ee 100644
--- a/Telegram/Build.bat
+++ b/Telegram/Build.bat
@@ -53,9 +53,12 @@ if %BetaVersion% neq 0 (
     exit /b 1
   )
 )
-
 cd SourceFiles\
-copy telegram.qrc /B+,,/Y
+if "%1" == "fast" (
+  echo Skipping touching of telegram.qrc..
+) else (
+  copy telegram.qrc /B+,,/Y
+)
 cd ..\
 if %errorlevel% neq 0 goto error
 
diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp
index d8cf7f345..045f77865 100644
--- a/Telegram/SourceFiles/app.cpp
+++ b/Telegram/SourceFiles/app.cpp
@@ -569,7 +569,7 @@ namespace App {
 
 				ChannelData *cdata = data->asChannel();
 				cdata->inputChannel = MTP_inputChannel(d.vid, d.vaccess_hash);
-				
+
 				QString uname = d.has_username() ? textOneLine(qs(d.vusername)) : QString();
 				cdata->setName(qs(d.vtitle), uname);
 
@@ -901,18 +901,12 @@ namespace App {
 			peerId = peerFromUser(m.vfrom_id);
 		}
 		if (HistoryItem *existing = App::histItemById(peerToChannel(peerId), m.vid.v)) {
-			bool hasLinks = m.has_entities() && !m.ventities.c_vector().v.isEmpty();
-			if ((hasLinks && !existing->hasTextLinks()) || (!hasLinks && existing->textHasLinks())) {
-				existing->setText(qs(m.vmessage), m.has_entities() ? entitiesFromMTP(m.ventities.c_vector().v) : EntitiesInText());
-				existing->initDimensions();
-				Notify::historyItemResized(existing);
-				if (existing->hasTextLinks() && existing->indexInOverview()) {
-					existing->history()->addToOverview(existing, OverviewLinks);
-				}
-			}
+			existing->setText(qs(m.vmessage), m.has_entities() ? entitiesFromMTP(m.ventities.c_vector().v) : EntitiesInText());
+			existing->initDimensions();
+			Notify::historyItemResized(existing);
 
 			existing->updateMedia(m.has_media() ? (&m.vmedia) : 0, true);
-
+			existing->addToOverview(AddToOverviewNew);
 			existing->setViewsCount(m.has_views() ? m.vviews.v : -1);
 
 			if (!existing->detached()) {
@@ -1001,7 +995,7 @@ namespace App {
 				const string &s(d.vbytes.c_string().v);
 				QByteArray bytes(s.data(), s.size());
 				return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, 0, 0, 0, 0), bytes);
-			}				
+			}
 		} break;
 		}
 		return ImagePtr();
@@ -1028,7 +1022,7 @@ namespace App {
 		}
 		return StorageImageLocation();
 	}
-	
+
 	void feedInboxRead(const PeerId &peer, MsgId upTo) {
 		History *h = App::historyLoaded(peer);
 		if (h) {
@@ -1250,7 +1244,7 @@ namespace App {
 				const string &s(i->c_photoSize().vtype.c_string().v);
 				if (s.size()) size = s[0];
 			} break;
-				
+
 			case mtpc_photoCachedSize: {
 				const string &s(i->c_photoCachedSize().vtype.c_string().v);
 				if (s.size()) size = s[0];
@@ -1291,7 +1285,7 @@ namespace App {
 		}
 		return App::photoSet(photo.vid.v, convert, 0, 0, ImagePtr(), ImagePtr(), ImagePtr());
 	}
-	
+
 	VideoData *feedVideo(const MTPDvideo &video, VideoData *convert) {
 		return App::videoSet(video.vid.v, convert, video.vaccess_hash.v, video.vdate.v, video.vduration.v, video.vw.v, video.vh.v, App::image(video.vthumb), video.vdc_id.v, video.vsize.v);
 	}
@@ -1767,7 +1761,7 @@ namespace App {
 		}
 		return result;
 	}
-	
+
 	ImageLinkData *imageLink(const QString &imageLink) {
 		ImageLinksData::const_iterator i = imageLinksData.constFind(imageLink);
 		if (i == imageLinksData.cend()) {
@@ -1775,7 +1769,7 @@ namespace App {
 		}
 		return i.value();
 	}
-		
+
 	ImageLinkData *imageLinkSet(const QString &imageLink, ImageLinkType type, const QString &url) {
 		ImageLinksData::const_iterator i = imageLinksData.constFind(imageLink);
 		ImageLinkData *result;
@@ -1812,7 +1806,7 @@ namespace App {
 	MTPPhoto photoFromUserPhoto(MTPint userId, MTPint date, const MTPUserProfilePhoto &photo) {
 		if (photo.type() == mtpc_userProfilePhoto) {
 			const MTPDuserProfilePhoto &uphoto(photo.c_userProfilePhoto());
-				
+
 			QVector<MTPPhotoSize> photoSizes;
 			photoSizes.push_back(MTP_photoSize(MTP_string("a"), uphoto.vphoto_small, MTP_int(160), MTP_int(160), MTP_int(0)));
 			photoSizes.push_back(MTP_photoSize(MTP_string("c"), uphoto.vphoto_big, MTP_int(640), MTP_int(640), MTP_int(0)));
@@ -1837,7 +1831,7 @@ namespace App {
 	History *historyFromDialog(const PeerId &peer, int32 unreadCnt, int32 maxInboxRead) {
 		return ::histories.findOrInsert(peer, unreadCnt, maxInboxRead);
 	}
-	
+
 	History *historyLoaded(const PeerId &peer) {
 		return ::histories.find(peer);
 	}
@@ -2136,13 +2130,13 @@ namespace App {
 		prepareCorners(MessageOutCorners, st::msgRadius, st::msgOutBg, &st::msgOutShadow);
 		prepareCorners(MessageOutSelectedCorners, st::msgRadius, st::msgOutBgSelected, &st::msgOutShadowSelected);
 	}
-	
+
 	void clearHistories() {
 		textlnkOver(TextLinkPtr());
 		textlnkDown(TextLinkPtr());
 
 		histories().clear();
-	
+
 		clearStorageImages();
 		cSetServerBackgrounds(WallPapers());
 
@@ -2191,7 +2185,7 @@ namespace App {
 	HistoryItem *pressedItem() {
 		return ::pressedItem;
 	}
-	
+
 	void hoveredLinkItem(HistoryItem *item) {
 		::hoveredLinkItem = item;
 	}
@@ -2207,7 +2201,7 @@ namespace App {
 	HistoryItem *pressedLinkItem() {
 		return ::pressedLinkItem;
 	}
-	
+
 	void contextItem(HistoryItem *item) {
 		::contextItem = item;
 	}
@@ -2539,7 +2533,7 @@ namespace App {
 		case mtpc_replyKeyboardMarkup: {
 			const MTPDreplyKeyboardMarkup &d(markup.c_replyKeyboardMarkup());
 			data.flags = d.vflags.v;
-			
+
 			const QVector<MTPKeyboardButtonRow> &v(d.vrows.c_vector().v);
 			if (!v.isEmpty()) {
 				commands.reserve(v.size());
@@ -2630,7 +2624,7 @@ namespace App {
 		} else {
 			socket.setProxy(QNetworkProxy(QNetworkProxy::NoProxy));
 		}
-	}	
+	}
 
 	QImage **cornersMask() {
 		return ::cornersMask;
diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp
index fffad3986..0ccdfbf77 100644
--- a/Telegram/SourceFiles/dropdown.cpp
+++ b/Telegram/SourceFiles/dropdown.cpp
@@ -2769,7 +2769,7 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
 		if (_cache.isNull()) {
 			p.fillRect(myrtlrect(r.x() + r.width() - st::emojiScroll.width, r.y(), st::emojiScroll.width, e_scroll.height()), st::white->b);
 			if (_stickersShown && s_inner.showSectionIcons()) {
-				p.fillRect(r.left(), _iconsTop, r.width(), st::rbEmoji.height, st::emojiPanCategories->b);
+				p.fillRect(r.left(), _iconsTop, r.width(), st::rbEmoji.height, st::emojiPanCategories);
 				p.drawSpriteLeft(_iconsLeft + 7 * st::rbEmoji.width + st::rbEmojiRecent.imagePos.x(), _iconsTop + st::rbEmojiRecent.imagePos.y(), width(), st::stickersSettings);
 
 				if (!_icons.isEmpty()) {
@@ -2818,10 +2818,13 @@ void EmojiPan::paintEvent(QPaintEvent *e) {
 						p.drawSpriteRight(QRect(width() - _iconsLeft - 7 * st::rbEmoji.width, _iconsTop, st::stickerIconRight.pxWidth(), st::rbEmoji.height), width(), st::stickerIconRight);
 					}
 				}
-			} else {
-				p.fillRect(r.left(), _recent.y(), (rtl() ? _objects.x() : _recent.x() - r.left()), st::rbEmoji.height, st::emojiPanCategories->b);
+			} else if (_stickersShown) {
 				int32 x = rtl() ? (_recent.x() + _recent.width()) : (_objects.x() + _objects.width());
-				p.fillRect(x, _recent.y(), r.left() + r.width() - x, st::rbEmoji.height, st::emojiPanCategories->b);
+				p.fillRect(x, _recent.y(), r.left() + r.width() - x, st::rbEmoji.height, st::white);
+			} else {
+				p.fillRect(r.left(), _recent.y(), (rtl() ? _objects.x() : _recent.x() - r.left()), st::rbEmoji.height, st::emojiPanCategories);
+				int32 x = rtl() ? (_recent.x() + _recent.width()) : (_objects.x() + _objects.width());
+				p.fillRect(x, _recent.y(), r.left() + r.width() - x, st::rbEmoji.height, st::emojiPanCategories);
 			}
 		} else {
 			p.fillRect(r, st::white->b);
diff --git a/Telegram/SourceFiles/dropdown.h b/Telegram/SourceFiles/dropdown.h
index 9cbc0eb6b..9bbaf30ab 100644
--- a/Telegram/SourceFiles/dropdown.h
+++ b/Telegram/SourceFiles/dropdown.h
@@ -584,6 +584,9 @@ public:
 	bool ui_isInlineItemVisible(const LayoutInlineItem *layout);
 	bool ui_isInlineItemBeingChosen();
 
+	bool inlineResultsShown() const {
+		return s_inner.inlineResultsShown();
+	}
 	void notify_automaticLoadSettingsChangedGif();
 
 public slots:
diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp
index b315f26fb..4f4415bd8 100644
--- a/Telegram/SourceFiles/history.cpp
+++ b/Telegram/SourceFiles/history.cpp
@@ -382,25 +382,6 @@ bool History::updateTyping(uint64 ms, uint32 dots, bool force) {
 	return changed;
 }
 
-void History::eraseFromOverview(MediaOverviewType type, MsgId msgId) {
-	if (overviewIds[type].isEmpty()) return;
-
-	History::MediaOverviewIds::iterator i = overviewIds[type].find(msgId);
-	if (i == overviewIds[type].cend()) return;
-
-	overviewIds[type].erase(i);
-	for (History::MediaOverview::iterator i = overview[type].begin(), e = overview[type].end(); i != e; ++i) {
-		if ((*i) == msgId) {
-			overview[type].erase(i);
-			if (overviewCountData[type] > 0) {
-				--overviewCountData[type];
-			}
-			break;
-		}
-	}
-	if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, type);
-}
-
 ChannelHistory::ChannelHistory(const PeerId &peer) : History(peer),
 unreadCountAll(0),
 _onlyImportant(!isMegagroup()),
@@ -1684,24 +1665,47 @@ void History::createInitialDateBlock(const QDateTime &date) {
 	}
 }
 
-void History::addToOverview(HistoryItem *item, MediaOverviewType type) {
-	if (overviewIds[type].constFind(item->id) == overviewIds[type].cend()) {
-		overview[type].push_back(item->id);
-		overviewIds[type].insert(item->id, NullType());
+bool History::addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMethod method) {
+	bool adding = false;
+	switch (method) {
+	case AddToOverviewNew:
+	case AddToOverviewFront: adding = (overviewIds[type].constFind(msgId) == overviewIds[type].cend()); break;
+	case AddToOverviewBack: adding = (overviewCountData[type] != 0); break;
+	}
+	if (!adding) return false;
+
+	overviewIds[type].insert(msgId, NullType());
+	switch (method) {
+	case AddToOverviewNew:
+	case AddToOverviewBack: overview[type].push_back(msgId); break;
+	case AddToOverviewFront: overview[type].push_front(msgId); break;
+	}
+	if (method == AddToOverviewNew) {
 		if (overviewCountData[type] > 0) {
 			++overviewCountData[type];
 		}
 		if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, type);
 	}
+	return true;
 }
 
-bool History::addToOverviewFront(HistoryItem *item, MediaOverviewType type) {
-	if (overviewIds[type].constFind(item->id) == overviewIds[type].cend()) {
-		overview[type].push_front(item->id);
-		overviewIds[type].insert(item->id, NullType());
-		return true;
+void History::eraseFromOverview(MediaOverviewType type, MsgId msgId) {
+	if (overviewIds[type].isEmpty()) return;
+
+	History::MediaOverviewIds::iterator i = overviewIds[type].find(msgId);
+	if (i == overviewIds[type].cend()) return;
+
+	overviewIds[type].erase(i);
+	for (History::MediaOverview::iterator i = overview[type].begin(), e = overview[type].end(); i != e; ++i) {
+		if ((*i) == msgId) {
+			overview[type].erase(i);
+			if (overviewCountData[type] > 0) {
+				--overviewCountData[type];
+			}
+			break;
+		}
 	}
-	return false;
+	if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, type);
 }
 
 HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg) {
@@ -1739,23 +1743,7 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
 		newItemAdded(adding);
 	}
 
-	if (adding->indexInOverview()) {
-		HistoryMedia *media = adding->getMedia(true);
-		if (media) {
-			HistoryMediaType mt = media->type();
-			MediaOverviewType t = mediaToOverviewType(mt);
-			if (t != OverviewCount) {
-				if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->getDocument()->song()) {
-					addToOverview(adding, OverviewAudioDocuments);
-				} else {
-					addToOverview(adding, t);
-				}
-			}
-		}
-		if (adding->hasTextLinks()) {
-			addToOverview(adding, OverviewLinks);
-		}
-	}
+	adding->addToOverview(AddToOverviewNew);
 	if (adding->from()->id) {
 		if (adding->from()->isUser()) {
 			QList<UserData*> *lastAuthors = 0;
@@ -2008,23 +1996,7 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
 			}
 			for (int32 i = block->items.size(); i > 0; --i) {
 				HistoryItem *item = block->items[i - 1];
-				if (item->indexInOverview()) {
-					HistoryMedia *media = item->getMedia(true);
-					if (media) {
-						HistoryMediaType mt = media->type();
-						MediaOverviewType t = mediaToOverviewType(mt);
-						if (t != OverviewCount) {
-							if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->getDocument()->song()) {
-								if (addToOverviewFront(item, OverviewAudioDocuments)) mask |= (1 << OverviewAudioDocuments);
-							} else {
-								if (addToOverviewFront(item, t)) mask |= (1 << t);
-							}
-						}
-					}
-					if (item->hasTextLinks()) {
-						if (addToOverviewFront(item, OverviewLinks)) mask |= (1 << OverviewLinks);
-					}
-				}
+				mask |= item->addToOverview(AddToOverviewFront);
 				if (item->from()->id) {
 					if (lastAuthors) { // chats
 						if (item->from()->isUser()) {
@@ -2159,38 +2131,7 @@ void History::addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
 		for (int32 i = 0; i < blocks.size(); ++i) {
 			HistoryBlock *b = blocks[i];
 			for (int32 j = 0; j < b->items.size(); ++j) {
-				HistoryItem *item = b->items[j];
-				if (!item->indexInOverview()) continue;
-
-				HistoryMedia *media = item->getMedia(true);
-				if (media) {
-					HistoryMediaType mt = media->type();
-					MediaOverviewType t = mediaToOverviewType(mt);
-					if (t != OverviewCount) {
-						if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->getDocument()->song()) {
-							t = OverviewAudioDocuments;
-							if (overviewCountData[t] != 0) {
-								overview[t].push_back(item->id);
-								overviewIds[t].insert(item->id, NullType());
-								mask |= (1 << t);
-							}
-						} else {
-							if (overviewCountData[t] != 0) {
-								overview[t].push_back(item->id);
-								overviewIds[t].insert(item->id, NullType());
-								mask |= (1 << t);
-							}
-						}
-					}
-				}
-				if (item->hasTextLinks()) {
-					MediaOverviewType t = OverviewLinks;
-					if (overviewCountData[t] != 0) {
-						overview[t].push_back(item->id);
-						overviewIds[t].insert(item->id, NullType());
-						mask |= (1 << t);
-					}
-				}
+				mask |= b->items[j]->addToOverview(AddToOverviewBack);
 			}
 		}
 		for (int32 t = 0; t < OverviewCount; ++t) {
@@ -2941,18 +2882,6 @@ void HistoryItem::destroy() {
 		history()->clearLastKeyboard();
 		if (App::main()) App::main()->updateBotKeyboard(history());
 	}
-	HistoryMedia *m = getMedia(true);
-	MediaOverviewType t = m ? mediaToOverviewType(m->type()) : OverviewCount;
-	if (t != OverviewCount) {
-		if (m->type() == MediaTypeDocument && static_cast<HistoryDocument*>(m)->getDocument()->song()) {
-			history()->eraseFromOverview(OverviewAudioDocuments, id);
-		} else {
-			history()->eraseFromOverview(t, id);
-		}
-	}
-	if (hasTextLinks()) {
-		history()->eraseFromOverview(OverviewLinks, id);
-	}
 	delete this;
 }
 
@@ -6276,6 +6205,38 @@ void HistoryMessage::fromNameUpdated() const {
 	}
 }
 
+int32 HistoryMessage::addToOverview(AddToOverviewMethod method) {
+	if (!indexInOverview()) return 0;
+
+	int32 result = 0;
+	if (HistoryMedia *media = getMedia(true)) {
+		MediaOverviewType type = mediaToOverviewType(media);
+		if (type != OverviewCount) {
+			if (history()->addToOverview(type, id, method)) {
+				result |= (1 << type);
+			}
+		}
+	}
+	if (hasTextLinks()) {
+		if (history()->addToOverview(OverviewLinks, id, method)) {
+			result |= (1 << OverviewLinks);
+		}
+	}
+	return result;
+}
+
+void HistoryMessage::eraseFromOverview() {
+	if (HistoryMedia *media = getMedia(true)) {
+		MediaOverviewType type = mediaToOverviewType(media);
+		if (type != OverviewCount) {
+			history()->eraseFromOverview(type, id);
+		}
+	}
+	if (hasTextLinks()) {
+		history()->eraseFromOverview(OverviewLinks, id);
+	}
+}
+
 QString HistoryMessage::selectedText(uint32 selection) const {
 	if (_media && selection == FullSelection) {
 		QString text = _text.original(0, 0xFFFF, Text::ExpandLinksAll), mediaText = _media->inHistoryText();
@@ -6327,12 +6288,10 @@ void HistoryMessage::setText(const QString &text, const EntitiesInText &entities
 	}
 	textstyleRestore();
 
-	if (id > 0) {
-		for (int32 i = 0, l = entities.size(); i != l; ++i) {
-			if (entities.at(i).type == EntityInTextUrl || entities.at(i).type == EntityInTextCustomUrl || entities.at(i).type == EntityInTextEmail) {
-				_flags |= MTPDmessage_flag_HAS_TEXT_LINKS;
-				break;
-			}
+	for (int32 i = 0, l = entities.size(); i != l; ++i) {
+		if (entities.at(i).type == EntityInTextUrl || entities.at(i).type == EntityInTextCustomUrl || entities.at(i).type == EntityInTextEmail) {
+			_flags |= MTPDmessage_flag_HAS_TEXT_LINKS;
+			break;
 		}
 	}
 	_textWidth = 0;
@@ -6550,6 +6509,11 @@ void HistoryMessage::drawMessageText(Painter &p, QRect trect, uint32 selection)
 	_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignLeft, 0, -1, selectedFrom, selectedTo);
 }
 
+void HistoryMessage::destroy() {
+	eraseFromOverview();
+	HistoryItem::destroy();
+}
+
 int32 HistoryMessage::resize(int32 width) {
 	if (width < st::msgMinWidth) return _height;
 
diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h
index 5f8ef0fd2..326f63176 100644
--- a/Telegram/SourceFiles/history.h
+++ b/Telegram/SourceFiles/history.h
@@ -116,18 +116,6 @@ enum MediaOverviewType {
 	OverviewCount
 };
 
-inline MediaOverviewType mediaToOverviewType(HistoryMediaType t) {
-	switch (t) {
-	case MediaTypePhoto: return OverviewPhotos;
-	case MediaTypeVideo: return OverviewVideos;
-	case MediaTypeDocument: return OverviewDocuments;
-	case MediaTypeGif: return OverviewDocuments;
-//	case MediaTypeSticker: return OverviewDocuments;
-	case MediaTypeAudio: return OverviewAudios;
-	}
-	return OverviewCount;
-}
-
 inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
 	switch (type) {
 	case OverviewPhotos: return MTP_inputMessagesFilterPhotos();
@@ -164,6 +152,12 @@ class HistoryMedia;
 class HistoryMessage;
 class HistoryUnreadBar;
 
+enum AddToOverviewMethod {
+	AddToOverviewNew, // when new message is added to history
+	AddToOverviewFront, // when old messages slice was received
+	AddToOverviewBack, // when new messages slice was received and it is the last one, we index all media
+};
+
 class ChannelHistory;
 class History {
 public:
@@ -207,8 +201,8 @@ public:
 
 	void addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed);
 	void addNewerSlice(const QVector<MTPMessage> &slice, const QVector<MTPMessageGroup> *collapsed);
-	void addToOverview(HistoryItem *item, MediaOverviewType type);
-	bool addToOverviewFront(HistoryItem *item, MediaOverviewType type);
+	bool addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMethod method);
+	void eraseFromOverview(MediaOverviewType type, MsgId msgId);
 
 	void newItemAdded(HistoryItem *item);
 	void unregTyping(UserData *from);
@@ -270,7 +264,6 @@ public:
 	}
 
 	void paintDialog(Painter &p, int32 w, bool sel) const;
-	void eraseFromOverview(MediaOverviewType type, MsgId msgId);
 	bool updateTyping(uint64 ms = 0, uint32 dots = 0, bool force = false);
 	void clearLastKeyboard();
 
@@ -823,7 +816,7 @@ public:
 	const HistoryBlock *block() const {
 		return _block;
 	}
-	void destroy();
+	virtual void destroy();
 	void detach();
 	void detachFast();
 	bool detached() const {
@@ -873,7 +866,7 @@ public:
 		return _history->isChannel() && isImportantChannelMessage(id, _flags);
 	}
 	bool indexInOverview() const {
-		return (!history()->isChannel() || history()->isMegagroup() || fromChannel());
+		return (id > 0) && (!history()->isChannel() || history()->isMegagroup() || fromChannel());
 	}
 
 	virtual bool needCheck() const {
@@ -906,6 +899,9 @@ public:
 	}
 	virtual void updateMedia(const MTPMessageMedia *media, bool allowEmitResize) {
 	}
+	virtual int32 addToOverview(AddToOverviewMethod method) {
+		return 0;
+	}
 	virtual bool hasBubble() const {
 		return false;
 	}
@@ -1207,6 +1203,18 @@ protected:
 
 };
 
+inline MediaOverviewType mediaToOverviewType(HistoryMedia *media) {
+	switch (media->type()) {
+	case MediaTypePhoto: return OverviewPhotos;
+	case MediaTypeVideo: return OverviewVideos;
+	case MediaTypeDocument: return media->getDocument()->song() ? OverviewAudioDocuments : OverviewDocuments;
+	case MediaTypeGif: return media->getDocument()->isGifv() ? OverviewCount : OverviewDocuments;
+//	case MediaTypeSticker: return OverviewDocuments;
+	case MediaTypeAudio: return OverviewAudios;
+	}
+	return OverviewCount;
+}
+
 class HistoryFileMedia : public HistoryMedia {
 public:
 
@@ -2023,6 +2031,8 @@ public:
 
 	virtual void drawMessageText(Painter &p, QRect trect, uint32 selection) const;
 
+	void destroy();
+
 	int32 resize(int32 width);
 	bool hasPoint(int32 x, int32 y) const;
 	bool pointInTime(int32 right, int32 bottom, int32 x, int32 y, InfoDisplayType type) const;
@@ -2052,6 +2062,8 @@ public:
 			setMedia(media, allowEmitResize);
 		}
 	}
+	int32 addToOverview(AddToOverviewMethod method);
+	void eraseFromOverview();
 
 	QString selectedText(uint32 selection) const;
 	QString inDialogsText() const;
diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp
index 631c129ae..a635b3fa2 100644
--- a/Telegram/SourceFiles/historywidget.cpp
+++ b/Telegram/SourceFiles/historywidget.cpp
@@ -6277,7 +6277,8 @@ void HistoryWidget::keyPressEvent(QKeyEvent *e) {
 	if (e->key() == Qt::Key_Escape) {
 		e->ignore();
 	} else if (e->key() == Qt::Key_Back) {
-		onCancel();
+		Ui::showChatsList();
+		emit cancelled();
 	} else if (e->key() == Qt::Key_PageDown) {
 		if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::MetaModifier)) {
 			PeerData *after = 0;
@@ -6780,8 +6781,12 @@ void HistoryWidget::updatePreview() {
 }
 
 void HistoryWidget::onCancel() {
-	Ui::showChatsList();
-	emit cancelled();
+	if (_inlineBot && _field.getLastText().startsWith('@' + _inlineBot->username + ' ')) {
+		setFieldText(QString(), TextUpdateEventsSaveDraft, false);
+	} else {
+		Ui::showChatsList();
+		emit cancelled();
+	}
 }
 
 void HistoryWidget::onFullPeerUpdated(PeerData *data) {
diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp
index e73ed08df..28cf54a83 100644
--- a/Telegram/SourceFiles/mainwidget.cpp
+++ b/Telegram/SourceFiles/mainwidget.cpp
@@ -4128,18 +4128,12 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
 			if (peerId) {
 				if (HistoryItem *item = App::histItemById(peerToChannel(peerId), d.vid.v)) {
 					if (!text.isEmpty()) {
-						bool hasLinks = d.has_entities() && !d.ventities.c_vector().v.isEmpty();
-						if ((hasLinks && !item->hasTextLinks()) || (!hasLinks && item->textHasLinks())) {
-							item->setText(text, d.has_entities() ? entitiesFromMTP(d.ventities.c_vector().v) : EntitiesInText());
-							item->initDimensions();
-							Notify::historyItemResized(item);
-							if (item->hasTextLinks() && item->indexInOverview()) {
-								item->history()->addToOverview(item, OverviewLinks);
-							}
-						}
+						item->setText(text, d.has_entities() ? entitiesFromMTP(d.ventities.c_vector().v) : EntitiesInText());
+						item->initDimensions();
+						Notify::historyItemResized(item);
 					}
-
 					item->updateMedia(d.has_media() ? (&d.vmedia) : 0, true);
+					item->addToOverview(AddToOverviewNew);
 				}
 			}
 		}