From 87cb0ada98282dd6ca1171a442f49a82081a1318 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Mon, 17 Jun 2019 15:29:07 +0200
Subject: [PATCH] Allow skipping archive results in messages search.

---
 Telegram/Resources/langs/lang.strings         |  2 ++
 Telegram/SourceFiles/auth_session.cpp         | 30 +++++++++++++++----
 Telegram/SourceFiles/auth_session.h           | 13 +++++---
 .../dialogs/dialogs_inner_widget.cpp          | 26 +++++++++++++---
 .../dialogs/dialogs_inner_widget.h            |  1 +
 .../SourceFiles/dialogs/dialogs_widget.cpp    | 27 +++++++++++++----
 Telegram/SourceFiles/dialogs/dialogs_widget.h |  1 +
 7 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index c9ae3ad7c3..43ca940d26 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -1252,6 +1252,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "lng_dialogs_text_media_wrapped" = "{media},";
 "lng_dialogs_show_all_chats" = "Show all chats";
 "lng_dialogs_hide_muted_chats" = "Hide muted chats";
+"lng_dialogs_skip_archive_in_search" = "Skip results from archive";
+"lng_dialogs_show_archive_in_search" = "With results from archive";
 
 "lng_open_this_link" = "Open this link?";
 "lng_open_link" = "Open";
diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp
index 0359ef8267..70b67faec6 100644
--- a/Telegram/SourceFiles/auth_session.cpp
+++ b/Telegram/SourceFiles/auth_session.cpp
@@ -97,6 +97,7 @@ QByteArray AuthSessionSettings::serialize() const {
 		stream << qint32(_variables.archiveCollapsed.current() ? 1 : 0);
 		stream << qint32(_variables.notifyAboutPinned.current() ? 1 : 0);
 		stream << qint32(_variables.archiveInMainMenu.current() ? 1 : 0);
+		stream << qint32(_variables.skipArchiveInSearch.current() ? 1 : 0);
 	}
 	return result;
 }
@@ -136,6 +137,7 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
 	qint32 archiveCollapsed = _variables.archiveCollapsed.current() ? 1 : 0;
 	qint32 notifyAboutPinned = _variables.notifyAboutPinned.current() ? 1 : 0;
 	qint32 archiveInMainMenu = _variables.archiveInMainMenu.current() ? 1 : 0;
+	qint32 skipArchiveInSearch = _variables.skipArchiveInSearch.current() ? 1 : 0;
 
 	stream >> selectorTab;
 	stream >> lastSeenWarningSeen;
@@ -224,6 +226,9 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
 	if (!stream.atEnd()) {
 		stream >> archiveInMainMenu;
 	}
+	if (!stream.atEnd()) {
+		stream >> skipArchiveInSearch;
+	}
 	if (stream.status() != QDataStream::Ok) {
 		LOG(("App Error: "
 			"Bad data for AuthSessionSettings::constructFromSerialized()"));
@@ -296,6 +301,7 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized)
 	_variables.archiveCollapsed = (archiveCollapsed == 1);
 	_variables.notifyAboutPinned = (notifyAboutPinned == 1);
 	_variables.archiveInMainMenu = (archiveInMainMenu == 1);
+	_variables.skipArchiveInSearch = (skipArchiveInSearch == 1);
 }
 
 void AuthSessionSettings::setSupportChatsTimeSlice(int slice) {
@@ -402,6 +408,18 @@ rpl::producer<bool> AuthSessionSettings::archiveCollapsedChanges() const {
 	return _variables.archiveCollapsed.changes();
 }
 
+void AuthSessionSettings::setArchiveInMainMenu(bool inMainMenu) {
+	_variables.archiveInMainMenu = inMainMenu;
+}
+
+bool AuthSessionSettings::archiveInMainMenu() const {
+	return _variables.archiveInMainMenu.current();
+}
+
+rpl::producer<bool> AuthSessionSettings::archiveInMainMenuChanges() const {
+	return _variables.archiveInMainMenu.changes();
+}
+
 void AuthSessionSettings::setNotifyAboutPinned(bool notify) {
 	_variables.notifyAboutPinned = notify;
 }
@@ -414,16 +432,16 @@ rpl::producer<bool> AuthSessionSettings::notifyAboutPinnedChanges() const {
 	return _variables.notifyAboutPinned.changes();
 }
 
-void AuthSessionSettings::setArchiveInMainMenu(bool inMainMenu) {
-	_variables.archiveInMainMenu = inMainMenu;
+void AuthSessionSettings::setSkipArchiveInSearch(bool skip) {
+	_variables.skipArchiveInSearch = skip;
 }
 
-bool AuthSessionSettings::archiveInMainMenu() const {
-	return _variables.archiveInMainMenu.current();
+bool AuthSessionSettings::skipArchiveInSearch() const {
+	return _variables.skipArchiveInSearch.current();
 }
 
-rpl::producer<bool> AuthSessionSettings::archiveInMainMenuChanges() const {
-	return _variables.archiveInMainMenu.changes();
+rpl::producer<bool> AuthSessionSettings::skipArchiveInSearchChanges() const {
+	return _variables.skipArchiveInSearch.changes();
 }
 
 AuthSession &Auth() {
diff --git a/Telegram/SourceFiles/auth_session.h b/Telegram/SourceFiles/auth_session.h
index f91bad6d15..76557acc89 100644
--- a/Telegram/SourceFiles/auth_session.h
+++ b/Telegram/SourceFiles/auth_session.h
@@ -196,13 +196,17 @@ public:
 	bool archiveCollapsed() const;
 	rpl::producer<bool> archiveCollapsedChanges() const;
 
+	void setArchiveInMainMenu(bool inMainMenu);
+	bool archiveInMainMenu() const;
+	rpl::producer<bool> archiveInMainMenuChanges() const;
+
 	void setNotifyAboutPinned(bool notify);
 	bool notifyAboutPinned() const;
 	rpl::producer<bool> notifyAboutPinnedChanges() const;
 
-	void setArchiveInMainMenu(bool inMainMenu);
-	bool archiveInMainMenu() const;
-	rpl::producer<bool> archiveInMainMenuChanges() const;
+	void setSkipArchiveInSearch(bool skip);
+	bool skipArchiveInSearch() const;
+	rpl::producer<bool> skipArchiveInSearchChanges() const;
 
 	bool hadLegacyCallsPeerToPeerNobody() const {
 		return _variables.hadLegacyCallsPeerToPeerNobody;
@@ -257,8 +261,9 @@ private:
 		bool exeLaunchWarning = true;
 		Data::AutoDownload::Full autoDownload;
 		rpl::variable<bool> archiveCollapsed = false;
-		rpl::variable<bool> notifyAboutPinned = true;
 		rpl::variable<bool> archiveInMainMenu = false;
+		rpl::variable<bool> notifyAboutPinned = true;
+		rpl::variable<bool> skipArchiveInSearch = false;
 
 		static constexpr auto kDefaultSupportChatsLimitSlice
 			= 7 * 24 * 60 * 60;
diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
index a9e2c10107..bf75cb932f 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp
@@ -1693,6 +1693,21 @@ void InnerWidget::fillSupportSearchMenu(not_null<Ui::PopupMenu*> menu) {
 	});
 }
 
+void InnerWidget::fillArchiveSearchMenu(not_null<Ui::PopupMenu*> menu) {
+	const auto folder = session().data().folderLoaded(Data::Folder::kId);
+	if (!folder || !folder->chatsListSize() || _searchInChat) {
+		return;
+	}
+	const auto skip = session().settings().skipArchiveInSearch();
+	const auto text = lang(skip
+		? lng_dialogs_show_archive_in_search
+		: lng_dialogs_skip_archive_in_search);
+	menu->addAction(text, [=] {
+		session().settings().setSkipArchiveInSearch(!skip);
+		session().saveSettingsDelayed();
+	});
+}
+
 void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
 	_menu = nullptr;
 
@@ -1712,8 +1727,7 @@ void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
 		} else if (_state == WidgetState::Filtered) {
 			if (base::in_range(_filteredSelected, 0, _filterResults.size())) {
 				return { _filterResults[_filteredSelected]->key(), FullMsgId() };
-			} else if (session().supportMode()
-				&& base::in_range(_searchedSelected, 0, _searchResults.size())) {
+			} else if (base::in_range(_searchedSelected, 0, _searchResults.size())) {
 				return {
 					_searchResults[_searchedSelected]->item()->history(),
 					_searchResults[_searchedSelected]->item()->fullId()
@@ -1730,8 +1744,12 @@ void InnerWidget::contextMenuEvent(QContextMenuEvent *e) {
 	}
 
 	_menu = base::make_unique_q<Ui::PopupMenu>(this);
-	if (session().supportMode() && row.fullId) {
-		fillSupportSearchMenu(_menu.get());
+	if (row.fullId) {
+		if (session().supportMode()) {
+			fillSupportSearchMenu(_menu.get());
+		} else {
+			fillArchiveSearchMenu(_menu.get());
+		}
 	} else if (const auto history = row.key.history()) {
 		Window::FillPeerMenu(
 			_controller,
diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h
index 9ed9ade439..40bcd2826f 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h
+++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h
@@ -240,6 +240,7 @@ private:
 		QRect updateRect = QRect(),
 		UpdateRowSections sections = UpdateRowSection::All);
 	void fillSupportSearchMenu(not_null<Ui::PopupMenu*> menu);
+	void fillArchiveSearchMenu(not_null<Ui::PopupMenu*> menu);
 
 	int dialogsOffset() const;
 	int fixedOnTopCount() const;
diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
index 44d5dc475f..0d42c454be 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
@@ -176,6 +176,9 @@ Widget::Widget(
 		refreshLoadMoreButton(mayBlock, isBlocked);
 	}, lifetime());
 
+	fullSearchRefreshOn(session().settings().skipArchiveInSearchChanges(
+	) | rpl::map([] { return rpl::empty_value(); }));
+
 	connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int)));
 	connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int)));
 	connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int)));
@@ -365,7 +368,13 @@ void Widget::setupSupportMode() {
 		return;
 	}
 
-	session().settings().supportAllSearchResultsValue(
+	fullSearchRefreshOn(session().settings().supportAllSearchResultsValue(
+	) | rpl::map([] { return rpl::empty_value(); }));
+}
+
+void Widget::fullSearchRefreshOn(rpl::producer<> events) {
+	std::move(
+		events
 	) | rpl::filter([=] {
 		return !_searchQuery.isEmpty();
 	}) | rpl::start_with_next([=] {
@@ -777,10 +786,14 @@ bool Widget::onSearchMessages(bool searchCache) {
 		//		rpcDone(&Widget::searchReceived, SearchRequestType::FromStart),
 		//		rpcFail(&Widget::searchFailed, SearchRequestType::FromStart));
 		} else {
+			const auto flags = session().settings().skipArchiveInSearch()
+				? MTPmessages_SearchGlobal::Flag::f_folder_id
+				: MTPmessages_SearchGlobal::Flag(0);
+			const auto folderId = 0;
 			_searchRequest = MTP::send(
 				MTPmessages_SearchGlobal(
-					MTP_flags(0),
-					MTP_int(0), // folder_id
+					MTP_flags(flags),
+					MTP_int(folderId),
 					MTP_string(_searchQuery),
 					MTP_int(0),
 					MTP_inputPeerEmpty(),
@@ -916,10 +929,14 @@ void Widget::onSearchMore() {
 			//		rpcDone(&Widget::searchReceived, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart),
 			//		rpcFail(&Widget::searchFailed, offsetId ? SearchRequestType::FromOffset : SearchRequestType::FromStart));
 			} else {
+				const auto flags = session().settings().skipArchiveInSearch()
+					? MTPmessages_SearchGlobal::Flag::f_folder_id
+					: MTPmessages_SearchGlobal::Flag(0);
+				const auto folderId = 0;
 				_searchRequest = MTP::send(
 					MTPmessages_SearchGlobal(
-						MTP_flags(0),
-						MTP_int(0), // folder_id
+						MTP_flags(flags),
+						MTP_int(folderId),
 						MTP_string(_searchQuery),
 						MTP_int(_searchNextRate),
 						offsetPeer
diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.h b/Telegram/SourceFiles/dialogs/dialogs_widget.h
index 0d4da4fa8c..a04240214e 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_widget.h
+++ b/Telegram/SourceFiles/dialogs/dialogs_widget.h
@@ -153,6 +153,7 @@ private:
 	QPixmap grabForFolderSlideAnimation();
 	void startSlideAnimation();
 
+	void fullSearchRefreshOn(rpl::producer<> events);
 	void applyFilterUpdate(bool force = false);
 	void refreshLoadMoreButton(bool mayBlock, bool isBlocked);
 	void loadMoreBlockedByDate();