From 51661a872c6b7102486a419f0c0aad14a4f08599 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 22 Jan 2025 13:05:33 +0400 Subject: [PATCH] Fix channel unique gift transfer. --- Telegram/SourceFiles/boxes/star_gift_box.cpp | 18 ++++--- Telegram/SourceFiles/boxes/star_gift_box.h | 2 +- .../SourceFiles/boxes/transfer_gift_box.cpp | 52 +++++++++++++------ Telegram/SourceFiles/data/data_session.h | 1 + Telegram/SourceFiles/history/history_item.cpp | 10 ++-- .../view/media/history_view_premium_gift.cpp | 2 + .../view/media/history_view_unique_gift.cpp | 2 + .../peer_gifts/info_peer_gifts_widget.cpp | 1 + .../settings/settings_credits_graphics.cpp | 13 ++++- 9 files changed, 71 insertions(+), 30 deletions(-) diff --git a/Telegram/SourceFiles/boxes/star_gift_box.cpp b/Telegram/SourceFiles/boxes/star_gift_box.cpp index 28d61f6f6..dbfa60999 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_box.cpp @@ -2926,25 +2926,29 @@ void RequestStarsFormAndSubmit( done(Payments::CheckoutResult::Failed, nullptr); }); }).fail([=](const MTP::Error &error) { - if (const auto strong = weak.get()) { - strong->showToast(error.type()); + const auto type = error.type(); + if (type == u"STARGIFT_EXPORT_IN_PROGRESS"_q) { + done(Payments::CheckoutResult::Cancelled, nullptr); + } else { + if (const auto strong = weak.get()) { + strong->showToast(type); + } + done(Payments::CheckoutResult::Failed, nullptr); } - done(Payments::CheckoutResult::Failed, nullptr); }).send(); } void ShowGiftTransferredToast( base::weak_ptr weak, not_null to, - const MTPUpdates &result) { - const auto gift = FindUniqueGift(&to->session(), result); - if (const auto strong = gift ? weak.get() : nullptr) { + const Data::UniqueGift &gift) { + if (const auto strong = weak.get()) { strong->showToast({ .title = tr::lng_gift_transferred_title(tr::now), .text = tr::lng_gift_transferred_about( tr::now, lt_name, - Text::Bold(Data::UniqueGiftName(*gift)), + Text::Bold(Data::UniqueGiftName(gift)), lt_recipient, Text::Bold(to->shortName()), Ui::Text::WithEntities), diff --git a/Telegram/SourceFiles/boxes/star_gift_box.h b/Telegram/SourceFiles/boxes/star_gift_box.h index 08391f657..f00f4ae3c 100644 --- a/Telegram/SourceFiles/boxes/star_gift_box.h +++ b/Telegram/SourceFiles/boxes/star_gift_box.h @@ -108,6 +108,6 @@ void RequestStarsFormAndSubmit( void ShowGiftTransferredToast( base::weak_ptr weak, not_null to, - const MTPUpdates &result); + const Data::UniqueGift &gift); } // namespace Ui diff --git a/Telegram/SourceFiles/boxes/transfer_gift_box.cpp b/Telegram/SourceFiles/boxes/transfer_gift_box.cpp index 005790d18..875d9c02d 100644 --- a/Telegram/SourceFiles/boxes/transfer_gift_box.cpp +++ b/Telegram/SourceFiles/boxes/transfer_gift_box.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_cloud_password.h" #include "base/unixtime.h" #include "boxes/passcode_box.h" +#include "data/data_session.h" #include "data/data_star_gift.h" #include "data/data_user.h" #include "boxes/filters/edit_filter_chats_list.h" // CreatePe...tionSubtitle. @@ -47,9 +48,9 @@ public: not_null window, std::shared_ptr gift, Data::SavedStarGiftId savedId, - Fn)> choose); + Fn, Fn)> choose); - void initExport(not_null box); + void init(not_null box); void noSearchSubmit(); @@ -68,8 +69,9 @@ private: const not_null _window; const std::shared_ptr _gift; const Data::SavedStarGiftId _giftId; - const Fn)> _choose; + const Fn, Fn)> _choose; ExportOption _exportOption; + QPointer _box; }; @@ -351,7 +353,7 @@ Controller::Controller( not_null window, std::shared_ptr gift, Data::SavedStarGiftId giftId, - Fn)> choose) + Fn, Fn)> choose) : ContactsBoxController(&window->session()) , _window(window) , _gift(std::move(gift)) @@ -362,7 +364,8 @@ Controller::Controller( } } -void Controller::initExport(not_null box) { +void Controller::init(not_null box) { + _box = box; if (const auto when = _gift->exportAt) { _exportOption = MakeExportOption(_window, box, _gift, _giftId, when); delegate()->peerListSetAboveWidget(std::move(_exportOption.content)); @@ -402,7 +405,11 @@ std::unique_ptr Controller::createRow( } void Controller::rowClicked(not_null row) { - _choose(row->peer()); + _choose(row->peer(), [parentBox = _box] { + if (const auto strong = parentBox.data()) { + strong->closeBox(); + } + }); } void TransferGift( @@ -418,12 +425,16 @@ void TransferGift( auto formDone = [=]( Payments::CheckoutResult result, const MTPUpdates *updates) { - if (result == Payments::CheckoutResult::Paid && updates) { + done(result); + if (result == Payments::CheckoutResult::Paid) { if (const auto strong = weak.get()) { - Ui::ShowGiftTransferredToast(strong, to, *updates); + strong->session().data().notifyGiftUpdate({ + .id = savedId, + .action = Data::GiftUpdate::Action::Transfer, + }); + Ui::ShowGiftTransferredToast(strong, to, *gift); } } - done(result); }; if (gift->starsForTransfer <= 0) { session->api().request(MTPpayments_TransferStarGift( @@ -433,10 +444,10 @@ void TransferGift( session->api().applyUpdates(result); formDone(Payments::CheckoutResult::Paid, &result); }).fail([=](const MTP::Error &error) { + formDone(Payments::CheckoutResult::Failed, nullptr); if (const auto strong = weak.get()) { strong->showToast(error.type()); } - formDone(Payments::CheckoutResult::Failed, nullptr); }).send(); return; } @@ -452,7 +463,8 @@ void ShowTransferToBox( not_null controller, not_null peer, std::shared_ptr gift, - Data::SavedStarGiftId savedId) { + Data::SavedStarGiftId savedId, + Fn closeParentBox) { const auto stars = gift->starsForTransfer; controller->show(Box([=](not_null box) { box->setTitle(tr::lng_gift_transfer_title( @@ -478,10 +490,18 @@ void ShowTransferToBox( state->sent = true; const auto weak = Ui::MakeWeak(box); const auto done = [=](Payments::CheckoutResult result) { - if (result != Payments::CheckoutResult::Paid) { + if (result == Payments::CheckoutResult::Cancelled) { + closeParentBox(); + if (const auto strong = weak.data()) { + strong->closeBox(); + } + } else if (result != Payments::CheckoutResult::Paid) { state->sent = false; } else { - controller->showPeerHistory(peer); + if (savedId.isUser()) { + controller->showPeerHistory(peer); + } + closeParentBox(); if (const auto strong = weak.data()) { strong->closeBox(); } @@ -525,12 +545,12 @@ void ShowTransferGiftBox( window, gift, savedId, - [=](not_null peer) { - ShowTransferToBox(window, peer, gift, savedId); + [=](not_null peer, Fn done) { + ShowTransferToBox(window, peer, gift, savedId, done); }); const auto controllerRaw = controller.get(); auto initBox = [=](not_null box) { - controllerRaw->initExport(box); + controllerRaw->init(box); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index fade93dad..bf1520a59 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -85,6 +85,7 @@ struct GiftUpdate { Save, Unsave, Convert, + Transfer, Delete, }; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 7abc084db..719ae4f59 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -5505,13 +5505,13 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { const auto service = _from->isServiceUser(); const auto toChannel = service && peerIsChannel(giftPeer); const auto peer = isSelf ? _history->peer : _from; + const auto fromId = action.vfrom_id() + ? peerFromMTP(*action.vfrom_id()) + : PeerId(); + const auto from = fromId ? peer->owner().peer(fromId) : peer; if (toChannel) { - const auto fromId = action.vfrom_id() - ? peerFromMTP(*action.vfrom_id()) - : PeerId(); const auto channel = peer->owner().channel( peerToChannel(giftPeer)); - const auto from = fromId ? peer->owner().peer(fromId) : peer; result.links.push_back(from->createOpenLink()); result.links.push_back(channel->createOpenLink()); result.text = (action.is_upgrade() @@ -5538,7 +5538,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { : tr::lng_action_gift_transferred))( tr::now, lt_user, - Ui::Text::Link(peer->shortName(), 1), // Link 1. + Ui::Text::Link(from->shortName(), 1), // Link 1. Ui::Text::WithEntities); } return result; diff --git a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp index 04a9c342f..033f7ec5e 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp @@ -70,6 +70,8 @@ QString PremiumGift::title() { const auto peer = _parent->history()->peer; return peer->isSelf() ? tr::lng_action_gift_self_subtitle(tr::now) + : peer->isServiceUser() + ? tr::lng_gift_link_label_gift(tr::now) : (outgoingGift() ? tr::lng_action_gift_sent_subtitle : tr::lng_action_gift_got_subtitle)( diff --git a/Telegram/SourceFiles/history/view/media/history_view_unique_gift.cpp b/Telegram/SourceFiles/history/view/media/history_view_unique_gift.cpp index db17b49ca..228ac5d20 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_unique_gift.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_unique_gift.cpp @@ -429,6 +429,8 @@ auto GenerateUniqueGiftMedia( pushText( Ui::Text::Bold(peer->isSelf() ? tr::lng_action_gift_self_subtitle(tr::now) + : peer->isServiceUser() + ? tr::lng_gift_link_label_gift(tr::now) : (outgoing ? tr::lng_action_gift_sent_subtitle : tr::lng_action_gift_got_subtitle)( diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp index b3a33fef7..75b27c6ee 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp @@ -172,6 +172,7 @@ void InnerWidget::subscribeToUpdates() { const auto index = int(i - begin(_entries)); using Action = Data::GiftUpdate::Action; if (update.action == Action::Convert + || update.action == Action::Transfer || update.action == Action::Delete) { _entries.erase(i); if (_totalCount > 0) { diff --git a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp index 72c75bd11..481fc8f2d 100644 --- a/Telegram/SourceFiles/settings/settings_credits_graphics.cpp +++ b/Telegram/SourceFiles/settings/settings_credits_graphics.cpp @@ -176,7 +176,9 @@ private: [[nodiscard]] Data::SavedStarGiftId EntryToSavedStarGiftId( not_null session, const Data::CreditsHistoryEntry &entry) { - return (entry.bareGiftListPeerId && entry.giftSavedId) + return !entry.stargift + ? Data::SavedStarGiftId() + : (entry.bareGiftListPeerId && entry.giftSavedId) ? Data::SavedStarGiftId::Chat( session->data().peer(PeerId(entry.bareGiftListPeerId)), entry.giftSavedId) @@ -979,6 +981,15 @@ void GenericCreditsEntryBox( && starGiftSender; const auto canConvert = forConvert && !timeExceeded; + if (auto savedId = EntryToSavedStarGiftId(session, e)) { + session->data().giftUpdates( + ) | rpl::start_with_next([=](const Data::GiftUpdate &update) { + if (update.id == savedId) { + box->closeBox(); + } + }, box->lifetime()); + } + box->setStyle(st.box ? *st.box : st::giveawayGiftCodeBox); box->setWidth(st::boxWideWidth); box->setNoContentMargin(true);