Allow buying reselling gifts.

This commit is contained in:
John Preston 2025-04-18 18:41:13 +04:00
parent 94e0ac3f54
commit c726bef740
14 changed files with 214 additions and 45 deletions

View file

@ -3447,12 +3447,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_send_limited_left#other" = "{count} left"; "lng_gift_send_limited_left#other" = "{count} left";
"lng_gift_send_button" = "Send a Gift for {cost}"; "lng_gift_send_button" = "Send a Gift for {cost}";
"lng_gift_send_button_self" = "Buy a Gift for {cost}"; "lng_gift_send_button_self" = "Buy a Gift for {cost}";
"lng_gift_buy_resale_title" = "Buy {name}";
"lng_gift_buy_resale_button" = "Buy for {cost}"; "lng_gift_buy_resale_button" = "Buy for {cost}";
"lng_gift_buy_resale_confirm" = "Do you want to buy {gift} for {cost} and gift it to {user}?"; "lng_gift_buy_resale_confirm" = "Do you want to buy {name} for {price} and gift it to {user}?";
"lng_gift_buy_resale_confirm_self" = "Do you want to buy {gift} for {cost}?"; "lng_gift_buy_resale_confirm_self" = "Do you want to buy {name} for {price}?";
"lng_gift_sent_title" = "Gift Sent!"; "lng_gift_sent_title" = "Gift Sent!";
"lng_gift_sent_resale_done" = "{user} has been notified about your gift."; "lng_gift_sent_resale_done" = "{user} has been notified about your gift.";
"lng_gift_sent_resale_done_self" = "{gift} is not yours."; "lng_gift_sent_resale_done_self" = "{gift} is now yours.";
"lng_gift_sent_about#one" = "You spent **{count}** Star from your balance."; "lng_gift_sent_about#one" = "You spent **{count}** Star from your balance.";
"lng_gift_sent_about#other" = "You spent **{count}** Stars from your balance."; "lng_gift_sent_about#other" = "You spent **{count}** Stars from your balance.";
"lng_gift_limited_of_one" = "unique"; "lng_gift_limited_of_one" = "unique";

View file

@ -853,10 +853,10 @@ std::optional<Data::StarGift> FromTL(
? peerFromMTP(*data.vowner_id()) ? peerFromMTP(*data.vowner_id())
: PeerId()), : PeerId()),
.number = data.vnum().v, .number = data.vnum().v,
.starsForResale = int(data.vresell_stars().value_or_empty()),
.model = *model, .model = *model,
.pattern = *pattern, .pattern = *pattern,
}), }),
.starsResellMin = int64(data.vresell_stars().value_or_empty()),
.document = model->document, .document = model->document,
.limitedLeft = (total - data.vavailability_issued().v), .limitedLeft = (total - data.vavailability_issued().v),
.limitedCount = total, .limitedCount = total,

View file

@ -1336,7 +1336,13 @@ void AddStarGiftTable(
}, tooltip->lifetime()); }, tooltip->lifetime());
}; };
if (unique && entry.bareGiftOwnerId) { if (unique && entry.bareGiftResaleRecipientId) {
AddTableRow(
table,
tr::lng_credits_box_history_entry_peer(),
MakePeerTableValue(table, show, PeerId(entry.bareGiftResaleRecipientId)),
st::giveawayGiftCodePeerMargin);
} else if (unique && entry.bareGiftOwnerId) {
const auto ownerId = PeerId(entry.bareGiftOwnerId); const auto ownerId = PeerId(entry.bareGiftOwnerId);
const auto was = std::make_shared<std::optional<CollectibleId>>(); const auto was = std::make_shared<std::optional<CollectibleId>>();
const auto handleChange = [=]( const auto handleChange = [=](

View file

@ -1896,16 +1896,15 @@ void ShowGiftUpgradedToast(
} }
void SendStarsFormRequest( void SendStarsFormRequest(
not_null<Window::SessionController*> controller, std::shared_ptr<Main::SessionShow> show,
Settings::SmallBalanceResult result, Settings::SmallBalanceResult result,
uint64 formId, uint64 formId,
MTPInputInvoice invoice, MTPInputInvoice invoice,
Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done) { Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done) {
using BalanceResult = Settings::SmallBalanceResult; using BalanceResult = Settings::SmallBalanceResult;
const auto session = &controller->session(); const auto session = &show->session();
if (result == BalanceResult::Success if (result == BalanceResult::Success
|| result == BalanceResult::Already) { || result == BalanceResult::Already) {
const auto weak = base::make_weak(controller);
session->api().request(MTPpayments_SendStarsForm( session->api().request(MTPpayments_SendStarsForm(
MTP_long(formId), MTP_long(formId),
invoice invoice
@ -1917,9 +1916,7 @@ void SendStarsFormRequest(
done(Payments::CheckoutResult::Failed, nullptr); done(Payments::CheckoutResult::Failed, nullptr);
}); });
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
if (const auto strong = weak.get()) { show->showToast(error.type());
strong->showToast(error.type());
}
done(Payments::CheckoutResult::Failed, nullptr); done(Payments::CheckoutResult::Failed, nullptr);
}).send(); }).send();
} else if (result == BalanceResult::Cancelled) { } else if (result == BalanceResult::Cancelled) {
@ -1965,7 +1962,7 @@ void UpgradeGift(
} }
using Flag = MTPDinputInvoiceStarGiftUpgrade::Flag; using Flag = MTPDinputInvoiceStarGiftUpgrade::Flag;
RequestStarsFormAndSubmit( RequestStarsFormAndSubmit(
window, window->uiShow(),
MTP_inputInvoiceStarGiftUpgrade( MTP_inputInvoiceStarGiftUpgrade(
MTP_flags(keepDetails ? Flag::f_keep_original_details : Flag()), MTP_flags(keepDetails ? Flag::f_keep_original_details : Flag()),
Api::InputSavedStarGiftId(savedId)), Api::InputSavedStarGiftId(savedId)),
@ -2613,7 +2610,7 @@ void SendGiftBox(
button->setDescriptor(descriptor, GiftButton::Mode::Full); button->setDescriptor(descriptor, GiftButton::Mode::Full);
button->setClickedCallback([=] { button->setClickedCallback([=] {
const auto star = std::get_if<GiftTypeStars>(&descriptor); const auto star = std::get_if<GiftTypeStars>(&descriptor);
if (star && star->info.unique) { if (star && star->info.unique && star->mine) {
const auto done = [=] { const auto done = [=] {
window->session().credits().load(true); window->session().credits().load(true);
window->showPeerHistory(peer); window->showPeerHistory(peer);
@ -2624,7 +2621,14 @@ void SendGiftBox(
star->info.unique, star->info.unique,
star->transferId, star->transferId,
done); done);
} else if (star->resale) { } else if (star && star->info.unique && star->resale) {
window->show(Box(
Settings::GlobalStarGiftBox,
window->uiShow(),
star->info,
peer->id,
Settings::CreditsEntryBoxStyleOverrides()));
} else if (star && star->resale) {
const auto id = star->info.id; const auto id = star->info.id;
if (state->resaleRequestingId == id) { if (state->resaleRequestingId == id) {
return; return;
@ -4460,11 +4464,10 @@ void AddUniqueCloseButton(
} }
void RequestStarsFormAndSubmit( void RequestStarsFormAndSubmit(
not_null<Window::SessionController*> window, std::shared_ptr<Main::SessionShow> show,
MTPInputInvoice invoice, MTPInputInvoice invoice,
Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done) { Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done) {
const auto weak = base::make_weak(window); show->session().api().request(MTPpayments_GetPaymentForm(
window->session().api().request(MTPpayments_GetPaymentForm(
MTP_flags(0), MTP_flags(0),
invoice, invoice,
MTPDataJSON() // theme_params MTPDataJSON() // theme_params
@ -4472,16 +4475,15 @@ void RequestStarsFormAndSubmit(
result.match([&](const MTPDpayments_paymentFormStarGift &data) { result.match([&](const MTPDpayments_paymentFormStarGift &data) {
const auto formId = data.vform_id().v; const auto formId = data.vform_id().v;
const auto prices = data.vinvoice().data().vprices().v; const auto prices = data.vinvoice().data().vprices().v;
const auto strong = weak.get(); if (!show->valid()) {
if (!strong) {
done(Payments::CheckoutResult::Failed, nullptr); done(Payments::CheckoutResult::Failed, nullptr);
return; return;
} }
const auto ready = [=](Settings::SmallBalanceResult result) { const auto ready = [=](Settings::SmallBalanceResult result) {
SendStarsFormRequest(strong, result, formId, invoice, done); SendStarsFormRequest(show, result, formId, invoice, done);
}; };
Settings::MaybeRequestBalanceIncrease( Settings::MaybeRequestBalanceIncrease(
strong->uiShow(), show,
prices.front().data().vamount().v, prices.front().data().vamount().v,
Settings::SmallBalanceDeepLink{}, Settings::SmallBalanceDeepLink{},
ready); ready);
@ -4493,20 +4495,17 @@ void RequestStarsFormAndSubmit(
if (type == u"STARGIFT_EXPORT_IN_PROGRESS"_q) { if (type == u"STARGIFT_EXPORT_IN_PROGRESS"_q) {
done(Payments::CheckoutResult::Cancelled, nullptr); done(Payments::CheckoutResult::Cancelled, nullptr);
} else { } else {
if (const auto strong = weak.get()) { show->showToast(type);
strong->showToast(type);
}
done(Payments::CheckoutResult::Failed, nullptr); done(Payments::CheckoutResult::Failed, nullptr);
} }
}).send(); }).send();
} }
void ShowGiftTransferredToast( void ShowGiftTransferredToast(
base::weak_ptr<Window::SessionController> weak, std::shared_ptr<Main::SessionShow> show,
not_null<PeerData*> to, not_null<PeerData*> to,
const Data::UniqueGift &gift) { const Data::UniqueGift &gift) {
if (const auto strong = weak.get()) { show->showToast({
strong->showToast({
.title = tr::lng_gift_transferred_title(tr::now), .title = tr::lng_gift_transferred_title(tr::now),
.text = tr::lng_gift_transferred_about( .text = tr::lng_gift_transferred_about(
tr::now, tr::now,
@ -4517,7 +4516,24 @@ void ShowGiftTransferredToast(
Ui::Text::WithEntities), Ui::Text::WithEntities),
.duration = kUpgradeDoneToastDuration, .duration = kUpgradeDoneToastDuration,
}); });
}
} }
void ShowResaleGiftBoughtToast(
std::shared_ptr<Main::SessionShow> show,
not_null<PeerData*> to,
const Data::UniqueGift &gift) {
show->showToast({
.title = tr::lng_gift_sent_title(tr::now),
.text = (to->isSelf()
? tr::lng_gift_sent_resale_done_self(
tr::now,
lt_gift,
Data::UniqueGiftName(gift))
: tr::lng_gift_sent_resale_done(
tr::now,
lt_user,
to->shortName())),
.duration = kUpgradeDoneToastDuration,
});
}
} // namespace Ui } // namespace Ui

View file

@ -19,6 +19,10 @@ struct GiftCode;
struct CreditsHistoryEntry; struct CreditsHistoryEntry;
} // namespace Data } // namespace Data
namespace Main {
class SessionShow;
} // namespace Main
namespace Payments { namespace Payments {
enum class CheckoutResult; enum class CheckoutResult;
} // namespace Payments } // namespace Payments
@ -101,12 +105,17 @@ void AddUniqueCloseButton(
Fn<void(not_null<PopupMenu*>)> fillMenu = nullptr); Fn<void(not_null<PopupMenu*>)> fillMenu = nullptr);
void RequestStarsFormAndSubmit( void RequestStarsFormAndSubmit(
not_null<Window::SessionController*> window, std::shared_ptr<Main::SessionShow> show,
MTPInputInvoice invoice, MTPInputInvoice invoice,
Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done); Fn<void(Payments::CheckoutResult, const MTPUpdates *)> done);
void ShowGiftTransferredToast( void ShowGiftTransferredToast(
base::weak_ptr<Window::SessionController> weak, std::shared_ptr<Main::SessionShow> show,
not_null<PeerData*> to,
const Data::UniqueGift &gift);
void ShowResaleGiftBoughtToast(
std::shared_ptr<Main::SessionShow> show,
not_null<PeerData*> to, not_null<PeerData*> to,
const Data::UniqueGift &gift); const Data::UniqueGift &gift);

View file

@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/vertical_list.h" #include "ui/vertical_list.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "styles/style_boxes.h" // peerListSingleRow. #include "styles/style_boxes.h" // peerListSingleRow.
#include "styles/style_credits.h" // starIconEmoji.
#include "styles/style_dialogs.h" // recentPeersSpecialName. #include "styles/style_dialogs.h" // recentPeersSpecialName.
#include "styles/style_layers.h" // boxLabel. #include "styles/style_layers.h" // boxLabel.
@ -431,12 +432,12 @@ void TransferGift(
const MTPUpdates *updates) { const MTPUpdates *updates) {
done(result); done(result);
if (result == Payments::CheckoutResult::Paid) { if (result == Payments::CheckoutResult::Paid) {
if (const auto strong = weak.get()) { session->data().notifyGiftUpdate({
strong->session().data().notifyGiftUpdate({
.id = savedId, .id = savedId,
.action = Data::GiftUpdate::Action::Transfer, .action = Data::GiftUpdate::Action::Transfer,
}); });
Ui::ShowGiftTransferredToast(strong, to, *gift); if (const auto strong = weak.get()) {
Ui::ShowGiftTransferredToast(strong->uiShow(), to, *gift);
} }
} }
}; };
@ -456,13 +457,35 @@ void TransferGift(
return; return;
} }
Ui::RequestStarsFormAndSubmit( Ui::RequestStarsFormAndSubmit(
window, window->uiShow(),
MTP_inputInvoiceStarGiftTransfer( MTP_inputInvoiceStarGiftTransfer(
Api::InputSavedStarGiftId(savedId), Api::InputSavedStarGiftId(savedId),
to->input), to->input),
std::move(formDone)); std::move(formDone));
} }
void BuyResaleGift(
std::shared_ptr<ChatHelpers::Show> show,
not_null<PeerData*> to,
std::shared_ptr<Data::UniqueGift> gift,
Fn<void(Payments::CheckoutResult)> done) {
Expects(to->isUser());
auto formDone = [=](
Payments::CheckoutResult result,
const MTPUpdates *updates) {
done(result);
if (result == Payments::CheckoutResult::Paid) {
AssertIsDebug(Refresh owners gifts list, refresh self list);
Ui::ShowResaleGiftBoughtToast(show, to, *gift);
}
};
Ui::RequestStarsFormAndSubmit(
show,
MTP_inputInvoiceStarGiftResale(MTP_string(gift->slug), to->input),
std::move(formDone));
}
} // namespace } // namespace
void ShowTransferToBox( void ShowTransferToBox(
@ -566,3 +589,73 @@ void ShowTransferGiftBox(
Box<PeerListBox>(std::move(controller), std::move(initBox)), Box<PeerListBox>(std::move(controller), std::move(initBox)),
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
} }
void ShowBuyResaleGiftBox(
std::shared_ptr<ChatHelpers::Show> show,
std::shared_ptr<Data::UniqueGift> gift,
not_null<PeerData*> to,
Fn<void()> closeParentBox) {
show->show(Box([=](not_null<Ui::GenericBox*> box) {
box->setTitle(tr::lng_gift_buy_resale_title(
lt_name,
rpl::single(UniqueGiftName(*gift))));
auto transfer = tr::lng_gift_buy_resale_button(
lt_cost,
rpl::single(
Ui::Text::IconEmoji(&st::starIconEmoji).append(
Lang::FormatCountDecimal(gift->starsForResale))),
Ui::Text::WithEntities);
struct State {
bool sent = false;
};
const auto state = std::make_shared<State>();
auto callback = [=](Fn<void()> close) {
if (state->sent) {
return;
}
state->sent = true;
const auto weak = Ui::MakeWeak(box);
const auto done = [=](Payments::CheckoutResult result) {
if (result == Payments::CheckoutResult::Cancelled) {
closeParentBox();
close();
} else if (result != Payments::CheckoutResult::Paid) {
state->sent = false;
} else {
show->showToast(u"done!"_q);
closeParentBox();
close();
}
};
BuyResaleGift(show, to, gift, done);
};
Ui::ConfirmBox(box, {
.text = to->isSelf()
? tr::lng_gift_buy_resale_confirm_self(
lt_name,
rpl::single(Ui::Text::Bold(UniqueGiftName(*gift))),
lt_price,
tr::lng_action_gift_for_stars(
lt_count,
rpl::single(gift->starsForResale * 1.),
Ui::Text::Bold),
Ui::Text::WithEntities)
: tr::lng_gift_buy_resale_confirm(
lt_name,
rpl::single(Ui::Text::Bold(UniqueGiftName(*gift))),
lt_price,
tr::lng_action_gift_for_stars(
lt_count,
rpl::single(gift->starsForResale * 1.),
Ui::Text::Bold),
lt_user,
rpl::single(Ui::Text::Bold(to->shortName())),
Ui::Text::WithEntities),
.confirmed = std::move(callback),
.confirmText = std::move(transfer),
});
}));
}

View file

@ -11,6 +11,10 @@ namespace Window {
class SessionController; class SessionController;
} // namespace Window } // namespace Window
namespace ChatHelpers {
class Show;
} // namespace ChatHelpers
namespace Data { namespace Data {
struct UniqueGift; struct UniqueGift;
class SavedStarGiftId; class SavedStarGiftId;
@ -27,3 +31,9 @@ void ShowTransferGiftBox(
not_null<Window::SessionController*> window, not_null<Window::SessionController*> window,
std::shared_ptr<Data::UniqueGift> gift, std::shared_ptr<Data::UniqueGift> gift,
Data::SavedStarGiftId savedId); Data::SavedStarGiftId savedId);
void ShowBuyResaleGiftBox(
std::shared_ptr<ChatHelpers::Show> show,
std::shared_ptr<Data::UniqueGift> gift,
not_null<PeerData*> to,
Fn<void()> closeParentBox);

View file

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

View file

@ -65,6 +65,7 @@ struct CreditsHistoryEntry final {
uint64 bareGiveawayMsgId = 0; uint64 bareGiveawayMsgId = 0;
uint64 bareGiftStickerId = 0; uint64 bareGiftStickerId = 0;
uint64 bareGiftOwnerId = 0; uint64 bareGiftOwnerId = 0;
uint64 bareGiftResaleRecipientId = 0;
uint64 bareActorId = 0; uint64 bareActorId = 0;
uint64 bareEntryOwnerId = 0; uint64 bareEntryOwnerId = 0;
uint64 giftChannelSavedId = 0; uint64 giftChannelSavedId = 0;

View file

@ -46,6 +46,7 @@ struct UniqueGift {
PeerId ownerId = 0; PeerId ownerId = 0;
int number = 0; int number = 0;
int starsForTransfer = -1; int starsForTransfer = -1;
int starsForResale = -1;
TimeId exportAt = 0; TimeId exportAt = 0;
UniqueGiftModel model; UniqueGiftModel model;
UniqueGiftPattern pattern; UniqueGiftPattern pattern;

View file

@ -145,7 +145,9 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
? (unique ? (unique
? _delegate->monostar() ? _delegate->monostar()
: _delegate->star()).append(' ').append( : _delegate->star()).append(' ').append(
Lang::FormatCountDecimal(data.info.starsResellMin) Lang::FormatCountDecimal(unique
? unique->starsForResale
: data.info.starsResellMin)
).append(data.info.resellCount > 1 ? "+" : "") ).append(data.info.resellCount > 1 ? "+" : "")
: unique : unique
? tr::lng_gift_transfer_button( ? tr::lng_gift_transfer_button(

View file

@ -1923,6 +1923,16 @@ void GenericCreditsEntryBox(
if (willBusy) { if (willBusy) {
state->confirmButtonBusy = true; state->confirmButtonBusy = true;
send(); send();
} else if (uniqueGift && uniqueGift->starsForResale && !giftToSelf) {
const auto to = e.bareGiftResaleRecipientId
? show->session().data().peer(
PeerId(e.bareGiftResaleRecipientId))
: show->session().user();
ShowBuyResaleGiftBox(
show,
e.uniqueGift,
to,
crl::guard(box, [=] { box->closeBox(); }));
} else if (canUpgradeFree) { } else if (canUpgradeFree) {
upgrade(); upgrade();
} else if (canToggle && !e.savedToProfile) { } else if (canToggle && !e.savedToProfile) {
@ -1931,6 +1941,14 @@ void GenericCreditsEntryBox(
box->closeBox(); box->closeBox();
} }
}); });
if (uniqueGift && uniqueGift->starsForResale && !giftToSelf) {
button->setText(tr::lng_gift_buy_resale_button(
lt_cost,
rpl::single(
Ui::Text::IconEmoji(&st::starIconEmoji).append(
Lang::FormatCountDecimal(uniqueGift->starsForResale))),
Ui::Text::WithEntities));
}
{ {
using namespace Info::Statistics; using namespace Info::Statistics;
const auto loadingAnimation = InfiniteRadialAnimationWidget( const auto loadingAnimation = InfiniteRadialAnimationWidget(
@ -2012,6 +2030,7 @@ void GlobalStarGiftBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
std::shared_ptr<ChatHelpers::Show> show, std::shared_ptr<ChatHelpers::Show> show,
const Data::StarGift &data, const Data::StarGift &data,
PeerId resaleRecipientId,
CreditsEntryBoxStyleOverrides st) { CreditsEntryBoxStyleOverrides st) {
const auto ownerId = data.unique ? data.unique->ownerId.value : 0; const auto ownerId = data.unique ? data.unique->ownerId.value : 0;
Settings::GenericCreditsEntryBox( Settings::GenericCreditsEntryBox(
@ -2021,6 +2040,7 @@ void GlobalStarGiftBox(
.credits = StarsAmount(data.stars), .credits = StarsAmount(data.stars),
.bareGiftStickerId = data.document->id, .bareGiftStickerId = data.document->id,
.bareGiftOwnerId = ownerId, .bareGiftOwnerId = ownerId,
.bareGiftResaleRecipientId = resaleRecipientId.value,
.stargiftId = data.id, .stargiftId = data.id,
.uniqueGift = data.unique, .uniqueGift = data.unique,
.peerType = Data::CreditsHistoryEntry::PeerType::Peer, .peerType = Data::CreditsHistoryEntry::PeerType::Peer,

View file

@ -154,6 +154,7 @@ void GlobalStarGiftBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
std::shared_ptr<ChatHelpers::Show> show, std::shared_ptr<ChatHelpers::Show> show,
const Data::StarGift &data, const Data::StarGift &data,
PeerId resaleRecipientId,
CreditsEntryBoxStyleOverrides st = {}); CreditsEntryBoxStyleOverrides st = {});
[[nodiscard]] Data::CreditsHistoryEntry SavedStarGiftEntry( [[nodiscard]] Data::CreditsHistoryEntry SavedStarGiftEntry(

View file

@ -58,14 +58,23 @@ void ConfirmBox(not_null<Ui::GenericBox*> box, ConfirmBoxArgs &&args) {
}; };
const auto &defaultButtonStyle = box->getDelegate()->style().button; const auto &defaultButtonStyle = box->getDelegate()->style().button;
const auto confirmTextPlain = v::text::is_plain(args.confirmText);
const auto confirmButton = box->addButton( const auto confirmButton = box->addButton(
v::text::take_plain(std::move(args.confirmText), tr::lng_box_ok()), (confirmTextPlain
? v::text::take_plain(
std::move(args.confirmText),
tr::lng_box_ok())
: rpl::single(QString())),
[=, c = prepareCallback(args.confirmed)]() { [=, c = prepareCallback(args.confirmed)]() {
lifetime->destroy(); lifetime->destroy();
c(); c();
}, },
args.confirmStyle ? *args.confirmStyle : defaultButtonStyle); args.confirmStyle ? *args.confirmStyle : defaultButtonStyle);
if (!confirmTextPlain) {
confirmButton->setText(
v::text::take_marked(std::move(args.confirmText)));
}
box->events( box->events(
) | rpl::start_with_next([=](not_null<QEvent*> e) { ) | rpl::start_with_next([=](not_null<QEvent*> e) {
if ((e->type() != QEvent::KeyPress) || !confirmButton) { if ((e->type() != QEvent::KeyPress) || !confirmButton) {