2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-22 10:17:10 +00:00

Allow switch resale display to TON.

This commit is contained in:
John Preston 2025-07-30 12:21:25 +04:00
parent 9bc26b0068
commit 170544f68d
11 changed files with 94 additions and 33 deletions

View File

@ -3759,6 +3759,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_resale_symbol" = "Symbol";
"lng_gift_resale_symbols#one" = "{count} Symbol";
"lng_gift_resale_symbols#other" = "{count} Symbols";
"lng_gift_resale_switch_to" = "Switch to {currency}";
"lng_gift_resale_early" = "You will be able to resell this gift in {duration}.";
"lng_gift_transfer_early" = "You will be able to transfer this gift in {duration}.";
"lng_gift_resale_transfer_early_title" = "Try Later";

View File

@ -2842,7 +2842,10 @@ void SendGiftBox(
Settings::GlobalStarGiftBox,
window->uiShow(),
star->info,
peer->id,
Settings::StarGiftResaleInfo{
.recipientId = peer->id,
.forceTon = star->forceTon,
},
Settings::CreditsEntryBoxStyleOverrides()));
} else if (star && star->resale) {
const auto id = star->info.id;
@ -3232,7 +3235,6 @@ void GiftResaleBox(
not_null<PeerData*> peer,
ResaleGiftsDescriptor descriptor) {
box->setWidth(st::boxWideWidth);
box->addButton(tr::lng_create_group_back(), [=] { box->closeBox(); });
// Create a proper vertical layout for the title
const auto titleWrap = box->setPinnedToTopContent(
@ -3273,12 +3275,29 @@ void GiftResaleBox(
rpl::event_stream<> updated;
ResaleGiftsDescriptor data;
rpl::variable<ResaleFilter> filter;
rpl::variable<bool> ton;
rpl::lifetime loading;
int lastMinHeight = 0;
};
const auto state = content->lifetime().make_state<State>();
state->data = std::move(descriptor);
box->addButton(tr::lng_create_group_back(), [=] { box->closeBox(); });
#ifndef OS_MAC_STORE
const auto currency = box->addLeftButton(rpl::single(QString()), [=] {
state->ton = !state->ton.current();
state->updated.fire({});
});
currency->setText(tr::lng_gift_resale_switch_to(
lt_currency,
rpl::conditional(
state->ton.value(),
rpl::single(Ui::Text::IconEmoji(&st::starIconEmoji)),
rpl::single(Ui::Text::IconEmoji(&st::tonIconEmoji))),
Ui::Text::WithEntities));
#endif
box->heightValue() | rpl::start_with_next([=](int height) {
if (height > state->lastMinHeight) {
state->lastMinHeight = height;
@ -3340,9 +3359,11 @@ void GiftResaleBox(
) | rpl::map([=] {
auto result = GiftsDescriptor();
const auto selfId = window->session().userPeerId();
const auto forceTon = state->ton.current();
for (const auto &gift : state->data.list) {
result.list.push_back(GiftTypeStars{
.info = gift,
.forceTon = forceTon,
.resale = true,
.mine = (gift.unique->ownerId == selfId),
});

View File

@ -676,6 +676,7 @@ void ShowTransferGiftBox(
void ShowBuyResaleGiftBox(
std::shared_ptr<ChatHelpers::Show> show,
std::shared_ptr<Data::UniqueGift> gift,
bool forceTon,
not_null<PeerData*> to,
Fn<void()> closeParentBox) {
show->show(Box([=](not_null<Ui::GenericBox*> box) {
@ -684,7 +685,7 @@ void ShowBuyResaleGiftBox(
bool sent = false;
};
const auto state = std::make_shared<State>();
state->ton = gift->onlyAcceptTon;
state->ton = gift->onlyAcceptTon || forceTon;
if (gift->onlyAcceptTon) {
box->addRow(
@ -699,7 +700,9 @@ void ShowBuyResaleGiftBox(
object_ptr<Ui::SubTabs>(
box,
Ui::SubTabsOptions{
.selected = u"stars"_q,
.selected = (state->ton.current()
? u"ton"_q
: u"stars"_q),
.centered = true,
},
std::vector<Ui::SubTabsTab>{

View File

@ -35,6 +35,7 @@ void ShowTransferGiftBox(
void ShowBuyResaleGiftBox(
std::shared_ptr<ChatHelpers::Show> show,
std::shared_ptr<Data::UniqueGift> gift,
bool forceTon,
not_null<PeerData*> to,
Fn<void()> closeParentBox);

View File

@ -1945,7 +1945,12 @@ void ResolveAndShowUniqueGift(
session->data().processUsers(data.vusers());
if (const auto gift = Api::FromTL(session, data.vgift())) {
using namespace ::Settings;
show->show(Box(GlobalStarGiftBox, show, *gift, PeerId(), st));
show->show(Box(
GlobalStarGiftBox,
show,
*gift,
StarGiftResaleInfo(),
st));
}
}).fail([=](const MTP::Error &error) {
clear();

View File

@ -102,6 +102,7 @@ struct CreditsHistoryEntry final {
bool giftRefunded : 1 = false;
bool giftUpgraded : 1 = false;
bool giftResale : 1 = false;
bool giftResaleForceTon : 1 = false;
bool giftPinned : 1 = false;
bool savedToProfile : 1 = false;
bool fromGiftsList : 1 = false;

View File

@ -92,10 +92,9 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
if (_descriptor == descriptor && _resalePrice == resalePrice) {
return;
}
auto player = base::take(_player);
const auto starsType = Ui::Premium::MiniStarsType::SlowStars;
_mediaLifetime.destroy();
unsubscribe();
update();
const auto format = [=](int64 number) {
const auto onlyK = (number < 100'000'000);
@ -161,13 +160,15 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
_price.setMarkedText(
st::semiboldTextStyle,
(data.resale
? (unique
? ((unique && data.forceTon)
? Data::FormatGiftResaleTon(*unique)
: (unique
? _delegate->monostar()
: _delegate->star()).append(' ').append(
format(unique
? unique->starsForResale
: data.info.starsResellMin)
).append(data.info.resellCount > 1 ? "+" : "")
).append(data.info.resellCount > 1 ? "+" : ""))
: (_small && unique && unique->starsForResale)
? Data::FormatGiftResaleAsked(*unique)
: unique
@ -196,11 +197,18 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
Ui::Premium::CreditsIconGradientStops());
}
});
_delegate->sticker(
_resolvedDocument = nullptr;
_documentLifetime = _delegate->sticker(
descriptor
) | rpl::start_with_next([=](not_null<DocumentData*> document) {
_documentLifetime.destroy();
setDocument(document);
}, lifetime());
});
if (_resolvedDocument) {
_documentLifetime.destroy();
}
_patterned = false;
_uniqueBackgroundCache = QImage();
_uniquePatternEmoji = nullptr;
@ -232,16 +240,19 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
}
}
bool GiftButton::documentResolved() const {
return _player || _mediaLifetime;
}
void GiftButton::setDocument(not_null<DocumentData*> document) {
_resolvedDocument = document;
if (_playerDocument == document) {
return;
}
const auto media = document->createMediaView();
media->checkStickerLarge();
media->goodThumbnailWanted();
rpl::single() | rpl::then(
const auto destroyed = base::take(_player);
_playerDocument = nullptr;
_mediaLifetime = rpl::single() | rpl::then(
document->owner().session().downloaderTaskFinished()
) | rpl::filter([=] {
return media->loaded();
@ -269,9 +280,13 @@ void GiftButton::setDocument(not_null<DocumentData*> document) {
st::giftBoxStickerSize);
}
result->setRepaintCallback([=] { update(); });
_playerDocument = media->owner();
_player = std::move(result);
update();
}, _mediaLifetime);
});
if (_playerDocument) {
_mediaLifetime.destroy();
}
}
void GiftButton::setGeometry(QRect inner, QMargins extend) {
@ -627,10 +642,11 @@ void GiftButton::paintEvent(QPaintEvent *e) {
QSize(icon.width() + 2 * add, icon.height() + 2 * add));
p.drawEllipse(rect);
icon.paintInCenter(p, rect);
} else if (unique->nanoTonForResale && unique->onlyAcceptTon) {
} else if (!data.forceTon
&& unique->nanoTonForResale
&& unique->onlyAcceptTon) {
if (_tonIcon.isNull()) {
_tonIcon = Ui::Earn::IconCurrencyColored(
st::tonIconEmojiSize,
_tonIcon = st::tonIconEmoji.icon.instance(
QColor(255, 255, 255));
}
const auto size = _tonIcon.size() / _tonIcon.devicePixelRatio();

View File

@ -65,6 +65,7 @@ struct GiftTypeStars {
PeerData *from = nullptr;
TimeId date = 0;
bool pinnedSelection : 1 = false;
bool forceTon : 1 = false;
bool userpic : 1 = false;
bool pinned : 1 = false;
bool hidden : 1 = false;
@ -160,7 +161,6 @@ private:
int height);
void setDocument(not_null<DocumentData*> document);
[[nodiscard]] bool documentResolved() const;
[[nodiscard]] QMargins currentExtend() const;
void unsubscribe();
@ -188,8 +188,12 @@ private:
QRect _button;
QMargins _extend;
DocumentData *_resolvedDocument = nullptr;
std::unique_ptr<HistoryView::StickerPlayer> _player;
DocumentData *_playerDocument = nullptr;
rpl::lifetime _mediaLifetime;
rpl::lifetime _documentLifetime;
};

View File

@ -1235,14 +1235,17 @@ void GenericCreditsEntryBox(
box->setNoContentMargin(true);
const auto slug = uniqueGift->slug;
const auto forceTon = e.giftResaleForceTon;
auto price = rpl::single(
rpl::empty
) | rpl::then(session->data().giftUpdates(
) | rpl::filter([=](const Data::GiftUpdate &update) {
return (update.action == Data::GiftUpdate::Action::ResaleChange)
&& (update.slug == slug);
}) | rpl::to_empty) | rpl::map([unique = e.uniqueGift] {
return Data::UniqueGiftResaleAsked(*unique);
}) | rpl::to_empty) | rpl::map([forceTon, unique = e.uniqueGift] {
return forceTon
? Data::UniqueGiftResaleTon(*unique)
: Data::UniqueGiftResaleAsked(*unique);
});
auto change = [=] {
const auto style = st.giftWearBox
@ -2091,6 +2094,7 @@ void GenericCreditsEntryBox(
ShowBuyResaleGiftBox(
show,
e.uniqueGift,
e.giftResaleForceTon,
to,
crl::guard(box, [=] { box->closeBox(); }));
} else if (canUpgradeFree) {
@ -2102,7 +2106,7 @@ void GenericCreditsEntryBox(
}
});
if (canBuyResold) {
if (uniqueGift->onlyAcceptTon) {
if (uniqueGift->onlyAcceptTon || e.giftResaleForceTon) {
button->setText(rpl::single(QString()));
Ui::SetButtonTwoLabels(
button,
@ -2205,7 +2209,7 @@ void GlobalStarGiftBox(
not_null<Ui::GenericBox*> box,
std::shared_ptr<ChatHelpers::Show> show,
const Data::StarGift &data,
PeerId resaleRecipientId,
StarGiftResaleInfo resale,
CreditsEntryBoxStyleOverrides st) {
const auto selfId = show->session().userPeerId();
const auto ownerId = data.unique ? data.unique->ownerId.value : 0;
@ -2216,8 +2220,8 @@ void GlobalStarGiftBox(
.credits = CreditsAmount(data.stars),
.bareGiftStickerId = data.document->id,
.bareGiftOwnerId = ownerId,
.bareGiftResaleRecipientId = ((resaleRecipientId != selfId)
? resaleRecipientId.value
.bareGiftResaleRecipientId = ((resale.recipientId != selfId)
? resale.recipientId.value
: 0),
.stargiftId = data.id,
.uniqueGift = data.unique,
@ -2225,6 +2229,7 @@ void GlobalStarGiftBox(
.limitedCount = data.limitedCount,
.limitedLeft = data.limitedLeft,
.stargift = true,
.giftResaleForceTon = resale.forceTon,
.fromGiftSlug = true,
.in = (ownerId == show->session().userPeerId().value),
.gift = true,

View File

@ -155,11 +155,16 @@ void CreditsPrizeBox(
not_null<Window::SessionController*> controller,
const Data::GiftCode &data,
TimeId date);
struct StarGiftResaleInfo {
PeerId recipientId;
bool forceTon = false;
};
void GlobalStarGiftBox(
not_null<Ui::GenericBox*> box,
std::shared_ptr<ChatHelpers::Show> show,
const Data::StarGift &data,
PeerId resaleRecipientId,
StarGiftResaleInfo resale,
CreditsEntryBoxStyleOverrides st = {});
[[nodiscard]] Data::CreditsHistoryEntry SavedStarGiftEntry(

View File

@ -85,7 +85,6 @@ tonIconEmoji: IconEmoji {
icon: icon{{ "payments/ton_emoji-18x18", currencyFg }};
padding: margins(0px, 1px, 0px, 0px);
}
tonIconEmojiSize: 18px;
creditsHistoryEntryTypeAds: icon {{ "folders/folders_channels", premiumButtonFg }};