From 5543927042d6603f4dbfa6b1563d67ce78627b89 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 16 Apr 2024 03:29:06 +0300 Subject: [PATCH] Added ability to enable sponsored messages for premium self. --- Telegram/Resources/langs/lang.strings | 5 + Telegram/SourceFiles/api/api_premium.cpp | 35 +++++++ Telegram/SourceFiles/api/api_premium.h | 12 +++ .../settings/settings_business.cpp | 98 +++++++++++++++++++ 4 files changed, 150 insertions(+) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 6215ec9fe..f31460e4e 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2272,6 +2272,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_business_about_chat_intro" = "Customize the message people see before they start a chat with you."; "lng_business_subtitle_chat_links" = "Links to Chat"; "lng_business_about_chat_links" = "Create links that start a chat with you, suggesting the first message."; +"lng_business_subtitle_sponsored" = "Ads in Channels"; +"lng_business_button_sponsored" = "Do Not Hide Ads"; +"lng_business_about_sponsored" = "As a Premium subscriber, you don’t see any ads on Telegram, but you can turn them on, for example, to view your own ads that you launched on the {link}"; +"lng_business_about_sponsored_link" = "Telegram Ad Platform {emoji}"; +"lng_business_about_sponsored_url" = "https://ads.telegram.org"; "lng_location_title" = "Location"; "lng_location_about" = "Display the location of your business on your account."; diff --git a/Telegram/SourceFiles/api/api_premium.cpp b/Telegram/SourceFiles/api/api_premium.cpp index 5257feb2d..6ff4aa130 100644 --- a/Telegram/SourceFiles/api/api_premium.cpp +++ b/Telegram/SourceFiles/api/api_premium.cpp @@ -602,6 +602,41 @@ bool PremiumGiftCodeOptions::giveawayGiftsPurchaseAvailable() const { false); } +SponsoredToggle::SponsoredToggle(not_null session) +: _api(&session->api().instance()) { +} + +rpl::producer SponsoredToggle::toggled() { + return [=](auto consumer) { + auto lifetime = rpl::lifetime(); + + _api.request(MTPusers_GetFullUser( + MTP_inputUserSelf() + )).done([=](const MTPusers_UserFull &result) { + consumer.put_next_copy( + result.data().vfull_user().data().is_sponsored_enabled()); + }).fail([=] { consumer.put_next(false); }).send(); + + return lifetime; + }; +} + +rpl::producer SponsoredToggle::setToggled(bool v) { + return [=](auto consumer) { + auto lifetime = rpl::lifetime(); + + _api.request(MTPaccount_ToggleSponsoredMessages( + MTP_bool(v) + )).done([=] { + consumer.put_done(); + }).fail([=](const MTP::Error &error) { + consumer.put_error_copy(error.type()); + }).send(); + + return lifetime; + }; +} + RequirePremiumState ResolveRequiresPremiumToWrite( not_null peer, History *maybeHistory) { diff --git a/Telegram/SourceFiles/api/api_premium.h b/Telegram/SourceFiles/api/api_premium.h index 9bacca92d..83423fcd2 100644 --- a/Telegram/SourceFiles/api/api_premium.h +++ b/Telegram/SourceFiles/api/api_premium.h @@ -216,6 +216,18 @@ private: }; +class SponsoredToggle final { +public: + explicit SponsoredToggle(not_null session); + + [[nodiscard]] rpl::producer toggled(); + [[nodiscard]] rpl::producer setToggled(bool); + +private: + MTP::Sender _api; + +}; + enum class RequirePremiumState { Unknown, Yes, diff --git a/Telegram/SourceFiles/settings/settings_business.cpp b/Telegram/SourceFiles/settings/settings_business.cpp index 163716819..c11a0f3cd 100644 --- a/Telegram/SourceFiles/settings/settings_business.cpp +++ b/Telegram/SourceFiles/settings/settings_business.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/business/data_business_info.h" #include "data/business/data_business_chatbots.h" #include "data/business/data_shortcut_messages.h" +#include "data/stickers/data_custom_emoji.h" #include "data/data_changes.h" #include "data/data_peer_values.h" // AmPremiumValue. #include "data/data_session.h" @@ -39,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/text_utilities.h" #include "ui/widgets/checkbox.h" // Ui::RadiobuttonGroup. #include "ui/widgets/gradient_round_button.h" +#include "ui/widgets/label_with_custom_emoji.h" #include "ui/wrap/fade_wrap.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/vertical_layout.h" @@ -51,6 +53,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_info.h" #include "styles/style_layers.h" #include "styles/style_settings.h" +#include "styles/style_chat.h" +#include "styles/style_channel_earn.h" namespace Settings { namespace { @@ -470,6 +474,100 @@ void Business::setupContent() { } }); + const auto sponsoredWrap = content->add( + object_ptr>( + content, + object_ptr(content))); + const auto fillSponsoredWrap = [=] { + while (sponsoredWrap->entity()->count()) { + delete sponsoredWrap->entity()->widgetAt(0); + } + Ui::AddDivider(sponsoredWrap->entity()); + const auto loading = sponsoredWrap->entity()->add( + object_ptr>( + sponsoredWrap->entity(), + object_ptr( + sponsoredWrap->entity(), + tr::lng_contacts_loading())), + st::boxRowPadding); + loading->entity()->setTextColorOverride(st::windowSubTextFg->c); + + const auto wrap = sponsoredWrap->entity()->add( + object_ptr>( + sponsoredWrap->entity(), + object_ptr(sponsoredWrap->entity()))); + wrap->toggle(false, anim::type::instant); + const auto inner = wrap->entity(); + Ui::AddSkip(inner); + Ui::AddSubsectionTitle( + inner, + tr::lng_business_subtitle_sponsored()); + const auto button = inner->add(object_ptr( + inner, + tr::lng_business_button_sponsored())); + Ui::AddSkip(inner); + + const auto session = &_controller->session(); + { + const auto arrow = Ui::Text::SingleCustomEmoji( + session->data().customEmojiManager().registerInternalEmoji( + st::topicButtonArrow, + st::channelEarnLearnArrowMargins, + false)); + inner->add(object_ptr( + inner, + Ui::CreateLabelWithCustomEmoji( + inner, + tr::lng_business_about_sponsored( + lt_link, + rpl::combine( + tr::lng_business_about_sponsored_link( + lt_emoji, + rpl::single(arrow), + Ui::Text::RichLangValue), + tr::lng_business_about_sponsored_url() + ) | rpl::map([](TextWithEntities text, QString url) { + return Ui::Text::Link(text, url); + }), + Ui::Text::RichLangValue), + { .session = session }, + st::boxDividerLabel), + st::defaultBoxDividerLabelPadding, + RectPart::Top | RectPart::Bottom)); + } + + const auto api = inner->lifetime().make_state( + session); + + api->toggled( + ) | rpl::start_with_next([=](bool enabled) { + button->toggleOn(rpl::single(enabled)); + wrap->toggle(true, anim::type::instant); + loading->toggle(false, anim::type::instant); + + button->toggledChanges( + ) | rpl::start_with_next([=](bool toggled) { + api->setToggled( + toggled + ) | rpl::start_with_error_done([=](const QString &error) { + _controller->showToast(error); + }, [] { + }, button->lifetime()); + }, button->lifetime()); + }, inner->lifetime()); + + Ui::ToggleChildrenVisibility(sponsoredWrap->entity(), true); + sponsoredWrap->entity()->resizeToWidth(content->width()); + }; + Data::AmPremiumValue( + &_controller->session() + ) | rpl::start_with_next([=](bool isPremium) { + sponsoredWrap->toggle(isPremium, anim::type::normal); + if (isPremium) { + fillSponsoredWrap(); + } + }, content->lifetime()); + Ui::ResizeFitChild(this, content); }