Add confirmation for go-to-Fragment.

This commit is contained in:
John Preston 2025-01-22 11:53:28 +04:00
parent ec69d557dc
commit 64706ea103
2 changed files with 46 additions and 12 deletions

View file

@ -3376,6 +3376,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_transfer_password_title" = "Two-step verification"; "lng_gift_transfer_password_title" = "Two-step verification";
"lng_gift_transfer_password_description" = "Please enter your password to transfer."; "lng_gift_transfer_password_description" = "Please enter your password to transfer.";
"lng_gift_transfer_password_about" = "You can withdraw only if you have:"; "lng_gift_transfer_password_about" = "You can withdraw only if you have:";
"lng_gift_transfer_confirm_title" = "Manage with Fragment";
"lng_gift_transfer_confirm_text" = "You can use Fragment, a third-party service, to transfer {name} to your TON account. After that, you can manage it as an NFT with any TON wallet outside Telegram.\n\nYou can also move such NFTs back to your Telegram account via Fragment.";
"lng_gift_transfer_confirm_button" = "Open Fragment";
"lng_gift_transfer_unlocks_days#one" = "unlocks in {count} day"; "lng_gift_transfer_unlocks_days#one" = "unlocks in {count} day";
"lng_gift_transfer_unlocks_days#other" = "unlocks in {count} days"; "lng_gift_transfer_unlocks_days#other" = "unlocks in {count} days";
"lng_gift_transfer_unlocks_hours#one" = "unlocks in {count} hour"; "lng_gift_transfer_unlocks_hours#one" = "unlocks in {count} hour";

View file

@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#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_dialogs.h" // recentPeersSpecialName. #include "styles/style_dialogs.h" // recentPeersSpecialName.
#include "styles/style_layers.h" // boxLabel.
namespace { namespace {
@ -66,17 +67,42 @@ private:
const not_null<Window::SessionController*> _window; const not_null<Window::SessionController*> _window;
const std::shared_ptr<Data::UniqueGift> _gift; const std::shared_ptr<Data::UniqueGift> _gift;
const Data::SavedStarGiftId _savedId; const Data::SavedStarGiftId _giftId;
const Fn<void(not_null<PeerData*>)> _choose; const Fn<void(not_null<PeerData*>)> _choose;
ExportOption _exportOption; ExportOption _exportOption;
}; };
void ConfirmExportBox(
not_null<Ui::GenericBox*> box,
std::shared_ptr<Data::UniqueGift> gift,
const QString &url,
Fn<void()> wentToUrl) {
box->setTitle(tr::lng_gift_transfer_confirm_title());
box->addRow(object_ptr<Ui::FlatLabel>(
box,
tr::lng_gift_transfer_confirm_text(
lt_name,
rpl::single(Ui::Text::Bold(UniqueGiftName(*gift))),
Ui::Text::WithEntities),
st::boxLabel));
box->addButton(tr::lng_gift_transfer_confirm_button(), [=] {
UrlClickHandler::Open(url);
wentToUrl();
box->closeBox();
});
box->addButton(tr::lng_cancel(), [=] {
box->closeBox();
});
}
void ExportOnBlockchain( void ExportOnBlockchain(
not_null<Window::SessionController*> window, not_null<Window::SessionController*> window,
not_null<Ui::RpWidget*> parent, not_null<Ui::RpWidget*> parent,
std::shared_ptr<Data::UniqueGift> gift,
Data::SavedStarGiftId giftId, Data::SavedStarGiftId giftId,
Fn<void()> waitFinished) { Fn<void()> waitFinished,
Fn<void()> wentToUrl) {
struct State { struct State {
bool loading = false; bool loading = false;
rpl::lifetime lifetime; rpl::lifetime lifetime;
@ -113,17 +139,16 @@ void ExportOnBlockchain(
= tr::lng_gift_transfer_password_description(tr::now); = tr::lng_gift_transfer_password_description(tr::now);
fields.customSubmitButton = tr::lng_passcode_submit(); fields.customSubmitButton = tr::lng_passcode_submit();
fields.customCheckCallback = crl::guard(parent, [=]( fields.customCheckCallback = crl::guard(parent, [=](
const Core::CloudPasswordResult &result, const Core::CloudPasswordResult &result,
QPointer<PasscodeBox> box) { QPointer<PasscodeBox> box) {
const auto done = [=](const QString &result) {
};
using ExportUrl = MTPpayments_StarGiftWithdrawalUrl; using ExportUrl = MTPpayments_StarGiftWithdrawalUrl;
session->api().request( session->api().request(
MTPpayments_GetStarGiftWithdrawalUrl( MTPpayments_GetStarGiftWithdrawalUrl(
Api::InputSavedStarGiftId(giftId), Api::InputSavedStarGiftId(giftId),
result.result) result.result)
).done([=](const ExportUrl &result) { ).done([=](const ExportUrl &result) {
UrlClickHandler::Open(qs(result.data().vurl())); const auto url = qs(result.data().vurl());
show->show(Box(ConfirmExportBox, gift, url, wentToUrl));
if (box) { if (box) {
box->closeBox(); box->closeBox();
} }
@ -141,7 +166,8 @@ void ExportOnBlockchain(
[[nodiscard]] ExportOption MakeExportOption( [[nodiscard]] ExportOption MakeExportOption(
not_null<Window::SessionController*> window, not_null<Window::SessionController*> window,
not_null<Ui::RpWidget*> parent, not_null<PeerListBox*> box,
std::shared_ptr<Data::UniqueGift> gift,
Data::SavedStarGiftId giftId, Data::SavedStarGiftId giftId,
TimeId when) { TimeId when) {
struct State { struct State {
@ -150,6 +176,7 @@ void ExportOnBlockchain(
const auto state = std::make_shared<State>(); const auto state = std::make_shared<State>();
const auto activate = [=] { const auto activate = [=] {
const auto now = base::unixtime::now(); const auto now = base::unixtime::now();
const auto weak = Ui::MakeWeak(box);
const auto left = (when > now) ? (when - now) : 0; const auto left = (when > now) ? (when - now) : 0;
const auto hours = left ? std::max((left + 1800) / 3600, 1) : 0; const auto hours = left ? std::max((left + 1800) / 3600, 1) : 0;
if (!hours) { if (!hours) {
@ -157,8 +184,12 @@ void ExportOnBlockchain(
return; return;
} }
state->exporting = true; state->exporting = true;
ExportOnBlockchain(window, parent, giftId, [=] { ExportOnBlockchain(window, box, gift, giftId, [=] {
state->exporting = false; state->exporting = false;
}, [=] {
if (const auto strong = weak.data()) {
strong->closeBox();
}
}); });
return; return;
} }
@ -319,12 +350,12 @@ void ExportOnBlockchain(
Controller::Controller( Controller::Controller(
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 giftId,
Fn<void(not_null<PeerData*>)> choose) Fn<void(not_null<PeerData*>)> choose)
: ContactsBoxController(&window->session()) : ContactsBoxController(&window->session())
, _window(window) , _window(window)
, _gift(std::move(gift)) , _gift(std::move(gift))
, _savedId(savedId) , _giftId(giftId)
, _choose(std::move(choose)) { , _choose(std::move(choose)) {
if (_gift->exportAt) { if (_gift->exportAt) {
setStyleOverrides(&st::peerListSmallSkips); setStyleOverrides(&st::peerListSmallSkips);
@ -333,7 +364,7 @@ Controller::Controller(
void Controller::initExport(not_null<PeerListBox*> box) { void Controller::initExport(not_null<PeerListBox*> box) {
if (const auto when = _gift->exportAt) { if (const auto when = _gift->exportAt) {
_exportOption = MakeExportOption(_window, box, _savedId, when); _exportOption = MakeExportOption(_window, box, _gift, _giftId, when);
delegate()->peerListSetAboveWidget(std::move(_exportOption.content)); delegate()->peerListSetAboveWidget(std::move(_exportOption.content));
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
} }