From f48732f813868c85faa25fd8aba8d1fb0dedb08a Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Tue, 6 Aug 2019 15:54:44 +0100
Subject: [PATCH] Extract username from t.me/username searches.

---
 .../api/api_single_message_search.cpp          | 18 +++++++++++++++++-
 .../api/api_single_message_search.h            |  2 ++
 .../SourceFiles/core/local_url_handlers.cpp    |  4 ++--
 .../SourceFiles/dialogs/dialogs_widget.cpp     | 13 +++++++------
 4 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/Telegram/SourceFiles/api/api_single_message_search.cpp b/Telegram/SourceFiles/api/api_single_message_search.cpp
index d8ee6088e..fc9829b2b 100644
--- a/Telegram/SourceFiles/api/api_single_message_search.cpp
+++ b/Telegram/SourceFiles/api/api_single_message_search.cpp
@@ -23,7 +23,7 @@ using Key = details::SingleMessageSearchKey;
 
 Key ExtractKey(const QString &query) {
 	const auto trimmed = query.trimmed();
-	const auto local = Core::TryConvertUrlToLocal(query);
+	const auto local = Core::TryConvertUrlToLocal(trimmed);
 	const auto check = local.isEmpty() ? trimmed : local;
 	const auto parse = [&] {
 		const auto delimeter = check.indexOf('?');
@@ -216,4 +216,20 @@ std::optional<HistoryItem*> SingleMessageSearch::performLookup(
 	return performLookupById(channelId, ready);
 }
 
+QString ConvertPeerSearchQuery(const QString &query) {
+	const auto trimmed = query.trimmed();
+	const auto local = Core::TryConvertUrlToLocal(trimmed);
+	const auto check = local.isEmpty() ? trimmed : local;
+	if (!check.startsWith(qstr("tg://resolve"), Qt::CaseInsensitive)) {
+		return query;
+	}
+	const auto delimeter = check.indexOf('?');
+	const auto params = (delimeter > 0)
+		? qthelp::url_parse_params(
+			check.mid(delimeter + 1),
+			qthelp::UrlParamNameTransform::ToLower)
+		: QMap<QString, QString>();
+	return params.value("domain", query);
+}
+
 } // namespace Api
diff --git a/Telegram/SourceFiles/api/api_single_message_search.h b/Telegram/SourceFiles/api/api_single_message_search.h
index 28b8ec675..48194d3f1 100644
--- a/Telegram/SourceFiles/api/api_single_message_search.h
+++ b/Telegram/SourceFiles/api/api_single_message_search.h
@@ -71,4 +71,6 @@ private:
 
 };
 
+[[nodiscard]] QString ConvertPeerSearchQuery(const QString &query);
+
 } // namespace Api
diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp
index d1a7137da..e18c13473 100644
--- a/Telegram/SourceFiles/core/local_url_handlers.cpp
+++ b/Telegram/SourceFiles/core/local_url_handlers.cpp
@@ -408,9 +408,9 @@ QString TryConvertUrlToLocal(QString url) {
 
 	using namespace qthelp;
 	auto matchOptions = RegExOption::CaseInsensitive;
-	auto telegramMeMatch = regex_match(qsl("^https?://(www\\.)?(telegram\\.(me|dog)|t\\.me)/(.+)$"), url, matchOptions);
+	auto telegramMeMatch = regex_match(qsl("^(https?://)?(www\\.)?(telegram\\.(me|dog)|t\\.me)/(.+)$"), url, matchOptions);
 	if (telegramMeMatch) {
-		auto query = telegramMeMatch->capturedRef(4);
+		auto query = telegramMeMatch->capturedRef(5);
 		if (auto joinChatMatch = regex_match(qsl("^joinchat/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"), query, matchOptions)) {
 			return qsl("tg://join?invite=") + url_encode(joinChatMatch->captured(1));
 		} else if (auto stickerSetMatch = regex_match(qsl("^addstickers/([a-zA-Z0-9\\.\\_]+)(\\?|$)"), query, matchOptions)) {
diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
index b1a39c5b6..68797353e 100644
--- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
+++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp
@@ -812,17 +812,18 @@ bool Widget::onSearchMessages(bool searchCache) {
 		}
 		_searchQueries.insert(_searchRequest, _searchQuery);
 	}
-	if (searchForPeersRequired(q)) {
+	const auto query = Api::ConvertPeerSearchQuery(q);
+	if (searchForPeersRequired(query)) {
 		if (searchCache) {
-			auto i = _peerSearchCache.constFind(q);
+			auto i = _peerSearchCache.constFind(query);
 			if (i != _peerSearchCache.cend()) {
-				_peerSearchQuery = q;
+				_peerSearchQuery = query;
 				_peerSearchRequest = 0;
 				peerSearchReceived(i.value(), 0);
 				result = true;
 			}
-		} else if (_peerSearchQuery != q) {
-			_peerSearchQuery = q;
+		} else if (_peerSearchQuery != query) {
+			_peerSearchQuery = query;
 			_peerSearchFull = false;
 			_peerSearchRequest = MTP::send(
 				MTPcontacts_Search(
@@ -833,7 +834,7 @@ bool Widget::onSearchMessages(bool searchCache) {
 			_peerSearchQueries.insert(_peerSearchRequest, _peerSearchQuery);
 		}
 	} else {
-		_peerSearchQuery = q;
+		_peerSearchQuery = query;
 		_peerSearchFull = true;
 		peerSearchReceived(
 			MTP_contacts_found(