From 1e1466700685da5bfb75bca4a5a26f8b551549ef Mon Sep 17 00:00:00 2001
From: John Preston <johnprestonmail@gmail.com>
Date: Mon, 2 Dec 2024 15:19:01 +0400
Subject: [PATCH] Add affiliate program point to bot info.

---
 .../bot/starref/info_bot_starref_common.cpp   |  4 +-
 .../bot/starref/info_bot_starref_common.h     |  2 +-
 .../info/profile/info_profile_actions.cpp     | 61 +++++++++++++++++++
 3 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp
index 99072d0b4..db86edab7 100644
--- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp
+++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp
@@ -524,7 +524,9 @@ object_ptr<Ui::BoxContent> StarRefLinkBox(
 			}
 			state->sent = true;
 			ConnectStarRef(bot->asUser(), peer, [=](ConnectedBot info) {
-				done(info.state);
+				if (const auto onstack = done) {
+					onstack(info.state);
+				}
 				show->show(StarRefLinkBox(info, peer));
 				if (const auto strong = state->weak.data()) {
 					strong->closeBox();
diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h
index 8370a1dc6..d8f538701 100644
--- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h
+++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h
@@ -66,7 +66,7 @@ void AddFullWidthButtonFooter(
 [[nodiscard]] object_ptr<Ui::BoxContent> JoinStarRefBox(
 	ConnectedBot row,
 	not_null<PeerData*> peer,
-	Fn<void(ConnectedBotState)> done);
+	Fn<void(ConnectedBotState)> done = nullptr);
 [[nodiscard]] object_ptr<Ui::BoxContent> ConfirmEndBox(Fn<void()> finish);
 
 std::unique_ptr<Ui::AbstractButton> MakePeerBubbleButton(
diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp
index 43b4ff317..64cca09af 100644
--- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp
+++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp
@@ -46,6 +46,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "history/history_item_helpers.h"
 #include "history/view/history_view_item_preview.h"
 #include "info/bot/earn/info_bot_earn_widget.h"
+#include "info/bot/starref/info_bot_starref_common.h"
 #include "info/channel_statistics/earn/earn_format.h"
 #include "info/channel_statistics/earn/earn_icons.h"
 #include "info/channel_statistics/earn/info_channel_earn_list.h"
@@ -61,6 +62,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "lang/lang_keys.h"
 #include "main/main_session.h"
 #include "menu/menu_mute.h"
+#include "settings/settings_common.h"
 #include "support/support_helper.h"
 #include "ui/boxes/peer_qr_box.h"
 #include "ui/boxes/report_box_graphics.h"
@@ -1003,6 +1005,7 @@ public:
 	object_ptr<Ui::RpWidget> fill();
 
 private:
+	void addAffiliateProgram(not_null<UserData*> user);
 	void addBalanceActions(not_null<UserData*> user);
 	void addInviteToGroupAction(not_null<UserData*> user);
 	void addShareContactAction(not_null<UserData*> user);
@@ -2114,6 +2117,63 @@ ActionsFiller::ActionsFiller(
 , _peer(peer) {
 }
 
+void ActionsFiller::addAffiliateProgram(not_null<UserData*> user) {
+	if (!user->isBot()) {
+		return;
+	}
+
+	const auto wrap = _wrap->add(
+		object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
+			_wrap.data(),
+			object_ptr<Ui::VerticalLayout>(_wrap.data())));
+	const auto inner = wrap->entity();
+	auto program = user->session().changes().peerFlagsValue(
+		user,
+		Data::PeerUpdate::Flag::StarRefProgram
+	) | rpl::map([=] {
+		return user->botInfo->starRefProgram;
+	}) | rpl::start_spawning(inner->lifetime());
+	auto commission = rpl::duplicate(
+		program
+	) | rpl::filter([=](StarRefProgram program) {
+		return program.commission > 0;
+	}) | rpl::map([=](StarRefProgram program) {
+		return Info::BotStarRef::FormatCommission(program.commission);
+	});
+	const auto show = _controller->uiShow();
+
+	Ui::AddSkip(inner);
+	::Settings::AddButtonWithLabel(
+		inner,
+		tr::lng_manage_peer_bot_star_ref(),
+		rpl::duplicate(commission),
+		st::infoSharedMediaButton,
+		{ &st::menuIconSharing }
+	)->setClickedCallback([=] {
+		const auto program = user->botInfo->starRefProgram;
+		show->show(Info::BotStarRef::JoinStarRefBox(
+			{ user, { program } },
+			user->session().user()));
+	});
+	Ui::AddSkip(inner);
+	Ui::AddDividerText(
+		inner,
+		tr::lng_manage_peer_bot_star_ref_about(
+			lt_bot,
+			rpl::single(TextWithEntities{ user->name() }),
+			lt_amount,
+			rpl::duplicate(commission) | Ui::Text::ToWithEntities(),
+			Ui::Text::RichLangValue));
+	Ui::AddSkip(inner);
+
+	wrap->toggleOn(std::move(
+		program
+	) | rpl::map([](StarRefProgram program) {
+		return program.commission > 0;
+	}));
+	wrap->finishAnimating();
+}
+
 void ActionsFiller::addBalanceActions(not_null<UserData*> user) {
 	const auto wrap = _wrap->add(
 		object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
@@ -2379,6 +2439,7 @@ void ActionsFiller::addJoinChannelAction(
 
 void ActionsFiller::fillUserActions(not_null<UserData*> user) {
 	if (user->isBot()) {
+		addAffiliateProgram(user);
 		addBalanceActions(user);
 		addInviteToGroupAction(user);
 	}