diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 983e6da4a1..0176d9484e 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3421,6 +3421,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_stars_link" = "What are Stars >"; "lng_gift_stars_limited" = "limited"; "lng_gift_stars_sold_out" = "sold out"; +"lng_gift_stars_resale" = "resale"; "lng_gift_stars_tabs_all" = "All Gifts"; "lng_gift_stars_tabs_my" = "My Gifts"; "lng_gift_stars_tabs_limited" = "Limited"; diff --git a/Telegram/SourceFiles/api/api_premium.cpp b/Telegram/SourceFiles/api/api_premium.cpp index be3ead5afc..63b9323c6f 100644 --- a/Telegram/SourceFiles/api/api_premium.cpp +++ b/Telegram/SourceFiles/api/api_premium.cpp @@ -799,6 +799,7 @@ std::optional FromTL( return gift.match([&](const MTPDstarGift &data) { const auto document = session->data().processDocument( data.vsticker()); + const auto resellPrice = data.vresell_min_stars().value_or_empty(); const auto remaining = data.vavailability_remains(); const auto total = data.vavailability_total(); if (!document->sticker()) { @@ -809,7 +810,9 @@ std::optional FromTL( .stars = int64(data.vstars().v), .starsConverted = int64(data.vconvert_stars().v), .starsToUpgrade = int64(data.vupgrade_stars().value_or_empty()), + .starsResellMin = int64(resellPrice), .document = document, + .resellCount = int(data.vavailability_resale().value_or_empty()), .limitedLeft = remaining.value_or_empty(), .limitedCount = total.value_or_empty(), .firstSaleDate = data.vfirst_sale_date().value_or_empty(), diff --git a/Telegram/SourceFiles/boxes/star_gift_box.cpp b/Telegram/SourceFiles/boxes/star_gift_box.cpp index 4247e936c3..bda9b868e5 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_box.cpp @@ -859,9 +859,15 @@ void PreviewWrap::paintEvent(QPaintEvent *e) { list.reserve(gifts.size()); for (auto &gift : gifts) { list.push_back({ .info = gift }); + if (gift.resellCount > 0) { + list.push_back({ .info = gift, .resale = true }); + } } ranges::stable_sort(list, [](const auto &a, const auto &b) { - return a.info.soldOut < b.info.soldOut; + const auto soldOut = [](const auto &gift) { + return gift.info.soldOut && !gift.resale; + }; + return soldOut(a) < soldOut(b); }); auto &map = Map[session]; diff --git a/Telegram/SourceFiles/data/data_star_gift.h b/Telegram/SourceFiles/data/data_star_gift.h index c529be692e..fd2f6bb5e1 100644 --- a/Telegram/SourceFiles/data/data_star_gift.h +++ b/Telegram/SourceFiles/data/data_star_gift.h @@ -62,7 +62,9 @@ struct StarGift { int64 stars = 0; int64 starsConverted = 0; int64 starsToUpgrade = 0; + int64 starsResellMin = 0; not_null document; + int resellCount = 0; int limitedLeft = 0; int limitedCount = 0; TimeId firstSaleDate = 0; diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp index fb014da15a..b143d03975 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.cpp @@ -141,7 +141,11 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) { } _price.setMarkedText( st::semiboldTextStyle, - (unique + (data.resale + ? _delegate->star().append(' ').append( + Lang::FormatCountDecimal(data.info.starsResellMin) + ).append(data.info.resellCount > 0 ? "+" : "") + : unique ? tr::lng_gift_transfer_button( tr::now, Ui::Text::WithEntities) @@ -152,7 +156,10 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) { if (!_stars) { _stars.emplace(this, true, starsType); } - if (unique) { + if (data.resale) { + _stars->setColorOverride( + Ui::Premium::CreditsIconGradientStops()); + } else if (unique) { const auto white = QColor(255, 255, 255); _stars->setColorOverride(QGradientStops{ { 0., anim::with_alpha(white, .3) }, @@ -491,10 +498,12 @@ void GiftButton::paintEvent(QPaintEvent *e) { && !data.userpic && !data.info.limitedLeft; return GiftBadge{ - .text = (soldOut - ? tr::lng_gift_stars_sold_out(tr::now) + .text = (data.resale + ? tr::lng_gift_stars_resale(tr::now) : (unique && pinned) ? ('#' + QString::number(unique->number)) + : soldOut + ? tr::lng_gift_stars_sold_out(tr::now) : (!data.userpic && !data.info.unique) ? tr::lng_gift_stars_limited(tr::now) : (count == 1) @@ -505,7 +514,9 @@ void GiftButton::paintEvent(QPaintEvent *e) { (((count % 1000) && (count < 10'000)) ? Lang::FormatCountDecimal(count) : Lang::FormatCountToShort(count).string))), - .bg1 = (unique + .bg1 = (data.resale + ? st::boxTextFgGood->c + : unique ? unique->backdrop.edgeColor : soldOut ? st::attentionButtonFg->c 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 aa852493a1..16658c6beb 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_common.h @@ -68,6 +68,7 @@ struct GiftTypeStars { bool userpic : 1 = false; bool pinned : 1 = false; bool hidden : 1 = false; + bool resale : 1 = false; bool mine : 1 = false; [[nodiscard]] friend inline bool operator==( diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index af06c44507..48e7697aa4 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -184,7 +184,7 @@ messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_am messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long crypto_currency:flags.0?string crypto_amount:flags.0?long transaction_id:flags.1?string = MessageAction; messageActionPrizeStars#b00c47a2 flags:# unclaimed:flags.0?true stars:long transaction_id:string boost_peer:Peer giveaway_msg_id:int = MessageAction; messageActionStarGift#4717e8a4 flags:# name_hidden:flags.0?true saved:flags.2?true converted:flags.3?true upgraded:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true gift:StarGift message:flags.1?TextWithEntities convert_stars:flags.4?long upgrade_msg_id:flags.5?int upgrade_stars:flags.8?long from_id:flags.11?Peer peer:flags.12?Peer saved_id:flags.12?long = MessageAction; -messageActionStarGiftUnique#acdfcb81 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long = MessageAction; +messageActionStarGiftUnique#5f6b75c9 flags:# upgrade:flags.0?true transferred:flags.1?true saved:flags.2?true refunded:flags.5?true gift:StarGift can_export_at:flags.3?int transfer_stars:flags.4?long from_id:flags.6?Peer peer:flags.7?Peer saved_id:flags.7?long resale_stars:flags.8?long = MessageAction; messageActionPaidMessagesRefunded#ac1f1fcd count:int stars:long = MessageAction; messageActionPaidMessagesPrice#bcd71419 stars:long = MessageAction; messageActionConferenceCall#2ffe2f7a flags:# missed:flags.0?true active:flags.1?true video:flags.4?true call_id:long duration:flags.2?int other_participants:flags.3?Vector = MessageAction; @@ -1490,6 +1490,7 @@ inputInvoiceStarGiftUpgrade#4d818d5d flags:# keep_original_details:flags.0?true inputInvoiceStarGiftTransfer#4a5f5bd9 stargift:InputSavedStarGift to_id:InputPeer = InputInvoice; inputInvoicePremiumGiftStars#dabab2ef flags:# user_id:InputUser months:int message:flags.0?TextWithEntities = InputInvoice; inputInvoiceBusinessBotTransferStars#f4997e42 bot:InputUser stars:long = InputInvoice; +inputInvoiceStarGiftResale#63cbc38c slug:string to_id:InputPeer = InputInvoice; payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice; @@ -1887,8 +1888,8 @@ starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption; -starGift#2cc73c8 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long = StarGift; -starGiftUnique#5c62d151 flags:# id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector availability_issued:int availability_total:int gift_address:flags.3?string = StarGift; +starGift#c62aca28 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int availability_resale:flags.4?long convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long resell_min_stars:flags.4?long title:flags.5?string = StarGift; +starGiftUnique#6411db89 flags:# id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector availability_issued:int availability_total:int gift_address:flags.3?string resell_stars:flags.4?long = StarGift; payments.starGiftsNotModified#a388a368 = payments.StarGifts; payments.starGifts#901689ea hash:int gifts:Vector = payments.StarGifts; @@ -1924,7 +1925,7 @@ botVerification#f93cd45c bot_id:long icon:long description:string = BotVerificat starGiftAttributeModel#39d99013 name:string document:Document rarity_permille:int = StarGiftAttribute; starGiftAttributePattern#13acff19 name:string document:Document rarity_permille:int = StarGiftAttribute; -starGiftAttributeBackdrop#94271762 name:string center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = StarGiftAttribute; +starGiftAttributeBackdrop#d93d859c name:string backdrop_id:int center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = StarGiftAttribute; starGiftAttributeOriginalDetails#e0bff26c flags:# sender_id:flags.0?Peer recipient_id:Peer date:int message:flags.1?TextWithEntities = StarGiftAttribute; payments.starGiftUpgradePreview#167bd90b sample_attributes:Vector = payments.StarGiftUpgradePreview; @@ -1964,6 +1965,14 @@ sponsoredPeer#c69708d3 flags:# random_id:bytes peer:Peer sponsor_info:flags.0?st contacts.sponsoredPeersEmpty#ea32b4b1 = contacts.SponsoredPeers; contacts.sponsoredPeers#eb032884 peers:Vector chats:Vector users:Vector = contacts.SponsoredPeers; +starGiftAttributeIdModel#48aaae3c document_id:long = StarGiftAttributeId; +starGiftAttributeIdPattern#4a162433 document_id:long = StarGiftAttributeId; +starGiftAttributeIdBackdrop#1f01c757 backdrop_id:int = StarGiftAttributeId; + +starGiftAttributeCounter#2eb1b658 attribute:StarGiftAttributeId count:int = StarGiftAttributeCounter; + +payments.resaleStarGifts#947a12df flags:# count:int gifts:Vector next_offset:flags.0?string attributes:flags.1?Vector attributes_hash:flags.1?long chats:Vector counters:flags.2?Vector users:Vector = payments.ResaleStarGifts; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -2564,6 +2573,8 @@ payments.getStarGiftWithdrawalUrl#d06e93a8 stargift:InputSavedStarGift password: payments.toggleChatStarGiftNotifications#60eaefa1 flags:# enabled:flags.0?true peer:InputPeer = Bool; payments.toggleStarGiftsPinnedToTop#1513e7b0 peer:InputPeer stargift:Vector = Bool; payments.canPurchaseStore#4fdc5ea7 purpose:InputStorePaymentPurpose = Bool; +payments.getResaleStarGifts#7a5fa236 flags:# sort_by_price:flags.1?true sort_by_num:flags.2?true attributes_hash:flags.0?long gift_id:long attributes:flags.3?Vector offset:string limit:int = payments.ResaleStarGifts; +payments.updateStarGiftPrice#e2d4f33a slug:string resell_stars:long = Updates; stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector software:flags.3?string = messages.StickerSet; stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet; @@ -2689,4 +2700,4 @@ smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool; fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo; -// LAYER 202 +// LAYER 203