From e2bff474db72e0c16b9476e5e9720ca68bccac02 Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Mon, 30 Dec 2024 21:20:38 +0400
Subject: [PATCH] Show upgraded gift from old "View" button.

---
 Telegram/SourceFiles/data/data_media_types.h  |   1 +
 Telegram/SourceFiles/history/history_item.cpp |   1 +
 .../view/media/history_view_premium_gift.cpp  | 114 +++++++++++++-----
 3 files changed, 83 insertions(+), 33 deletions(-)

diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h
index c2cd05699..83bdcd1e2 100644
--- a/Telegram/SourceFiles/data/data_media_types.h
+++ b/Telegram/SourceFiles/data/data_media_types.h
@@ -142,6 +142,7 @@ struct GiftCode {
 	TextWithEntities message;
 	ChannelData *channel = nullptr;
 	MsgId giveawayMsgId = 0;
+	MsgId upgradeMsgId = 0;
 	int starsConverted = 0;
 	int starsToUpgrade = 0;
 	int starsUpgradedBySender = 0;
diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp
index 4ad4081c9..c8f57334f 100644
--- a/Telegram/SourceFiles/history/history_item.cpp
+++ b/Telegram/SourceFiles/history/history_item.cpp
@@ -5661,6 +5661,7 @@ void HistoryItem::applyAction(const MTPMessageAction &action) {
 						data.vmessage()->data().ventities().v),
 				}
 				: TextWithEntities()),
+			.upgradeMsgId = data.vupgrade_msg_id().value_or_empty(),
 			.starsConverted = int(data.vconvert_stars().value_or_empty()),
 			.starsUpgradedBySender = int(
 				data.vupgrade_stars().value_or_empty()),
diff --git a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp
index f3a1d0fd2..cd0f28494 100644
--- a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp
+++ b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp
@@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 */
 #include "history/view/media/history_view_premium_gift.h"
 
+#include "apiwrap.h"
+#include "api/api_premium.h"
 #include "base/unixtime.h"
 #include "boxes/gift_premium_box.h" // ResolveGiftCode
 #include "chat_helpers/stickers_gift_box_pack.h"
@@ -177,44 +179,90 @@ ClickHandlerPtr PremiumGift::createViewLink() {
 	const auto peer = _parent->history()->peer;
 	const auto date = _parent->data()->date();
 	const auto data = *_gift->gift();
-	return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
-		const auto my = context.other.value<ClickHandlerContext>();
-		if (const auto controller = my.sessionWindow.get()) {
-			const auto selfId = controller->session().userPeerId();
-			const auto sent = (from->id == selfId);
-			if (starGift()) {
-				const auto item = controller->session().data().message(itemId);
-				if (item) {
-					controller->show(Box(
-						Settings::StarGiftViewBox,
-						controller,
-						data,
-						item));
-				}
-			} else if (creditsPrize()) {
+	const auto showForWeakWindow = [=](
+			base::weak_ptr<Window::SessionController> weak) {
+		const auto controller = weak.get();
+		if (!controller) {
+			return;
+		}
+		const auto selfId = controller->session().userPeerId();
+		const auto sent = (from->id == selfId);
+		if (starGift()) {
+			const auto item = controller->session().data().message(itemId);
+			if (item) {
 				controller->show(Box(
-					Settings::CreditsPrizeBox,
+					Settings::StarGiftViewBox,
 					controller,
 					data,
-					date));
-			} else if (data.type == Data::GiftType::Credits) {
-				const auto to = sent ? peer : peer->session().user();
-				controller->show(Box(
-					Settings::GiftedCreditsBox,
-					controller,
-					from,
-					to,
-					data.count,
-					date));
-			} else if (data.slug.isEmpty()) {
-				const auto months = data.count;
-				Settings::ShowGiftPremium(controller, peer, months, sent);
-			} else {
-				const auto fromId = from->id;
-				const auto toId = sent ? peer->id : selfId;
-				ResolveGiftCode(controller, data.slug, fromId, toId);
+					item));
 			}
+		} else if (creditsPrize()) {
+			controller->show(Box(
+				Settings::CreditsPrizeBox,
+				controller,
+				data,
+				date));
+		} else if (data.type == Data::GiftType::Credits) {
+			const auto to = sent ? peer : peer->session().user();
+			controller->show(Box(
+				Settings::GiftedCreditsBox,
+				controller,
+				from,
+				to,
+				data.count,
+				date));
+		} else if (data.slug.isEmpty()) {
+			const auto months = data.count;
+			Settings::ShowGiftPremium(controller, peer, months, sent);
+		} else {
+			const auto fromId = from->id;
+			const auto toId = sent ? peer->id : selfId;
+			ResolveGiftCode(controller, data.slug, fromId, toId);
 		}
+	};
+
+	if (const auto upgradeTo = data.upgradeMsgId) {
+		const auto requesting = std::make_shared<bool>();
+		return std::make_shared<LambdaClickHandler>([=](
+				ClickContext context) {
+			const auto my = context.other.value<ClickHandlerContext>();
+			const auto weak = my.sessionWindow;
+			const auto controller = weak.get();
+			if (!controller || *requesting) {
+				return;
+			}
+			*requesting = true;
+			controller->session().api().request(MTPpayments_GetUserStarGift(
+				MTP_vector<MTPint>(1, MTP_int(upgradeTo))
+			)).done([=](const MTPpayments_UserStarGifts &result) {
+				*requesting = false;
+				if (const auto window = weak.get()) {
+					const auto &data = result.data();
+					window->session().data().processUsers(data.vusers());
+					const auto self = window->session().user();
+					const auto &list = data.vgifts().v;
+					if (list.empty()) {
+						showForWeakWindow(weak);
+					} else if (auto parsed = Api::FromTL(self, list[0])) {
+						window->show(Box(
+							Settings::UserStarGiftBox,
+							window,
+							self,
+							*parsed));
+					}
+				}
+			}).fail([=](const MTP::Error &error) {
+				*requesting = false;
+				if (const auto window = weak.get()) {
+					window->showToast(error.type());
+				}
+				showForWeakWindow(weak);
+			}).send();
+		});
+	}
+	return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
+		showForWeakWindow(
+			context.other.value<ClickHandlerContext>().sessionWindow);
 	});
 }