mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-22 10:17:10 +00:00
Allow buying gifts resold for TONs.
This commit is contained in:
parent
2a50d0856b
commit
3b1c7dc5e1
@ -646,6 +646,7 @@ PRIVATE
|
||||
data/data_shared_media.h
|
||||
data/data_sparse_ids.cpp
|
||||
data/data_sparse_ids.h
|
||||
data/data_star_gift.cpp
|
||||
data/data_star_gift.h
|
||||
data/data_statistics.h
|
||||
data/data_stories.cpp
|
||||
|
@ -2094,6 +2094,8 @@ void SendStarsFormRequest(
|
||||
)).done([=](const MTPpayments_PaymentResult &result) {
|
||||
result.match([&](const MTPDpayments_paymentResult &data) {
|
||||
session->api().applyUpdates(data.vupdates());
|
||||
session->credits().tonLoad(true);
|
||||
session->credits().load(true);
|
||||
done(Payments::CheckoutResult::Paid, &data.vupdates());
|
||||
}, [&](const MTPDpayments_paymentVerificationNeeded &data) {
|
||||
done(Payments::CheckoutResult::Failed, nullptr);
|
||||
@ -2808,11 +2810,17 @@ void SendGiftBox(
|
||||
using Payments::CheckoutResult;
|
||||
const auto formReady = [=](
|
||||
uint64 formId,
|
||||
uint64 price,
|
||||
CreditsAmount price,
|
||||
std::optional<CheckoutResult> failure) {
|
||||
state->transferRequested = nullptr;
|
||||
if (!failure || *failure == CheckoutResult::Free) {
|
||||
unique->starsForTransfer = price;
|
||||
if (!failure && !price.stars()) {
|
||||
LOG(("API Error: "
|
||||
"Bad transfer invoice currenct."));
|
||||
} else if (!failure
|
||||
|| *failure == CheckoutResult::Free) {
|
||||
unique->starsForTransfer = failure
|
||||
? 0
|
||||
: price.whole();
|
||||
ShowTransferToBox(
|
||||
window,
|
||||
peer,
|
||||
@ -2823,7 +2831,7 @@ void SendGiftBox(
|
||||
done();
|
||||
}
|
||||
};
|
||||
RequestStarsForm(
|
||||
RequestOurForm(
|
||||
window->uiShow(),
|
||||
MTP_inputInvoiceStarGiftTransfer(
|
||||
Api::InputSavedStarGiftId(savedId, unique),
|
||||
@ -4574,12 +4582,7 @@ void UniqueGiftSellBox(
|
||||
};
|
||||
const auto state = box->lifetime().make_state<State>();
|
||||
state->onlyTon = unique->onlyAcceptTon;
|
||||
const auto priceNow = unique->onlyAcceptTon
|
||||
? CreditsAmount(
|
||||
unique->nanoTonForResale / Ui::kNanosInOne,
|
||||
unique->nanoTonForResale % Ui::kNanosInOne,
|
||||
CreditsType::Ton)
|
||||
: CreditsAmount(unique->starsForResale);
|
||||
const auto priceNow = Data::UniqueGiftResaleAsked(*unique);
|
||||
state->price = priceNow
|
||||
? priceNow
|
||||
: price
|
||||
@ -5171,15 +5174,49 @@ void SubmitStarsForm(
|
||||
ready);
|
||||
}
|
||||
|
||||
void RequestStarsForm(
|
||||
void SubmitTonForm(
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
MTPInputInvoice invoice,
|
||||
uint64 formId,
|
||||
CreditsAmount ton,
|
||||
Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done) {
|
||||
const auto ready = [=] {
|
||||
SendStarsFormRequest(
|
||||
show,
|
||||
Settings::SmallBalanceResult::Already,
|
||||
formId,
|
||||
invoice,
|
||||
done);
|
||||
};
|
||||
struct State {
|
||||
rpl::lifetime lifetime;
|
||||
bool success = false;
|
||||
};
|
||||
const auto state = std::make_shared<State>();
|
||||
|
||||
const auto session = &show->session();
|
||||
session->credits().tonLoad();
|
||||
session->credits().tonLoadedValue(
|
||||
) | rpl::filter(rpl::mappers::_1) | rpl::start_with_next([=] {
|
||||
state->lifetime.destroy();
|
||||
|
||||
if (session->credits().tonBalance() < ton) {
|
||||
show->show(Box(InsufficientTonBox, session->user(), ton));
|
||||
} else {
|
||||
ready();
|
||||
}
|
||||
}, state->lifetime);
|
||||
}
|
||||
|
||||
void RequestOurForm(
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
MTPInputInvoice invoice,
|
||||
Fn<void(
|
||||
uint64 formId,
|
||||
uint64 price,
|
||||
CreditsAmount price,
|
||||
std::optional<Payments::CheckoutResult> failure)> done) {
|
||||
const auto fail = [=](Payments::CheckoutResult failure) {
|
||||
done(0, 0, failure);
|
||||
done(0, {}, failure);
|
||||
};
|
||||
show->session().api().request(MTPpayments_GetPaymentForm(
|
||||
MTP_flags(0),
|
||||
@ -5187,10 +5224,24 @@ void RequestStarsForm(
|
||||
MTPDataJSON() // theme_params
|
||||
)).done([=](const MTPpayments_PaymentForm &result) {
|
||||
result.match([&](const MTPDpayments_paymentFormStarGift &data) {
|
||||
const auto prices = data.vinvoice().data().vprices().v;
|
||||
const auto &invoice = data.vinvoice().data();
|
||||
const auto prices = invoice.vprices().v;
|
||||
if (show->valid() && !prices.isEmpty()) {
|
||||
const auto price = prices.front().data().vamount().v;
|
||||
done(data.vform_id().v, price, std::nullopt);
|
||||
const auto currency = qs(invoice.vcurrency());
|
||||
const auto amount = (currency == Ui::kCreditsCurrency)
|
||||
? CreditsAmount(price)
|
||||
: (currency == u"TON"_q)
|
||||
? CreditsAmount(
|
||||
price / Ui::kNanosInOne,
|
||||
price % Ui::kNanosInOne,
|
||||
CreditsType::Ton)
|
||||
: std::optional<CreditsAmount>();
|
||||
if (amount) {
|
||||
done(data.vform_id().v, *amount, std::nullopt);
|
||||
} else {
|
||||
fail(Payments::CheckoutResult::Failed);
|
||||
}
|
||||
} else {
|
||||
fail(Payments::CheckoutResult::Failed);
|
||||
}
|
||||
@ -5214,14 +5265,16 @@ void RequestStarsFormAndSubmit(
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
MTPInputInvoice invoice,
|
||||
Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done) {
|
||||
RequestStarsForm(show, invoice, [=](
|
||||
RequestOurForm(show, invoice, [=](
|
||||
uint64 formId,
|
||||
uint64 price,
|
||||
CreditsAmount price,
|
||||
std::optional<Payments::CheckoutResult> failure) {
|
||||
if (!failure) {
|
||||
SubmitStarsForm(show, invoice, formId, price, done);
|
||||
} else {
|
||||
if (failure) {
|
||||
done(*failure, nullptr);
|
||||
} else if (!price.stars()) {
|
||||
done(Payments::CheckoutResult::Failed, nullptr);
|
||||
} else {
|
||||
SubmitStarsForm(show, invoice, formId, price.whole(), done);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -129,12 +129,18 @@ void SubmitStarsForm(
|
||||
uint64 formId,
|
||||
uint64 price,
|
||||
Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done);
|
||||
void RequestStarsForm(
|
||||
void SubmitTonForm(
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
MTPInputInvoice invoice,
|
||||
uint64 formId,
|
||||
CreditsAmount ton,
|
||||
Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done);
|
||||
void RequestOurForm(
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
MTPInputInvoice invoice,
|
||||
Fn<void(
|
||||
uint64 formId,
|
||||
uint64 price,
|
||||
CreditsAmount price,
|
||||
std::optional<Payments::CheckoutResult> failure)> done);
|
||||
void RequestStarsFormAndSubmit(
|
||||
std::shared_ptr<Main::SessionShow> show,
|
||||
|
@ -487,6 +487,7 @@ void BuyResaleGift(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
not_null<PeerData*> to,
|
||||
std::shared_ptr<Data::UniqueGift> gift,
|
||||
CreditsType type,
|
||||
Fn<void(Payments::CheckoutResult)> done) {
|
||||
auto paymentDone = [=](
|
||||
Payments::CheckoutResult result,
|
||||
@ -504,22 +505,42 @@ void BuyResaleGift(
|
||||
|
||||
using Flag = MTPDinputInvoiceStarGiftResale::Flag;
|
||||
const auto invoice = MTP_inputInvoiceStarGiftResale(
|
||||
MTP_flags(gift->onlyAcceptTon ? Flag::f_ton : Flag()),
|
||||
MTP_flags((type == CreditsType::Ton) ? Flag::f_ton : Flag()),
|
||||
MTP_string(gift->slug),
|
||||
to->input);
|
||||
|
||||
Ui::RequestStarsForm(show, invoice, [=](
|
||||
Ui::RequestOurForm(show, invoice, [=](
|
||||
uint64 formId,
|
||||
uint64 price,
|
||||
CreditsAmount price,
|
||||
std::optional<Payments::CheckoutResult> failure) {
|
||||
if ((type == CreditsType::Ton && price.stars())
|
||||
|| (type == CreditsType::Stars && price.ton())) {
|
||||
paymentDone(Payments::CheckoutResult::Failed, nullptr);
|
||||
return;
|
||||
}
|
||||
const auto submit = [=] {
|
||||
SubmitStarsForm(show, invoice, formId, price, paymentDone);
|
||||
if (price.stars()) {
|
||||
SubmitStarsForm(
|
||||
show,
|
||||
invoice,
|
||||
formId,
|
||||
price.whole(),
|
||||
paymentDone);
|
||||
} else {
|
||||
SubmitTonForm(show, invoice, formId, price, paymentDone);
|
||||
}
|
||||
};
|
||||
const auto was = (type == CreditsType::Ton)
|
||||
? Data::UniqueGiftResaleTon(*gift)
|
||||
: Data::UniqueGiftResaleStars(*gift);
|
||||
if (failure) {
|
||||
paymentDone(*failure, nullptr);
|
||||
} else if (price != gift->starsForResale) {
|
||||
const auto cost = Ui::Text::IconEmoji(&st::starIconEmoji).append(
|
||||
Lang::FormatCountDecimal(price));
|
||||
} else if (price != was) {
|
||||
const auto cost = price.ton()
|
||||
? Ui::Text::IconEmoji(&st::tonIconEmoji).append(
|
||||
Lang::FormatCreditsAmountDecimal(price))
|
||||
: Ui::Text::IconEmoji(&st::starIconEmoji).append(
|
||||
Lang::FormatCountDecimal(price.whole()));
|
||||
const auto cancelled = [=](Fn<void()> close) {
|
||||
paymentDone(Payments::CheckoutResult::Cancelled, nullptr);
|
||||
close();
|
||||
@ -663,16 +684,7 @@ void ShowBuyResaleGiftBox(
|
||||
|
||||
auto transfer = tr::lng_gift_buy_resale_button(
|
||||
lt_cost,
|
||||
rpl::single(gift->onlyAcceptTon
|
||||
? Ui::Text::IconEmoji(
|
||||
&st::tonIconEmoji
|
||||
).append(
|
||||
Lang::FormatCreditsAmountDecimal(CreditsAmount(
|
||||
gift->nanoTonForResale / Ui::kNanosInOne,
|
||||
gift->nanoTonForResale % Ui::kNanosInOne,
|
||||
CreditsType::Ton)))
|
||||
: Ui::Text::IconEmoji(&st::starIconEmoji).append(
|
||||
Lang::FormatCountDecimal(gift->starsForResale))),
|
||||
rpl::single(Data::FormatGiftResaleAsked(*gift)),
|
||||
Ui::Text::WithEntities);
|
||||
|
||||
struct State {
|
||||
@ -697,7 +709,10 @@ void ShowBuyResaleGiftBox(
|
||||
close();
|
||||
}
|
||||
};
|
||||
BuyResaleGift(show, to, gift, done);
|
||||
const auto type = gift->onlyAcceptTon
|
||||
? CreditsType::Ton
|
||||
: CreditsType::Stars;
|
||||
BuyResaleGift(show, to, gift, type, done);
|
||||
};
|
||||
|
||||
Ui::ConfirmBox(box, {
|
||||
@ -709,7 +724,8 @@ void ShowBuyResaleGiftBox(
|
||||
(gift->onlyAcceptTon
|
||||
? tr::lng_action_gift_for_ton(
|
||||
lt_count,
|
||||
rpl::single(gift->nanoTonForResale / 1'000'000'000.),
|
||||
rpl::single(gift->nanoTonForResale
|
||||
/ float64(Ui::kNanosInOne)),
|
||||
Ui::Text::Bold)
|
||||
: tr::lng_action_gift_for_stars(
|
||||
lt_count_decimal,
|
||||
@ -723,7 +739,8 @@ void ShowBuyResaleGiftBox(
|
||||
(gift->onlyAcceptTon
|
||||
? tr::lng_action_gift_for_ton(
|
||||
lt_count,
|
||||
rpl::single(gift->nanoTonForResale / 1'000'000'000.),
|
||||
rpl::single(gift->nanoTonForResale
|
||||
/ float64(Ui::kNanosInOne)),
|
||||
Ui::Text::Bold)
|
||||
: tr::lng_action_gift_for_stars(
|
||||
lt_count_decimal,
|
||||
|
56
Telegram/SourceFiles/data/data_star_gift.cpp
Normal file
56
Telegram/SourceFiles/data/data_star_gift.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "data/data_star_gift.h"
|
||||
|
||||
#include "lang/lang_tag.h"
|
||||
#include "ui/controls/ton_common.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "styles/style_credits.h"
|
||||
|
||||
namespace Data {
|
||||
|
||||
QString UniqueGiftName(const UniqueGift &gift) {
|
||||
return gift.title + u" #"_q + QString::number(gift.number);
|
||||
}
|
||||
|
||||
CreditsAmount UniqueGiftResaleStars(const UniqueGift &gift) {
|
||||
return CreditsAmount(gift.starsForResale);
|
||||
}
|
||||
|
||||
CreditsAmount UniqueGiftResaleTon(const UniqueGift &gift) {
|
||||
return CreditsAmount(
|
||||
gift.nanoTonForResale / Ui::kNanosInOne,
|
||||
gift.nanoTonForResale % Ui::kNanosInOne,
|
||||
CreditsType::Ton);
|
||||
}
|
||||
|
||||
CreditsAmount UniqueGiftResaleAsked(const UniqueGift &gift) {
|
||||
return gift.onlyAcceptTon
|
||||
? UniqueGiftResaleTon(gift)
|
||||
: UniqueGiftResaleStars(gift);
|
||||
}
|
||||
|
||||
TextWithEntities FormatGiftResaleStars(const UniqueGift &gift) {
|
||||
return Ui::Text::IconEmoji(
|
||||
&st::starIconEmoji
|
||||
).append(Lang::FormatCountDecimal(gift.starsForResale));
|
||||
}
|
||||
|
||||
TextWithEntities FormatGiftResaleTon(const UniqueGift &gift) {
|
||||
return Ui::Text::IconEmoji(
|
||||
&st::tonIconEmoji
|
||||
).append(Lang::FormatCreditsAmountDecimal(UniqueGiftResaleTon(gift)));
|
||||
}
|
||||
|
||||
TextWithEntities FormatGiftResaleAsked(const UniqueGift &gift) {
|
||||
return gift.onlyAcceptTon
|
||||
? FormatGiftResaleTon(gift)
|
||||
: FormatGiftResaleStars(gift);
|
||||
}
|
||||
|
||||
} // namespace Data
|
@ -59,9 +59,15 @@ struct UniqueGift {
|
||||
UniqueGiftOriginalDetails originalDetails;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline QString UniqueGiftName(const UniqueGift &gift) {
|
||||
return gift.title + u" #"_q + QString::number(gift.number);
|
||||
}
|
||||
[[nodiscard]] QString UniqueGiftName(const UniqueGift &gift);
|
||||
|
||||
[[nodiscard]] CreditsAmount UniqueGiftResaleStars(const UniqueGift &gift);
|
||||
[[nodiscard]] CreditsAmount UniqueGiftResaleTon(const UniqueGift &gift);
|
||||
[[nodiscard]] CreditsAmount UniqueGiftResaleAsked(const UniqueGift &gift);
|
||||
|
||||
[[nodiscard]] TextWithEntities FormatGiftResaleStars(const UniqueGift &gift);
|
||||
[[nodiscard]] TextWithEntities FormatGiftResaleTon(const UniqueGift &gift);
|
||||
[[nodiscard]] TextWithEntities FormatGiftResaleAsked(const UniqueGift &gift);
|
||||
|
||||
struct StarGift {
|
||||
uint64 id = 0;
|
||||
|
@ -1242,12 +1242,7 @@ void GenericCreditsEntryBox(
|
||||
return (update.action == Data::GiftUpdate::Action::ResaleChange)
|
||||
&& (update.slug == slug);
|
||||
}) | rpl::to_empty) | rpl::map([unique = e.uniqueGift] {
|
||||
return unique->onlyAcceptTon
|
||||
? CreditsAmount(
|
||||
unique->nanoTonForResale / Ui::kNanosInOne,
|
||||
unique->nanoTonForResale % Ui::kNanosInOne,
|
||||
CreditsType::Ton)
|
||||
: CreditsAmount(unique->starsForResale);
|
||||
return Data::UniqueGiftResaleAsked(*unique);
|
||||
});
|
||||
auto change = [=] {
|
||||
const auto style = st.giftWearBox
|
||||
@ -2113,20 +2108,11 @@ void GenericCreditsEntryBox(
|
||||
button,
|
||||
tr::lng_gift_buy_resale_button(
|
||||
lt_cost,
|
||||
rpl::single(Ui::Text::IconEmoji(
|
||||
&st::tonIconEmoji
|
||||
).append(
|
||||
Lang::FormatCreditsAmountDecimal(CreditsAmount(
|
||||
uniqueGift->nanoTonForResale / Ui::kNanosInOne,
|
||||
uniqueGift->nanoTonForResale % Ui::kNanosInOne,
|
||||
CreditsType::Ton)))),
|
||||
rpl::single(Data::FormatGiftResaleTon(*uniqueGift)),
|
||||
Ui::Text::WithEntities),
|
||||
tr::lng_gift_buy_resale_equals(
|
||||
lt_cost,
|
||||
rpl::single(Ui::Text::IconEmoji(
|
||||
&st::starIconEmojiSmall
|
||||
).append(Lang::FormatCountDecimal(
|
||||
uniqueGift->starsForResale))),
|
||||
rpl::single(Data::FormatGiftResaleStars(*uniqueGift)),
|
||||
Ui::Text::WithEntities),
|
||||
st::giftResaleButtonTitle,
|
||||
st::giftResaleButtonSubtitle);
|
||||
|
Loading…
x
Reference in New Issue
Block a user