From f1307f70cec953c57b62acc6941347ee0713c26e Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Wed, 19 Oct 2016 17:33:28 +0300
Subject: [PATCH] Fixed history scroll state clearing in case bot info was
 shown.

---
 Telegram/Resources/basic.style             |  1 -
 Telegram/SourceFiles/history/history.style |  2 +
 Telegram/SourceFiles/historywidget.cpp     | 52 ++++++++++------------
 Telegram/SourceFiles/historywidget.h       |  2 +-
 4 files changed, 26 insertions(+), 31 deletions(-)

diff --git a/Telegram/Resources/basic.style b/Telegram/Resources/basic.style
index a2aee4a99..67e166752 100644
--- a/Telegram/Resources/basic.style
+++ b/Telegram/Resources/basic.style
@@ -960,7 +960,6 @@ msgDateImgPadding: point(8px, 2px);
 msgDateImgCheckSpace: 4px;
 
 msgDogImg: sprite(216px, 92px, 126px, 126px);
-historyPadding: 10px;
 
 collapseButton: flatButton(btnDefFlat) {
 	font: msgServiceFont;
diff --git a/Telegram/SourceFiles/history/history.style b/Telegram/SourceFiles/history/history.style
index c81d899f4..d09ad184b 100644
--- a/Telegram/SourceFiles/history/history.style
+++ b/Telegram/SourceFiles/history/history.style
@@ -21,6 +21,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
 using "basic.style";
 using "dialogs/dialogs.style";
 
+historyPaddingBottom: 10px;
+
 historyToDown: icon {
 	{ "history_down_shadow", #00000040 },
 	{ "history_down_circle", #fff, point(2px, 1px) },
diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp
index b914f3847..863993545 100644
--- a/Telegram/SourceFiles/historywidget.cpp
+++ b/Telegram/SourceFiles/historywidget.cpp
@@ -1512,14 +1512,11 @@ void HistoryInner::keyPressEvent(QKeyEvent *e) {
 }
 
 void HistoryInner::recountHeight() {
-	int htop = historyTop(), mtop = migratedTop();
-
-	int ph = _scroll->height(), minadd = 0;
-	int wasYSkip = ph - historyHeight() - st::historyPadding;
+	int visibleHeight = _scroll->height();
+	int oldHistoryPaddingTop = qMax(visibleHeight - historyHeight() - st::historyPaddingBottom, 0);
 	if (_botAbout && !_botAbout->info->text.isEmpty()) {
-		minadd = st::msgMargin.top() + st::msgMargin.bottom() + st::msgPadding.top() + st::msgPadding.bottom() + st::msgNameFont->height + st::botDescSkip + _botAbout->height;
+		accumulate_max(oldHistoryPaddingTop, st::msgMargin.top() + st::msgMargin.bottom() + st::msgPadding.top() + st::msgPadding.bottom() + st::msgNameFont->height + st::botDescSkip + _botAbout->height);
 	}
-	if (wasYSkip < minadd) wasYSkip = minadd;
 
 	_history->resizeGetHeight(_scroll->width());
 	if (_migrated) {
@@ -1559,7 +1556,7 @@ void HistoryInner::recountHeight() {
 			descMaxWidth = qMin(descMaxWidth, int32(st::msgMaxWidth + 2 * st::msgPhotoSkip + 2 * st::msgMargin.left()));
 		}
 		int32 descAtX = (descMaxWidth - _botAbout->width) / 2 - st::msgPadding.left();
-		int32 descAtY = qMin(_historyOffset - descH, qMax(0, (_scroll->height() - descH) / 2)) + st::msgMargin.top();
+		int32 descAtY = qMin(_historyPaddingTop - descH, qMax(0, (_scroll->height() - descH) / 2)) + st::msgMargin.top();
 
 		_botAbout->rect = QRect(descAtX, descAtY, _botAbout->width + st::msgPadding.left() + st::msgPadding.right(), descH - st::msgMargin.top() - st::msgMargin.bottom());
 	} else if (_botAbout) {
@@ -1567,17 +1564,17 @@ void HistoryInner::recountHeight() {
 		_botAbout->rect = QRect();
 	}
 
-	int32 newYSkip = ph - historyHeight() - st::historyPadding;
+	int newHistoryPaddingTop = qMax(visibleHeight - historyHeight() - st::historyPaddingBottom, 0);
 	if (_botAbout && !_botAbout->info->text.isEmpty()) {
-		minadd = st::msgMargin.top() + st::msgMargin.bottom() + st::msgPadding.top() + st::msgPadding.bottom() + st::msgNameFont->height + st::botDescSkip + _botAbout->height;
+		accumulate_max(newHistoryPaddingTop, st::msgMargin.top() + st::msgMargin.bottom() + st::msgPadding.top() + st::msgPadding.bottom() + st::msgNameFont->height + st::botDescSkip + _botAbout->height);
 	}
-	if (newYSkip < minadd) newYSkip = minadd;
 
-	if (newYSkip != wasYSkip) {
+	auto historyPaddingTopDelta = (newHistoryPaddingTop - oldHistoryPaddingTop);
+	if (historyPaddingTopDelta != 0) {
 		if (_history->scrollTopItem) {
-			_history->scrollTopOffset += (newYSkip - wasYSkip);
+			_history->scrollTopOffset += historyPaddingTopDelta;
 		} else if (_migrated && _migrated->scrollTopItem) {
-			_migrated->scrollTopOffset += (newYSkip - wasYSkip);
+			_migrated->scrollTopOffset += historyPaddingTopDelta;
 		}
 	}
 }
@@ -1609,7 +1606,7 @@ void HistoryInner::updateBotInfo(bool recount) {
 		if (_botAbout->height > 0) {
 			int32 descH = st::msgMargin.top() + st::msgPadding.top() + st::msgNameFont->height + st::botDescSkip + _botAbout->height + st::msgPadding.bottom() + st::msgMargin.bottom();
 			int32 descAtX = (_scroll->width() - _botAbout->width) / 2 - st::msgPadding.left();
-			int32 descAtY = qMin(_historyOffset - descH, (_scroll->height() - descH) / 2) + st::msgMargin.top();
+			int32 descAtY = qMin(_historyPaddingTop - descH, (_scroll->height() - descH) / 2) + st::msgMargin.top();
 
 			_botAbout->rect = QRect(descAtX, descAtY, _botAbout->width + st::msgPadding.left() + st::msgPadding.right(), descH - st::msgMargin.top() - st::msgMargin.bottom());
 		} else {
@@ -1637,7 +1634,7 @@ void HistoryInner::visibleAreaUpdated(int top, int bottom) {
 		return;
 	}
 
-	if (bottom >= historyHeight()) {
+	if (bottom >= _historyPaddingTop + historyHeight() + st::historyPaddingBottom) {
 		_history->forgetScrollState();
 		if (_migrated) {
 			_migrated->forgetScrollState();
@@ -1712,12 +1709,11 @@ void HistoryInner::repaintScrollDateCallback() {
 }
 
 void HistoryInner::updateSize() {
-	int32 ph = _scroll->height(), minadd = 0;
-	int32 newYSkip = ph - historyHeight() - st::historyPadding;
+	int visibleHeight = _scroll->height();
+	int newHistoryPaddingTop = qMax(visibleHeight - historyHeight() - st::historyPaddingBottom, 0);
 	if (_botAbout && !_botAbout->info->text.isEmpty()) {
-		minadd = st::msgMargin.top() + st::msgMargin.bottom() + st::msgPadding.top() + st::msgPadding.bottom() + st::msgNameFont->height + st::botDescSkip + _botAbout->height;
+		accumulate_max(newHistoryPaddingTop, st::msgMargin.top() + st::msgMargin.bottom() + st::msgPadding.top() + st::msgPadding.bottom() + st::msgNameFont->height + st::botDescSkip + _botAbout->height);
 	}
-	if (newYSkip < minadd) newYSkip = minadd;
 
 	if (_botAbout && _botAbout->height > 0) {
 		int32 descH = st::msgMargin.top() + st::msgPadding.top() + st::msgNameFont->height + st::botDescSkip + _botAbout->height + st::msgPadding.bottom() + st::msgMargin.bottom();
@@ -1726,17 +1722,16 @@ void HistoryInner::updateSize() {
 			descMaxWidth = qMin(descMaxWidth, int32(st::msgMaxWidth + 2 * st::msgPhotoSkip + 2 * st::msgMargin.left()));
 		}
 		int32 descAtX = (descMaxWidth - _botAbout->width) / 2 - st::msgPadding.left();
-		int32 descAtY = qMin(newYSkip - descH, qMax(0, (_scroll->height() - descH) / 2)) + st::msgMargin.top();
+		int32 descAtY = qMin(newHistoryPaddingTop - descH, qMax(0, (_scroll->height() - descH) / 2)) + st::msgMargin.top();
 
 		_botAbout->rect = QRect(descAtX, descAtY, _botAbout->width + st::msgPadding.left() + st::msgPadding.right(), descH - st::msgMargin.top() - st::msgMargin.bottom());
 	}
 
-	int32 yAdded = newYSkip - _historyOffset;
-	_historyOffset = newYSkip;
+	_historyPaddingTop = newHistoryPaddingTop;
 
-	int32 nh = _historyOffset + historyHeight() + st::historyPadding;
-	if (width() != _scroll->width() || height() != nh) {
-		resize(_scroll->width(), nh);
+	int newHeight = _historyPaddingTop + historyHeight() + st::historyPaddingBottom;
+	if (width() != _scroll->width() || height() != newHeight) {
+		resize(_scroll->width(), newHeight);
 
 		dragActionUpdate(QCursor::pos());
 	} else {
@@ -1952,7 +1947,7 @@ void HistoryInner::onUpdateSelected() {
 	HistoryTextState dragState;
 	ClickHandlerHost *lnkhost = nullptr;
 	bool selectingText = (item == _dragItem && item == App::hoveredItem() && !_selected.isEmpty() && _selected.cbegin().value() != FullSelection);
-	if (point.y() < _historyOffset) {
+	if (point.y() < _historyPaddingTop) {
 		if (_botAbout && !_botAbout->info->text.isEmpty() && _botAbout->height > 0) {
 			dragState = _botAbout->info->text.getState(point.x() - _botAbout->rect.left() - st::msgPadding.left(), point.y() - _botAbout->rect.top() - st::msgPadding.top() - st::botDescSkip - st::msgNameFont->height, _botAbout->width);
 			lnkhost = _botAbout.get();
@@ -2143,12 +2138,12 @@ int HistoryInner::historyScrollTop() const {
 }
 
 int HistoryInner::migratedTop() const {
-	return (_migrated && !_migrated->isEmpty()) ? _historyOffset : -1;
+	return (_migrated && !_migrated->isEmpty()) ? _historyPaddingTop : -1;
 }
 
 int HistoryInner::historyTop() const {
 	int mig = migratedTop();
-	return (_history && !_history->isEmpty()) ? (mig >= 0 ? (mig + _migrated->height - _historySkipHeight) : _historyOffset) : -1;
+	return (_history && !_history->isEmpty()) ? (mig >= 0 ? (mig + _migrated->height - _historySkipHeight) : _historyPaddingTop) : -1;
 }
 
 int HistoryInner::historyDrawTop() const {
@@ -7263,7 +7258,6 @@ int HistoryWidget::unreadBarTop() const {
 }
 
 void HistoryWidget::addMessagesToFront(PeerData *peer, const QVector<MTPMessage> &messages) {
-	int oldH = _list->historyHeight();
 	_list->messagesReceived(peer, messages);
 	if (!_firstLoadRequest) {
 		updateListSize();
diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h
index b2a364c2b..2a5532db5 100644
--- a/Telegram/SourceFiles/historywidget.h
+++ b/Telegram/SourceFiles/historywidget.h
@@ -168,7 +168,7 @@ private:
 	PeerData *_peer = nullptr;
 	History *_migrated = nullptr;
 	History *_history = nullptr;
-	int _historyOffset = 0;
+	int _historyPaddingTop = 0;
 
 	// with migrated history we perhaps do not need to display first _history message
 	// (if last _migrated message and first _history message are both isGroupMigrate)