diff --git a/Telegram/SourceFiles/boxes/gift_premium_box.cpp b/Telegram/SourceFiles/boxes/gift_premium_box.cpp index 94afb8c8e..4d1de594a 100644 --- a/Telegram/SourceFiles/boxes/gift_premium_box.cpp +++ b/Telegram/SourceFiles/boxes/gift_premium_box.cpp @@ -1642,6 +1642,9 @@ void AddCreditsHistoryEntryTable( not_null controller, not_null container, const Data::CreditsHistoryEntry &entry) { + if (!entry) { + return; + } auto table = container->add( object_ptr( container, @@ -1757,3 +1760,33 @@ void AddCreditsHistoryEntryTable( Ui::Text::Link(entry.successLink, entry.successLink))); } } + +void AddSubscriptionEntryTable( + not_null controller, + not_null container, + const Data::SubscriptionEntry &s) { + if (!s) { + return; + } + auto table = container->add( + object_ptr( + container, + st::giveawayGiftCodeTable), + st::giveawayGiftCodeTableMargin); + const auto peerId = PeerId(s.barePeerId); + AddTableRow( + table, + tr::lng_credits_subscription_row_to(), + controller, + peerId); + if (!s.until.isNull()) { + AddTableRow( + table, + s.expired + ? tr::lng_credits_subscription_row_next_none() + : s.cancelled + ? tr::lng_credits_subscription_row_next_off() + : tr::lng_credits_subscription_row_next_on(), + rpl::single(Ui::Text::WithEntities(langDateTime(s.until)))); + } +} diff --git a/Telegram/SourceFiles/boxes/gift_premium_box.h b/Telegram/SourceFiles/boxes/gift_premium_box.h index e3194b273..c58caea48 100644 --- a/Telegram/SourceFiles/boxes/gift_premium_box.h +++ b/Telegram/SourceFiles/boxes/gift_premium_box.h @@ -19,6 +19,7 @@ namespace Data { struct CreditsHistoryEntry; struct GiveawayStart; struct GiveawayResults; +struct SubscriptionEntry; } // namespace Data namespace Ui { @@ -78,3 +79,8 @@ void AddCreditsHistoryEntryTable( not_null controller, not_null container, const Data::CreditsHistoryEntry &entry); + +void AddSubscriptionEntryTable( + not_null controller, + not_null container, + const Data::SubscriptionEntry &s); diff --git a/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp index 893be4461..84910f9ab 100644 --- a/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp +++ b/Telegram/SourceFiles/info/bot/earn/info_bot_earn_list.cpp @@ -353,11 +353,14 @@ void InnerWidget::fillHistory() { }, inner->lifetime()); const auto controller = _controller->parentController(); - const auto entryClicked = [=](const Data::CreditsHistoryEntry &e) { + const auto entryClicked = [=]( + const Data::CreditsHistoryEntry &e, + const Data::SubscriptionEntry &s) { controller->uiShow()->show(Box( ::Settings::ReceiptCreditsBox, controller, - e)); + e, + s)); }; Info::Statistics::AddCreditsHistoryList( diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp index a0fa623a7..30022f364 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp @@ -1404,11 +1404,13 @@ void InnerWidget::fill() { const auto show = controller->uiShow(); const auto premiumBot = _peer->owner().peer(data.premiumBotId); const auto entryClicked = [=]( - const Data::CreditsHistoryEntry &e) { + const Data::CreditsHistoryEntry &e, + const Data::SubscriptionEntry &s) { show->show(Box( ::Settings::ReceiptCreditsBox, controller, - e)); + e, + s)); }; Info::Statistics::AddCreditsHistoryList( diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp index ea2e53468..9ca8384f5 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp @@ -133,7 +133,7 @@ struct BoostsDescriptor final { struct CreditsDescriptor final { Data::CreditsStatusSlice firstSlice; - Fn entryClickedCallback; + Clicked entryClickedCallback; not_null peer; bool in = false; bool out = false; @@ -980,7 +980,7 @@ private: void applySlice(const Data::CreditsStatusSlice &slice); const not_null _session; - Fn _entryClickedCallback; + Clicked _entryClickedCallback; Api::CreditsHistory _api; Data::CreditsStatusSlice _firstSlice; @@ -1066,8 +1066,8 @@ void CreditsController::applySlice(const Data::CreditsStatusSlice &slice) { void CreditsController::rowClicked(not_null row) { if (_entryClickedCallback) { - _entryClickedCallback( - static_cast(row.get())->entry()); + const auto r = static_cast(row.get()); + _entryClickedCallback(r->entry(), r->subscription()); } } @@ -1230,7 +1230,7 @@ void AddCreditsHistoryList( std::shared_ptr show, const Data::CreditsStatusSlice &firstSlice, not_null container, - Fn callback, + Clicked callback, not_null bot, bool in, bool out) { diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h index 0b14a10ae..00f0022dd 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h @@ -20,6 +20,7 @@ struct CreditsHistoryEntry; struct CreditsStatusSlice; struct PublicForwardsSlice; struct RecentPostId; +struct SubscriptionEntry; struct SupergroupStatistics; } // namespace Data @@ -50,11 +51,14 @@ void AddBoostsList( not_null peer, rpl::producer title); +using Clicked = Fn; void AddCreditsHistoryList( std::shared_ptr show, const Data::CreditsStatusSlice &firstSlice, not_null container, - Fn entryClickedCallback, + Clicked entryClickedCallback, not_null peer, bool in, bool out); diff --git a/Telegram/SourceFiles/payments/payments_non_panel_process.cpp b/Telegram/SourceFiles/payments/payments_non_panel_process.cpp index 28fda8529..393428931 100644 --- a/Telegram/SourceFiles/payments/payments_non_panel_process.cpp +++ b/Telegram/SourceFiles/payments/payments_non_panel_process.cpp @@ -102,7 +102,8 @@ void ProcessCreditsReceipt( controller->uiShow()->show(Box( Settings::ReceiptCreditsBox, controller, - entry)); + entry, + Data::SubscriptionEntry{})); controller->window().activate(); } diff --git a/Telegram/SourceFiles/settings/settings_credits.cpp b/Telegram/SourceFiles/settings/settings_credits.cpp index bae6e9f94..c6476e2b0 100644 --- a/Telegram/SourceFiles/settings/settings_credits.cpp +++ b/Telegram/SourceFiles/settings/settings_credits.cpp @@ -150,11 +150,14 @@ void Credits::setupSubscriptions(not_null container) { object_ptr(inner))); const auto controller = _controller->parentController(); - const auto entryClicked = [=](const Data::CreditsHistoryEntry &e) { + const auto entryClicked = [=]( + const Data::CreditsHistoryEntry &e, + const Data::SubscriptionEntry &s) { controller->uiShow()->show(Box( ReceiptCreditsBox, controller, - e)); + e, + s)); }; Info::Statistics::AddCreditsHistoryList( @@ -280,11 +283,14 @@ void Credits::setupHistory(not_null container) { }, inner->lifetime()); const auto controller = _controller->parentController(); - const auto entryClicked = [=](const Data::CreditsHistoryEntry &e) { + const auto entryClicked = [=]( + const Data::CreditsHistoryEntry &e, + const Data::SubscriptionEntry &s) { controller->uiShow()->show(Box( ReceiptCreditsBox, controller, - e)); + e, + s)); }; Info::Statistics::AddCreditsHistoryList( diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 335d1b09a..ff39a28d0 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_file_origin.h" #include "data/data_photo_media.h" #include "data/data_session.h" +#include "data/data_subscriptions.h" #include "data/data_user.h" #include "data/stickers/data_custom_emoji.h" #include "history/history.h" @@ -440,12 +441,11 @@ not_null AddBalanceWidget( void ReceiptCreditsBox( not_null box, not_null controller, - const Data::CreditsHistoryEntry &e) { + const Data::CreditsHistoryEntry &e, + const Data::SubscriptionEntry &s) { box->setStyle(st::giveawayGiftCodeBox); box->setNoContentMargin(true); - const auto star = Ui::GenerateStars(st::creditsTopupButton.height, 1); - const auto content = box->verticalLayout(); Ui::AddSkip(content); Ui::AddSkip(content); @@ -455,7 +455,9 @@ void ReceiptCreditsBox( const auto &stUser = st::boostReplaceUserpic; const auto session = &controller->session(); - const auto peer = (e.peerType == Type::PremiumBot) + const auto peer = (s.barePeerId) + ? session->data().peer(PeerId(s.barePeerId)).get() + : (e.peerType == Type::PremiumBot) ? nullptr : e.barePeerId ? session->data().peer(PeerId(e.barePeerId)).get() @@ -548,7 +550,9 @@ void ReceiptCreditsBox( box, object_ptr( box, - rpl::single(!e.subscriptionUntil.isNull() + rpl::single(!s.until.isNull() + ? tr::lng_credits_box_subscription_title(tr::now) + : !e.subscriptionUntil.isNull() ? tr::lng_credits_box_history_entry_subscription(tr::now) : !e.title.isEmpty() ? e.title @@ -564,10 +568,7 @@ void ReceiptCreditsBox( { constexpr auto kMinus = QChar(0x2212); auto &lifetime = content->lifetime(); - const auto text = lifetime.make_state( - st::semiboldTextStyle, - (e.in ? u"+"_q : e.gift ? QString() : QString(kMinus)) - + Lang::FormatCountDecimal(std::abs(int64(e.credits)))); + const auto text = lifetime.make_state(); const auto roundedText = e.refunded ? tr::lng_channel_earn_history_return(tr::now) : e.pending @@ -584,25 +585,50 @@ void ReceiptCreditsBox( const auto amount = content->add( object_ptr( content, - star.height() / style::DevicePixelRatio())); + st::defaultTextStyle.font->height)); + const auto context = Core::MarkedTextContext{ + .session = session, + .customEmojiRepaint = [=] { amount->update(); }, + }; + if (s) { + text->setMarkedText( + st::defaultTextStyle, + tr::lng_credits_subscription_subtitle( + tr::now, + lt_emoji, + session->data().customEmojiManager().creditsEmoji(), + lt_cost, + { QString::number(s.subscription.credits) }, + Ui::Text::WithEntities), + kMarkupTextOptions, + context); + } else { + auto t = TextWithEntities() + .append(e.in ? u"+"_q : e.gift ? QString() : QString(kMinus)) + .append(Lang::FormatCountDecimal(std::abs(int64(e.credits)))) + .append(QChar(' ')) + .append(session->data().customEmojiManager().creditsEmoji()); + text->setMarkedText( + st::semiboldTextStyle, + std::move(t), + kMarkupTextOptions, + context); + } const auto font = text->style()->font; const auto roundedFont = st::defaultTextStyle.font; - const auto starWidth = star.width() - / style::DevicePixelRatio(); const auto roundedSkip = roundedFont->spacew * 2; const auto roundedWidth = rounded ? roundedFont->width(roundedText) + roundedSkip + roundedFont->height : 0; - const auto fullWidth = text->maxWidth() - + font->spacew * 1 - + starWidth - + roundedWidth; + const auto fullWidth = text->maxWidth() + roundedWidth; amount->paintRequest( ) | rpl::start_with_next([=] { auto p = Painter(amount); - p.setPen(e.pending + p.setPen(s + ? st::windowSubTextFg + : e.pending ? st::creditsStroke : e.in ? st::boxTextFgGood @@ -617,10 +643,6 @@ void ReceiptCreditsBox( .outerWidth = amount->width(), .availableWidth = amount->width(), }); - p.drawImage( - x + fullWidth - starWidth - roundedWidth, - 0, - star); if (rounded) { const auto roundedLeft = fullWidth @@ -702,6 +724,7 @@ void ReceiptCreditsBox( Ui::AddSkip(content); AddCreditsHistoryEntryTable(controller, content, e); + AddSubscriptionEntryTable(controller, content, s); Ui::AddSkip(content); @@ -713,11 +736,24 @@ void ReceiptCreditsBox( lt_link, tr::lng_payments_terms_link( ) | Ui::Text::ToLink( - tr::lng_credits_box_out_about_link(tr::now) - ), + tr::lng_credits_box_out_about_link(tr::now)), Ui::Text::WithEntities), st::creditsBoxAboutDivider))); + if (s) { + Ui::AddSkip(content); + box->addRow(object_ptr>( + box, + object_ptr( + box, + s.cancelled + ? tr::lng_credits_subscription_off_about() + : tr::lng_credits_subscription_on_about( + lt_date, + rpl::single(langDayOfMonthFull(s.until.date()))), + st::creditsBoxAboutDivider))); + } + Ui::AddSkip(content); if (e.peerType == Data::CreditsHistoryEntry::PeerType::PremiumBot) { @@ -782,7 +818,7 @@ void GiftedCreditsBox( .peerType = (anonymous ? PeerType::Fragment : PeerType::Peer), .in = received, .gift = true, - }); + }, {}); } void ShowRefundInfoBox( @@ -808,7 +844,8 @@ void ShowRefundInfoBox( controller->show(Box( ::Settings::ReceiptCreditsBox, controller, - info)); + info, + Data::SubscriptionEntry{})); } object_ptr GenericEntryPhoto( diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.h b/Telegram/SourceFiles/settings/settings_credits_graphics.h index f91bd0f6f..785a7635f 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.h +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.h @@ -14,6 +14,7 @@ class PeerData; namespace Data { struct CreditsHistoryEntry; +struct SubscriptionEntry; } // namespace Data namespace Main { @@ -57,7 +58,8 @@ void AddWithdrawalWidget( void ReceiptCreditsBox( not_null box, not_null controller, - const Data::CreditsHistoryEntry &e); + const Data::CreditsHistoryEntry &e, + const Data::SubscriptionEntry &s); void GiftedCreditsBox( not_null box, not_null controller,