diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index f8dab61e2e..231f2e352d 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3883,6 +3883,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_dialogs_suggestions_premium_grace_about" = "Don’t lose access to exclusive features."; "lng_dialogs_suggestions_userpics_title" = "Add your photo! 📸"; "lng_dialogs_suggestions_userpics_about" = "Help your friends spot you easily."; +"lng_dialogs_suggestions_credits_sub_low_title#one" = "{emoji} {count} Star needed for {channels}"; +"lng_dialogs_suggestions_credits_sub_low_title#other" = "{emoji} {count} Stars needed for {channels}"; +"lng_dialogs_suggestions_credits_sub_low_about" = "Insufficient funds to cover your subscription."; "lng_about_random" = "Send a {emoji} emoji to any chat to try your luck."; "lng_about_random_send" = "Send"; diff --git a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp index ca0c3b703d..14ff8c2795 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_top_bar_suggestion.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "dialogs/dialogs_top_bar_suggestion.h" +#include "api/api_credits.h" #include "api/api_peer_photo.h" #include "api/api_premium.h" #include "apiwrap.h" @@ -24,8 +25,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "main/main_app_config.h" #include "main/main_session.h" +#include "settings/settings_credits_graphics.h" #include "settings/settings_premium.h" #include "ui/controls/userpic_button.h" +#include "ui/layers/generic_box.h" +#include "ui/text/format_values.h" #include "ui/text/text_utilities.h" #include "ui/ui_utility.h" #include "ui/wrap/slide_wrap.h" @@ -52,6 +56,7 @@ constexpr auto kSugPremiumUpgrade = "PREMIUM_UPGRADE"_cs; constexpr auto kSugPremiumRestore = "PREMIUM_RESTORE"_cs; constexpr auto kSugPremiumGrace = "PREMIUM_GRACE"_cs; constexpr auto kSugSetUserpic = "USERPIC_SETUP"_cs; +constexpr auto kSugLowCreditsSubs = "STARS_SUBSCRIPTION_LOW_BALANCE"_cs; } // namespace @@ -77,6 +82,8 @@ rpl::producer*> TopBarSuggestionValue( rpl::lifetime premiumLifetime; rpl::lifetime userpicLifetime; rpl::lifetime giftsLifetime; + rpl::lifetime creditsLifetime; + std::unique_ptr creditsHistory; }; const auto state = lifetime.make_state(); @@ -108,6 +115,81 @@ rpl::producer*> TopBarSuggestionValue( using RightIcon = TopBarSuggestionContent::RightIcon; const auto config = &session->appConfig(); if (session->premiumCanBuy() + && config->suggestionCurrent(kSugLowCreditsSubs.utf8())) { + state->creditsHistory = std::make_unique( + session->user(), + false, + false); + const auto show = [=]( + const QString &peers, + uint64 needed, + uint64 whole) { + content->setRightIcon(RightIcon::Close); + content->setClickedCallback([=] { + const auto controller = FindSessionController(parent); + if (!controller) { + return; + } + controller->uiShow()->show(Box( + Settings::SmallBalanceBox, + controller->uiShow(), + needed, + Settings::SmallBalanceSubscription{ peers }, + [=] { + config->dismissSuggestion( + kSugLowCreditsSubs.utf8()); + repeat(repeat); + })); + }); + content->setHideCallback([=] { + config->dismissSuggestion(kSugLowCreditsSubs.utf8()); + repeat(repeat); + }); + content->setContent( + tr::lng_dialogs_suggestions_credits_sub_low_title( + tr::now, + lt_count, + float64(needed - whole), + lt_emoji, + Ui::Text::SingleCustomEmoji(Ui::kCreditsCurrency), + lt_channels, + { peers }, + Ui::Text::Bold), + tr::lng_dialogs_suggestions_credits_sub_low_about( + tr::now, + TextWithEntities::Simple), + true); + state->desiredWrapToggle.force_assign( + Toggle{ true, anim::type::normal }); + }; + session->credits().load(); + state->creditsLifetime.destroy(); + session->credits().balanceValue() | rpl::start_with_next([=] { + state->creditsLifetime.destroy(); + state->creditsHistory->requestSubscriptions( + Data::CreditsStatusSlice::OffsetToken(), + [=](Data::CreditsStatusSlice slice) { + state->creditsHistory = nullptr; + auto peers = QStringList(); + auto credits = uint64(0); + for (const auto &entry : slice.subscriptions) { + if (entry.barePeerId) { + const auto peer = session->data().peer( + PeerId(entry.barePeerId)); + peers.append(peer->name()); + credits += entry.subscription.credits; + } + } + show( + peers.join(", "), + credits, + session->credits().balance().whole()); + }, + true); + }, state->creditsLifetime); + + return; + } else if (session->premiumCanBuy() && config->suggestionCurrent(kSugPremiumGrace.utf8())) { content->setRightIcon(RightIcon::Close); content->setClickedCallback([=] { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp index 6444f2647b..d08ffae49c 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.cpp @@ -6,6 +6,8 @@ For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "dialogs/ui/dialogs_top_bar_suggestion_content.h" +#include "ui/effects/credits_graphics.h" +#include "ui/text/text_custom_emoji.h" #include "ui/ui_rpl_filter.h" #include "styles/style_chat.h" #include "styles/style_chat_helpers.h" @@ -140,9 +142,33 @@ void TopBarSuggestionContent::draw(QPainter &p) { void TopBarSuggestionContent::setContent( TextWithEntities title, - TextWithEntities description) { - _contentTitle.setMarkedText(_contentTitleSt, std::move(title)); - _contentText.setMarkedText(_contentTextSt, std::move(description)); + TextWithEntities description, + bool makeContext) { + if (makeContext) { + auto customEmojiFactory = [=, h = _contentTitleSt.font->height]( + QStringView data, + const Ui::Text::MarkedContext &context + ) -> std::unique_ptr { + return Ui::MakeCreditsIconEmoji(h, 1); + }; + const auto context = Ui::Text::MarkedContext{ + .repaint = [=] { update(); }, + .customEmojiFactory = std::move(customEmojiFactory), + }; + _contentTitle.setMarkedText( + _contentTitleSt, + std::move(title), + kMarkupTextOptions, + context); + _contentText.setMarkedText( + _contentTextSt, + std::move(description), + kMarkupTextOptions, + context); + } else { + _contentTitle.setMarkedText(_contentTitleSt, std::move(title)); + _contentText.setMarkedText(_contentTextSt, std::move(description)); + } } void TopBarSuggestionContent::paintEvent(QPaintEvent *) { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h index 82b2f3b9f6..39aa4f997b 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_top_bar_suggestion_content.h @@ -28,7 +28,8 @@ public: void setContent( TextWithEntities title, - TextWithEntities description); + TextWithEntities description, + bool makeContext = false); [[nodiscard]] rpl::producer desiredHeightValue() const override;