diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index bc504f4c56..2374510777 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2205,6 +2205,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_action_gift_upgraded_self_channel" = "You turned this gift to {channel} into a unique collectible"; "lng_action_gift_upgraded_mine" = "You turned the gift from {user} into a unique collectible"; "lng_action_gift_upgraded_self" = "You turned this gift into a unique collectible"; +"lng_action_gift_sent_upgrade_other" = "{from} sent an upgrade worth {cost} for the gift you received from {user}."; +"lng_action_gift_sent_upgrade_self_other" = "You sent an upgrade worth {cost} for the gift {name} received from {user}."; +"lng_action_gift_sent_upgrade" = "{from} sent an upgrade worth {cost} for your gift."; +"lng_action_gift_sent_upgrade_self" = "You sent an upgrade worth {cost} for this gift."; +"lng_action_gift_sent_upgrade_self_channel" = "You sent an upgrade worth {cost} for your gift to {name}."; +"lng_action_gift_upgraded_helped" = "{user} unpacked the gift that you helped to upgrade."; +"lng_action_gift_upgraded_helped_self" = "You unpacked the gift that {user} helped to upgrade."; "lng_action_gift_transferred" = "{user} transferred you a gift"; "lng_action_gift_transferred_channel" = "{user} transferred a gift to {channel}"; "lng_action_gift_transferred_unknown" = "Someone transferred you a gift"; @@ -3657,6 +3664,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_unique_status_non" = "Non-Unique"; "lng_gift_unique_upgrade" = "Upgrade"; "lng_gift_unique_upgrade_next" = "Upgrade Next Gift"; +"lng_gift_unique_gift_upgrade" = "Gift an Upgrade"; +"lng_gift_unique_gift_pay_upgrade" = "Pay {amount} for Upgrade"; "lng_gift_unique_number" = "Collectible #{index}"; "lng_gift_unique_number_by" = "Collectible #{index} by {name}"; "lng_gift_unique_model" = "Model"; @@ -3709,10 +3718,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_upgrade_preview_about_channel" = "Let the admins of {name} turn your gift into a unique collectible."; "lng_gift_upgrade_unique_title" = "Unique"; "lng_gift_upgrade_unique_about" = "Get a unique number, model, backdrop and symbol for your gift."; +"lng_gift_upgrade_unique_about_user" = "{name} will get a unique number, model, backdrop and symbol for your gift."; +"lng_gift_upgrade_unique_about_channel" = "Admins of {name} will get a unique number, model, backdrop and symbol for your gift."; "lng_gift_upgrade_transferable_title" = "Transferable"; "lng_gift_upgrade_transferable_about" = "Send your upgraded gift to any of your friends on Telegram."; +"lng_gift_upgrade_transferable_about_user" = "{name} will be able to send the gift to anyone on Telegram."; +"lng_gift_upgrade_transferable_about_channel" = "Admins of {name} will be able to send the gift to anyone on Telegram."; "lng_gift_upgrade_tradable_title" = "Tradable"; "lng_gift_upgrade_tradable_about" = "Sell or auction your gift on third-party NFT marketplaces."; +"lng_gift_upgrade_tradable_about_user" = "{name} will be able to sell the gift on Telegram and NFT marketplaces."; +"lng_gift_upgrade_tradable_about_channel" = "Admins of {name} will be able to sell the gift on Telegram and NFT marketplaces."; "lng_gift_upgrade_button" = "Upgrade for {price}"; "lng_gift_upgrade_free" = "Upgrade for Free"; "lng_gift_upgrade_confirm" = "Confirm"; @@ -3722,6 +3737,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_upgrade_add_comment" = "Add sender's name and comment"; "lng_gift_upgraded_title" = "Gift Upgraded"; "lng_gift_upgraded_about" = "Your gift {name} now has unique attributes and can be transferred to others"; +"lng_gift_upgrade_gifted_title" = "Upgrade Gifted"; +"lng_gift_upgrade_gifted_about" = "Now {name} can turn your gift into a unique collectible."; +"lng_gift_upgrade_gifted_about_channel" = "Now the admins of {name} can turn your gift into a unique collectible."; "lng_gift_transferred_title" = "Gift Transferred"; "lng_gift_transferred_about" = "{name} was successfully transferred to {recipient}."; "lng_gift_transfer_title" = "Transfer {name}"; diff --git a/Telegram/SourceFiles/api/api_premium.cpp b/Telegram/SourceFiles/api/api_premium.cpp index c8380d62d7..309f20261c 100644 --- a/Telegram/SourceFiles/api/api_premium.cpp +++ b/Telegram/SourceFiles/api/api_premium.cpp @@ -967,6 +967,8 @@ std::optional FromTL( .starsConverted = int64(data.vconvert_stars().value_or_empty()), .starsUpgradedBySender = int64( data.vupgrade_stars().value_or_empty()), + .giftPrepayUpgradeHash = qs( + data.vprepaid_upgrade_hash().value_or_empty()), .fromId = (data.vfrom_id() ? peerFromMTP(*data.vfrom_id()) : PeerId()), diff --git a/Telegram/SourceFiles/boxes/star_gift_box.cpp b/Telegram/SourceFiles/boxes/star_gift_box.cpp index 961171463e..31c5df9afe 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_box.cpp @@ -2086,6 +2086,23 @@ void ShowGiftUpgradedToast( } } +void ShowUpgradeGiftedToast( + base::weak_ptr weak, + not_null peer) { + if (const auto strong = weak.get()) { + strong->showToast({ + .title = tr::lng_gift_upgrade_gifted_title(tr::now), + .text = (peer->isBroadcast() + ? tr::lng_gift_upgrade_gifted_about_channel + : tr::lng_gift_upgrade_gifted_about)( + tr::now, + lt_name, + peer->shortName()), + .duration = kUpgradeDoneToastDuration, + }); + } +} + void SendStarsFormRequest( std::shared_ptr show, Settings::SmallBalanceResult result, @@ -2138,9 +2155,9 @@ void UpgradeGift( if (owner) { owner->owner().nextForUpgradeGiftInvalidate(owner); } - if (updates) { - ShowGiftUpgradedToast(strong, session, *updates); - } + } + if (updates) { + ShowGiftUpgradedToast(weak, session, *updates); } } done(result); @@ -2170,6 +2187,30 @@ void UpgradeGift( std::move(formDone)); } +void GiftUpgrade( + not_null window, + not_null peer, + QString giftPrepayUpgradeHash, + int stars, + Fn done) { + const auto weak = base::make_weak(window); + auto formDone = [=]( + Payments::CheckoutResult result, + const MTPUpdates *updates) { + if (result == Payments::CheckoutResult::Paid) { + ShowUpgradeGiftedToast(weak, peer); + } + done(result); + }; + using Flag = MTPDinputInvoiceStarGiftUpgrade::Flag; + RequestStarsFormAndSubmit( + window->uiShow(), + MTP_inputInvoiceStarGiftPrepaidUpgrade( + peer->input, + MTP_string(giftPrepayUpgradeHash)), + std::move(formDone)); +} + void SoldOutBox( not_null box, not_null window, @@ -4904,15 +4945,33 @@ void UpgradeBox( infoRow( tr::lng_gift_upgrade_unique_title(), - tr::lng_gift_upgrade_unique_about(), + (args.savedId + ? tr::lng_gift_upgrade_unique_about() + : (args.peer->isBroadcast() + ? tr::lng_gift_upgrade_unique_about_channel + : tr::lng_gift_upgrade_unique_about_user)( + lt_name, + rpl::single(args.peer->shortName()))), &st::menuIconUnique); infoRow( tr::lng_gift_upgrade_transferable_title(), - tr::lng_gift_upgrade_transferable_about(), + (args.savedId + ? tr::lng_gift_upgrade_transferable_about() + : (args.peer->isBroadcast() + ? tr::lng_gift_upgrade_transferable_about_channel + : tr::lng_gift_upgrade_transferable_about_user)( + lt_name, + rpl::single(args.peer->shortName()))), &st::menuIconReplace); infoRow( tr::lng_gift_upgrade_tradable_title(), - tr::lng_gift_upgrade_tradable_about(), + (args.savedId + ? tr::lng_gift_upgrade_tradable_about() + : (args.peer->isBroadcast() + ? tr::lng_gift_upgrade_tradable_about_channel + : tr::lng_gift_upgrade_tradable_about_user)( + lt_name, + rpl::single(args.peer->shortName()))), &st::menuIconTradable); struct State { @@ -4920,9 +4979,11 @@ void UpgradeBox( bool preserveDetails = false; }; const auto state = std::make_shared(); - const auto preview = !args.savedId; + const auto gifting = !args.savedId + && !args.giftPrepayUpgradeHash.isEmpty(); + const auto preview = !args.savedId && !gifting; - if (!preview) { + if (!preview && !gifting) { const auto skip = st::defaultVerticalListSkip; container->add( object_ptr(container), @@ -4946,6 +5007,9 @@ void UpgradeBox( } box->setStyle(preview ? st::giftBox : st::upgradeGiftBox); + if (gifting) { + box->setWidth(st::boxWideWidth); + } const auto cost = args.cost; auto buttonText = preview ? tr::lng_box_ok() : rpl::single(QString()); @@ -4969,11 +5033,18 @@ void UpgradeBox( } } }; - UpgradeGift(controller, args.savedId, keepDetails, cost, done); + if (gifting) { + GiftUpgrade( + controller, + args.peer, + args.giftPrepayUpgradeHash, + cost, + done); + } else { + UpgradeGift(controller, args.savedId, keepDetails, cost, done); + } }); if (!preview) { - auto helper = Ui::Text::CustomEmojiHelper(); - auto star = helper.paletteDependent(Ui::Earn::IconCreditsEmoji()); SetButtonMarkedLabel( button, (cost @@ -4985,7 +5056,7 @@ void UpgradeBox( CreditsAmount{ cost }))), Ui::Text::WithEntities) : tr::lng_gift_upgrade_confirm(Ui::Text::WithEntities)), - helper.context(), + {}, st::creditsBoxButtonLabel, &st::giftBox.button.textFg); } diff --git a/Telegram/SourceFiles/boxes/star_gift_box.h b/Telegram/SourceFiles/boxes/star_gift_box.h index 39698139c5..5f0e305f19 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.h +++ b/Telegram/SourceFiles/boxes/star_gift_box.h @@ -110,6 +110,7 @@ struct StarGiftUpgradeArgs { Fn ready; not_null peer; Data::SavedStarGiftId savedId; + QString giftPrepayUpgradeHash; int cost = 0; bool canAddSender = false; bool canAddComment = false; diff --git a/Telegram/SourceFiles/data/data_credits.h b/Telegram/SourceFiles/data/data_credits.h index 7a82c49f93..45d1f9d9bd 100644 --- a/Telegram/SourceFiles/data/data_credits.h +++ b/Telegram/SourceFiles/data/data_credits.h @@ -71,6 +71,7 @@ struct CreditsHistoryEntry final { uint64 bareEntryOwnerId = 0; uint64 giftChannelSavedId = 0; uint64 stargiftId = 0; + QString giftPrepayUpgradeHash; std::shared_ptr uniqueGift; Fn()> pinnedSavedGifts; uint64 nextToUpgradeStickerId = 0; diff --git a/Telegram/SourceFiles/data/data_star_gift.h b/Telegram/SourceFiles/data/data_star_gift.h index b44707aaf9..becf3777c6 100644 --- a/Telegram/SourceFiles/data/data_star_gift.h +++ b/Telegram/SourceFiles/data/data_star_gift.h @@ -154,6 +154,7 @@ struct SavedStarGift { TextWithEntities message; int64 starsConverted = 0; int64 starsUpgradedBySender = 0; + QString giftPrepayUpgradeHash; PeerId fromId = 0; TimeId date = 0; bool upgradable = false; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 788456e7da..783121f7f8 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -5839,12 +5839,17 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { auto prepareStarGift = [&]( const MTPDmessageActionStarGift &action) { auto result = PreparedServiceText(); + const auto upgradeGifted = action.is_prepaid_upgrade(); const auto isSelf = _from->isSelf(); const auto peer = isSelf ? _history->peer : _from; const auto stars = action.vgift().match([&]( const MTPDstarGift &data) { - return uint64(data.vstars().v) - + uint64(action.vupgrade_stars().value_or_empty()); + return upgradeGifted + ? uint64(action.vupgrade_stars().value_or_empty()) + : action.is_upgrade_separate() + ? uint64(data.vstars().v) + : (uint64(data.vstars().v) + + uint64(action.vupgrade_stars().value_or_empty())); }, [](const MTPDstarGiftUnique &) { return uint64(); }); @@ -5876,30 +5881,54 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { const auto fromId = action.vfrom_id() ? peerFromMTP(*action.vfrom_id()) : PeerId(); - const auto from = fromId ? peer->owner().peer(fromId) : peer; + const auto from = fromId + ? peer->owner().peer(fromId).get() + : nullptr; const auto channel = peer->owner().channel( peerToChannel(giftPeer)); - if (from->isSelf()) { + if (!from || from->isSelf()) { result.links.push_back(channel->createOpenLink()); - result.text = tr::lng_action_gift_sent_self_channel( - tr::now, - lt_name, - Ui::Text::Link(channel->name(), 1), - lt_cost, - cost, - Ui::Text::WithEntities); + if (upgradeGifted) { + result.text = tr::lng_action_gift_sent_upgrade_self_channel( + tr::now, + lt_cost, + cost, + lt_name, + Ui::Text::Link(channel->name(), 1), + Ui::Text::WithEntities); + } else { + result.text = tr::lng_action_gift_sent_self_channel( + tr::now, + lt_name, + Ui::Text::Link(channel->name(), 1), + lt_cost, + cost, + Ui::Text::WithEntities); + } } else { result.links.push_back(from->createOpenLink()); result.links.push_back(channel->createOpenLink()); - result.text = tr::lng_action_gift_sent_channel( - tr::now, - lt_user, - Ui::Text::Link(from->shortName(), 1), - lt_name, - Ui::Text::Link(channel->name(), 2), - lt_cost, - cost, - Ui::Text::WithEntities); + if (upgradeGifted) { + result.text = tr::lng_action_gift_sent_upgrade_self_other( + tr::now, + lt_cost, + cost, + lt_name, + Ui::Text::Link(channel->name(), 2), + lt_user, + Ui::Text::Link(from->shortName(), 1), + Ui::Text::WithEntities); + } else { + result.text = tr::lng_action_gift_sent_channel( + tr::now, + lt_user, + Ui::Text::Link(from->shortName(), 1), + lt_name, + Ui::Text::Link(channel->name(), 2), + lt_cost, + cost, + Ui::Text::WithEntities); + } } } else if (anonymous || _history->peer->isSelf()) { result.text = (anonymous @@ -5909,6 +5938,57 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { lt_cost, cost, Ui::Text::WithEntities); + } else if (upgradeGifted) { + // Who sent the gift. + const auto fromId = action.vfrom_id() + ? peerFromMTP(*action.vfrom_id()) + : PeerId(); + const auto from = fromId + ? peer->owner().peer(fromId).get() + : nullptr; + if (isSelf) { + result.links.push_back(peer->createOpenLink()); + if (!from || from->isSelf()) { + result.text = tr::lng_action_gift_sent_upgrade_self( + tr::now, + lt_cost, + cost, + Ui::Text::WithEntities); + } else { + result.links.push_back(from->createOpenLink()); + result.text = tr::lng_action_gift_sent_upgrade_self_other( + tr::now, + lt_cost, + cost, + lt_name, + Ui::Text::Link(peer->shortName(), 1), + lt_user, + Ui::Text::Link(from->shortName(), 2), + Ui::Text::WithEntities); + } + } else { + result.links.push_back(peer->createOpenLink()); + if (from && from != peer && !from->isSelf()) { + result.links.push_back(from->createOpenLink()); + result.text = tr::lng_action_gift_sent_upgrade_other( + tr::now, + lt_from, + Ui::Text::Link(peer->shortName(), 1), + lt_cost, + cost, + lt_user, + Ui::Text::Link(from->shortName(), 2), + Ui::Text::WithEntities); + } else { + result.text = tr::lng_action_gift_sent_upgrade( + tr::now, + lt_from, + Ui::Text::Link(peer->shortName(), 1), + lt_cost, + cost, + Ui::Text::WithEntities); + } + } } else { if (!isSelf) { result.links.push_back(peer->createOpenLink()); @@ -5950,6 +6030,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { : PeerId(); const auto service = _from->isServiceUser(); const auto toChannel = service && peerIsChannel(giftPeer); + const auto upgradeHelped = action.is_prepaid_upgrade(); const auto peer = isSelf ? _history->peer : _from; const auto fromId = action.vfrom_id() ? peerFromMTP(*action.vfrom_id()) @@ -6003,7 +6084,22 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { } result.links.push_back(channel->createOpenLink()); } else { - if (!from->isServiceUser() && !_history->peer->isSelf()) { + if (upgradeHelped) { + result.links.push_back(peer->createOpenLink()); + if (isSelf) { + result.text = tr::lng_action_gift_upgraded_helped_self( + tr::now, + lt_user, + Ui::Text::Link(peer->shortName(), 1), + Ui::Text::WithEntities); + } else { + result.text = tr::lng_action_gift_upgraded_helped( + tr::now, + lt_user, + Ui::Text::Link(peer->shortName(), 1), + Ui::Text::WithEntities); + } + } else if (!from->isServiceUser() && !_history->peer->isSelf()) { if (!resale || !isSelf) { result.links.push_back(from->createOpenLink()); } diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 5612c29328..d3264e2c0d 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -185,8 +185,8 @@ messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector = MessageAction; @@ -1504,6 +1504,7 @@ inputInvoiceStarGiftTransfer#4a5f5bd9 stargift:InputSavedStarGift to_id:InputPee inputInvoicePremiumGiftStars#dabab2ef flags:# user_id:InputUser months:int message:flags.0?TextWithEntities = InputInvoice; inputInvoiceBusinessBotTransferStars#f4997e42 bot:InputUser stars:long = InputInvoice; inputInvoiceStarGiftResale#c39f5324 flags:# ton:flags.0?true slug:string to_id:InputPeer = InputInvoice; +inputInvoiceStarGiftPrepaidUpgrade#9a0b48b8 peer:InputPeer hash:string = InputInvoice; payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice; @@ -1853,7 +1854,7 @@ starsTransactionPeerAPI#f9677aad = StarsTransactionPeer; starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption; -starsTransaction#13659eb0 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true stargift_upgrade:flags.18?true business_transfer:flags.21?true stargift_resale:flags.22?true posts_search:flags.24?true id:string amount:StarsAmount date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector subscription_period:flags.12?int giveaway_post_id:flags.13?int stargift:flags.14?StarGift floodskip_number:flags.15?int starref_commission_permille:flags.16?int starref_peer:flags.17?Peer starref_amount:flags.17?StarsAmount paid_messages:flags.19?int premium_gift_months:flags.20?int ads_proceeds_from_date:flags.23?int ads_proceeds_to_date:flags.23?int = StarsTransaction; +starsTransaction#13659eb0 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true stargift_upgrade:flags.18?true business_transfer:flags.21?true stargift_resale:flags.22?true posts_search:flags.24?true stargift_prepaid_upgrade:flags.25?true id:string amount:StarsAmount date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector subscription_period:flags.12?int giveaway_post_id:flags.13?int stargift:flags.14?StarGift floodskip_number:flags.15?int starref_commission_permille:flags.16?int starref_peer:flags.17?Peer starref_amount:flags.17?StarsAmount paid_messages:flags.19?int premium_gift_months:flags.20?int ads_proceeds_from_date:flags.23?int ads_proceeds_to_date:flags.23?int = StarsTransaction; payments.starsStatus#6c9ce8ed flags:# balance:StarsAmount subscriptions:flags.1?Vector subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector next_offset:flags.0?string chats:Vector users:Vector = payments.StarsStatus; @@ -1941,7 +1942,7 @@ payments.uniqueStarGift#caa2f60b gift:StarGift users:Vector = payments.Uni messages.webPagePreview#b53e8b21 media:MessageMedia users:Vector = messages.WebPagePreview; -savedStarGift#1ea646df flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true pinned_to_top:flags.12?true from_id:flags.1?Peer date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int saved_id:flags.11?long convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long can_transfer_at:flags.13?int can_resell_at:flags.14?int collection_id:flags.15?Vector = SavedStarGift; +savedStarGift#19a9b572 flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true pinned_to_top:flags.12?true from_id:flags.1?Peer date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int saved_id:flags.11?long convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long can_transfer_at:flags.13?int can_resell_at:flags.14?int collection_id:flags.15?Vector prepaid_upgrade_hash:flags.16?string = SavedStarGift; payments.savedStarGifts#95f389b1 flags:# count:int chat_notifications_enabled:flags.1?Bool gifts:Vector next_offset:flags.0?string chats:Vector users:Vector = payments.SavedStarGifts; diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 0d60b20c62..e1845fc39f 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -1832,6 +1832,14 @@ void GenericCreditsEntryBox( ToggleStarGiftSaved(show, savedId, save, done); }; + const auto canUpgrade = e.stargiftId + && e.canUpgradeGift + && (e.in || giftToSelf || giftToChannelCanManage) + && !e.uniqueGift; + const auto canUpgradeFree = canUpgrade && (e.starsUpgradedBySender > 0); + const auto canGiftUpgrade = !e.uniqueGift + && !e.in + && !e.giftPrepayUpgradeHash.isEmpty(); const auto upgradeGuard = std::make_shared(); const auto upgrade = [=] { const auto window = show->resolveWindow(); @@ -1840,7 +1848,7 @@ void GenericCreditsEntryBox( } *upgradeGuard = true; const auto savedId = EntryToSavedStarGiftId(&window->session(), e); - const auto openWhenDone = giftToChannel + const auto openWhenDone = (giftToChannel || canGiftUpgrade) ? window->session().data().peer(PeerId(e.bareGiftOwnerId)).get() : starGiftSender; using namespace Ui; @@ -1850,6 +1858,7 @@ void GenericCreditsEntryBox( .ready = [=](bool) { *upgradeGuard = false; }, .peer = openWhenDone, .savedId = savedId, + .giftPrepayUpgradeHash = e.giftPrepayUpgradeHash, .cost = e.starsUpgradedBySender ? 0 : e.starsToUpgrade, .canAddSender = !giftToSelf && !e.anonymous, .canAddComment = (!giftToSelf @@ -1860,11 +1869,6 @@ void GenericCreditsEntryBox( || (e.starsUpgradedBySender && !e.anonymous)), }); }; - const auto canUpgrade = e.stargiftId - && e.canUpgradeGift - && (e.in || giftToSelf || giftToChannelCanManage) - && !e.uniqueGift; - const auto canUpgradeFree = canUpgrade && (e.starsUpgradedBySender > 0); if (isStarGift && e.id.isEmpty()) { const auto convert = [=, weak = base::make_weak(box)] { @@ -2097,6 +2101,8 @@ void GenericCreditsEntryBox( ? tr::lng_gift_upgrade_free() : canUpgrade ? tr::lng_gift_unique_upgrade() + : canGiftUpgrade + ? tr::lng_gift_unique_gift_upgrade() : (canToggle && !e.savedToProfile) ? (e.giftChannelSavedId ? tr::lng_gift_show_on_channel @@ -2169,7 +2175,7 @@ void GenericCreditsEntryBox( e.giftResaleForceTon, to, crl::guard(box, [=] { box->closeBox(); })); - } else if (canUpgrade) { + } else if (canUpgrade || canGiftUpgrade) { upgrade(); } else if (canToggle && !e.savedToProfile) { toggleVisibility(true); @@ -2348,6 +2354,7 @@ Data::CreditsHistoryEntry SavedStarGiftEntry( .bareEntryOwnerId = chatGiftPeer ? chatGiftPeer->id.value : 0, .giftChannelSavedId = data.manageId.chatSavedId(), .stargiftId = data.info.id, + .giftPrepayUpgradeHash = data.giftPrepayUpgradeHash, .uniqueGift = data.info.unique, .peerType = Data::CreditsHistoryEntry::PeerType::Peer, .limitedCount = data.info.limitedCount,