From 41873412e7407ece5a527f89817451a42cbe10aa Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Fri, 17 Nov 2017 11:33:20 +0400
Subject: [PATCH] Fix crash and improve info navigation.

---
 .../SourceFiles/info/info_wrap_widget.cpp     | 45 ++++++++++++++-----
 Telegram/SourceFiles/info/info_wrap_widget.h  |  4 +-
 2 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp
index 2733cc08d..5466c3e34 100644
--- a/Telegram/SourceFiles/info/info_wrap_widget.cpp
+++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp
@@ -93,8 +93,6 @@ void WrapWidget::restoreHistoryStack(
 	Expects(!stack.empty());
 	Expects(!hasStackHistory());
 
-	startInjectingActivePeerProfiles();
-
 	auto content = std::move(stack.back());
 	stack.pop_back();
 	if (!stack.empty()) {
@@ -105,6 +103,9 @@ void WrapWidget::restoreHistoryStack(
 			_historyStack.push_back(std::move(item));
 		}
 	}
+
+	startInjectingActivePeerProfiles();
+
 	showNewContent(content.get());
 }
 
@@ -136,15 +137,13 @@ void WrapWidget::injectActivePeerProfile(not_null<PeerData*> peer) {
 		_historyStack.insert(
 			_historyStack.begin(),
 			std::move(injected));
-		afterStackHistoryInject();
+		if (_content) {
+			setupTop();
+			finishShowContent();
+		}
 	}
 }
 
-void WrapWidget::afterStackHistoryInject() {
-	setupTop();
-	finishShowContent();
-}
-
 std::unique_ptr<Controller> WrapWidget::createController(
 		not_null<Window::Controller*> window,
 		not_null<ContentMemento*> memento) {
@@ -685,8 +684,7 @@ bool WrapWidget::showInternal(
 		auto content = infoMemento->content();
 		auto skipInternal = hasStackHistory()
 			&& (params.way == Window::SectionShow::Way::ClearStack);
-		if (_controller->validateMementoPeer(content)
-			&& infoMemento->stackSize() == 1) {
+		if (_controller->validateMementoPeer(content)) {
 			if (!skipInternal && _content->showInternal(content)) {
 				highlightTopBar();
 				return true;
@@ -711,6 +709,14 @@ bool WrapWidget::showInternal(
 			//	}
 			}
 		}
+
+		// If we're in a nested section and we're asked to show
+		// a chat profile that is at the bottom of the stack we'll
+		// just go back in the stack all the way instead of pushing.
+		if (returnToFirstStackFrame(content, params)) {
+			return true;
+		}
+
 		showNewContent(
 			content,
 			params);
@@ -750,6 +756,25 @@ QRect WrapWidget::contentGeometry() const {
 	return rect().marginsRemoved({ 0, topWidget()->height(), 0, 0 });
 }
 
+
+bool WrapWidget::returnToFirstStackFrame(
+		not_null<ContentMemento*> memento,
+		const Window::SectionShow &params) {
+	if (!hasStackHistory()) {
+		return false;
+	}
+	auto firstPeerId = _historyStack.front().section->peerId();
+	auto firstSection = _historyStack.front().section->section();
+	if (firstPeerId == memento->peerId()
+		&& firstSection.type() == memento->section().type()
+		&& firstSection.type() == Section::Type::Profile) {
+		_historyStack.resize(1);
+		showBackFromStack();
+		return true;
+	}
+	return false;
+}
+
 void WrapWidget::showNewContent(
 		not_null<ContentMemento*> memento,
 		const Window::SectionShow &params) {
diff --git a/Telegram/SourceFiles/info/info_wrap_widget.h b/Telegram/SourceFiles/info/info_wrap_widget.h
index 7cc95d7b8..574b12b4b 100644
--- a/Telegram/SourceFiles/info/info_wrap_widget.h
+++ b/Telegram/SourceFiles/info/info_wrap_widget.h
@@ -146,7 +146,6 @@ private:
 	struct StackItem;
 
 	void startInjectingActivePeerProfiles();
-	void afterStackHistoryInject();
 	void injectActivePeerProfile(not_null<PeerData*> peer);
 	void restoreHistoryStack(
 		std::vector<std::unique_ptr<ContentMemento>> stack);
@@ -158,6 +157,9 @@ private:
 	void showNewContent(
 		not_null<ContentMemento*> memento,
 		const Window::SectionShow &params);
+	bool returnToFirstStackFrame(
+		not_null<ContentMemento*> memento,
+		const Window::SectionShow &params);
 	void setupTop();
 	//void setupTabbedTop();
 	//void setupTabs(Tab tab);