From 928be4151bb8213c1af047dac4735bd8ed0d4aa2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 21 Feb 2025 10:15:26 +0400 Subject: [PATCH] Update API scheme, parse premium gifts for stars. --- Telegram/Resources/langs/lang.strings | 1 + Telegram/SourceFiles/api/api_premium.cpp | 16 ++-- Telegram/SourceFiles/api/api_premium.h | 3 +- Telegram/SourceFiles/boxes/star_gift_box.cpp | 73 ++++++++++++++----- .../info/peer_gifts/info_peer_gifts_common.h | 1 + Telegram/SourceFiles/mtproto/scheme/api.tl | 2 +- 6 files changed, 70 insertions(+), 26 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 5b378b5d1..aac02c54a 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3341,6 +3341,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_send_anonymous" = "Hide My Name"; "lng_gift_send_anonymous_self" = "Hide my name and message from visitors to my profile."; "lng_gift_send_anonymous_about" = "You can hide your name and message from visitors to {user}'s profile. {recipient} will still see your name and message."; +"lng_gift_send_anonymous_about_paid" = "You can hide your name from visitors to {user}'s profile. {recipient} will still see your name."; "lng_gift_send_anonymous_about_channel" = "You can hide your name and message from all visitors of this channel except its admins."; "lng_gift_send_unique" = "Make Unique for {price}"; "lng_gift_send_unique_about" = "Enable this to let {user} turn your gift into a unique collectible. {link}"; diff --git a/Telegram/SourceFiles/api/api_premium.cpp b/Telegram/SourceFiles/api/api_premium.cpp index 26913462b..b44ca20ed 100644 --- a/Telegram/SourceFiles/api/api_premium.cpp +++ b/Telegram/SourceFiles/api/api_premium.cpp @@ -482,6 +482,7 @@ rpl::producer PremiumGiftCodeOptions::request() { const auto token = Token{ data.vusers().v, data.vmonths().v }; _stores[token] = Store{ .amount = data.vamount().v, + .currency = qs(data.vcurrency()), .product = qs(data.vstore_product().value_or_empty()), .quantity = data.vstore_quantity().value_or_empty(), }; @@ -490,14 +491,14 @@ rpl::producer PremiumGiftCodeOptions::request() { } } for (const auto &[amount, tlOptions] : tlMapOptions) { - if (amount == 1 && _optionsForOnePerson.currency.isEmpty()) { - _optionsForOnePerson.currency = qs( - tlOptions.front().data().vcurrency()); + if (amount == 1 && _optionsForOnePerson.currencies.empty()) { for (const auto &option : tlOptions) { _optionsForOnePerson.months.push_back( option.data().vmonths().v); _optionsForOnePerson.totalCosts.push_back( option.data().vamount().v); + _optionsForOnePerson.currencies.push_back( + qs(option.data().vcurrency())); } } _subscriptionOptions[amount] = GiftCodesFromTL(tlOptions); @@ -555,7 +556,7 @@ Payments::InvoicePremiumGiftCode PremiumGiftCodeOptions::invoice( const auto token = Token{ users, months }; const auto &store = _stores[token]; return Payments::InvoicePremiumGiftCode{ - .currency = _optionsForOnePerson.currency, + .currency = store.currency, .storeProduct = store.product, .randomId = randomId, .amount = store.amount, @@ -568,14 +569,15 @@ Payments::InvoicePremiumGiftCode PremiumGiftCodeOptions::invoice( std::vector PremiumGiftCodeOptions::optionsForPeer() const { auto result = std::vector(); - if (!_optionsForOnePerson.currency.isEmpty()) { + if (!_optionsForOnePerson.currencies.empty()) { const auto count = int(_optionsForOnePerson.months.size()); result.reserve(count); for (auto i = 0; i != count; ++i) { Assert(i < _optionsForOnePerson.totalCosts.size()); + Assert(i < _optionsForOnePerson.currencies.size()); result.push_back({ .cost = _optionsForOnePerson.totalCosts[i], - .currency = _optionsForOnePerson.currency, + .currency = _optionsForOnePerson.currencies[i], .months = _optionsForOnePerson.months[i], }); } @@ -596,7 +598,7 @@ Data::PremiumSubscriptionOptions PremiumGiftCodeOptions::options(int amount) { MTP_int(_optionsForOnePerson.months[i]), MTPstring(), MTPint(), - MTP_string(_optionsForOnePerson.currency), + MTP_string(_optionsForOnePerson.currencies[i]), MTP_long(_optionsForOnePerson.totalCosts[i] * amount))); } _subscriptionOptions[amount] = GiftCodesFromTL(tlOptions); diff --git a/Telegram/SourceFiles/api/api_premium.h b/Telegram/SourceFiles/api/api_premium.h index 0430c754b..5f4d06d83 100644 --- a/Telegram/SourceFiles/api/api_premium.h +++ b/Telegram/SourceFiles/api/api_premium.h @@ -209,6 +209,7 @@ private: }; struct Store final { uint64 amount = 0; + QString currency; QString product; int quantity = 0; }; @@ -219,7 +220,7 @@ private: struct { std::vector months; std::vector totalCosts; - QString currency; + std::vector currencies; } _optionsForOnePerson; std::vector _availablePresets; diff --git a/Telegram/SourceFiles/boxes/star_gift_box.cpp b/Telegram/SourceFiles/boxes/star_gift_box.cpp index c99b64959..fcd18526b 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_box.cpp @@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "chat_helpers/tabbed_panel.h" #include "chat_helpers/tabbed_selector.h" #include "core/ui_integration.h" +#include "data/data_changes.h" #include "data/data_channel.h" #include "data/data_credits.h" #include "data/data_document.h" @@ -80,6 +81,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/checkbox.h" #include "ui/widgets/popup_menu.h" #include "ui/widgets/shadow.h" +#include "ui/wrap/slide_wrap.h" #include "window/themes/window_theme.h" #include "window/section_widget.h" #include "window/window_session_controller.h" @@ -622,14 +624,27 @@ void PreviewWrap::paintEvent(QPaintEvent *e) { list.reserve(options.size()); auto minMonthsGift = GiftTypePremium(); for (const auto &option : options) { - list.push_back({ - .cost = option.cost, - .currency = option.currency, - .months = option.months, - }); - if (!minMonthsGift.months - || option.months < minMonthsGift.months) { - minMonthsGift = list.back(); + if (option.currency != kCreditsCurrency) { + list.push_back({ + .cost = option.cost, + .currency = option.currency, + .months = option.months, + }); + if (!minMonthsGift.months + || option.months < minMonthsGift.months) { + minMonthsGift = list.back(); + } + } + } + for (const auto &option : options) { + if (option.currency == kCreditsCurrency) { + const auto i = ranges::find( + list, + option.months, + &GiftTypePremium::months); + if (i != end(list)) { + i->stars = option.cost; + } } } for (auto &gift : list) { @@ -1424,6 +1439,7 @@ void SendGiftBox( struct State { rpl::variable details; + rpl::variable messageAllowed; std::shared_ptr media; bool submitting = false; }; @@ -1432,6 +1448,13 @@ void SendGiftBox( .descriptor = descriptor, .randomId = base::RandomValue(), }; + peer->updateFull(); + state->messageAllowed = peer->session().changes().peerFlagsValue( + peer, + Data::PeerUpdate::Flag::StarsPerMessage + ) | rpl::map([=] { + return peer->starsPerMessageChecked() == 0; + }); auto cost = state->details.value( ) | rpl::map([session](const GiftDetails &details) { @@ -1462,10 +1485,17 @@ void SendGiftBox( peer, state->details.value())); + const auto messageWrap = container->add( + object_ptr>( + container, + object_ptr(container))); + messageWrap->toggleOn(state->messageAllowed.value()); + messageWrap->finishAnimating(); + const auto messageInner = messageWrap->entity(); const auto limit = StarGiftMessageLimit(session); const auto text = AddPartInput( window, - container, + messageInner, box->getDelegate()->outerContainer(), tr::lng_gift_send_message(), QString(), @@ -1509,7 +1539,6 @@ void SendGiftBox( text, session, { .suggestCustomEmoji = true, .allowCustomWithoutPremium = allow }); - if (stars) { const auto cost = stars->info.starsToUpgrade; if (cost > 0 && !peer->isSelf()) { @@ -1552,7 +1581,7 @@ void SendGiftBox( AddSkip(container); } v::match(descriptor, [&](const GiftTypePremium &) { - AddDividerText(container, tr::lng_gift_send_premium_about( + AddDividerText(messageInner, tr::lng_gift_send_premium_about( lt_user, rpl::single(peer->shortName()))); }, [&](const GiftTypeStars &) { @@ -1560,11 +1589,18 @@ void SendGiftBox( ? tr::lng_gift_send_anonymous_self() : peer->isBroadcast() ? tr::lng_gift_send_anonymous_about_channel() - : tr::lng_gift_send_anonymous_about( - lt_user, - rpl::single(peer->shortName()), - lt_recipient, - rpl::single(peer->shortName()))); + : rpl::conditional( + state->messageAllowed.value(), + tr::lng_gift_send_anonymous_about( + lt_user, + rpl::single(peer->shortName()), + lt_recipient, + rpl::single(peer->shortName())), + tr::lng_gift_send_anonymous_about_paid( + lt_user, + rpl::single(peer->shortName()), + lt_recipient, + rpl::single(peer->shortName())))); }); const auto buttonWidth = st::boxWideWidth @@ -1575,7 +1611,10 @@ void SendGiftBox( return; } state->submitting = true; - const auto details = state->details.current(); + auto details = state->details.current(); + if (!state->messageAllowed.current()) { + details.text = {}; + } const auto weak = MakeWeak(box); const auto done = [=](Payments::CheckoutResult result) { if (result == Payments::CheckoutResult::Paid) { diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h index bba226aaa..8362ef85d 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h @@ -44,6 +44,7 @@ namespace Info::PeerGifts { struct GiftTypePremium { int64 cost = 0; QString currency; + int stars = 0; int months = 0; int discountPercent = 0; diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 5884d4d86..84522a174 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -175,7 +175,7 @@ messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction; messageActionRequestedPeer#31518e9b button_id:int peers:Vector = MessageAction; messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction; -messageActionGiftCode#56d03994 flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long message:flags.4?TextWithEntities = MessageAction; +messageActionGiftCode#56d03994 flags:# via_giveaway:flags.0?true unclaimed:flags.5?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long message:flags.4?TextWithEntities = MessageAction; messageActionGiveawayLaunch#a80f51e4 flags:# stars:flags.0?long = MessageAction; messageActionGiveawayResults#87e2f155 flags:# stars:flags.0?true winners_count:int unclaimed_count:int = MessageAction; messageActionBoostApply#cc02aa6d boosts:int = MessageAction;