Fix channel unique gift transfer.

This commit is contained in:
John Preston 2025-01-22 13:05:33 +04:00
parent 64706ea103
commit 51661a872c
9 changed files with 71 additions and 30 deletions

View file

@ -2926,25 +2926,29 @@ void RequestStarsFormAndSubmit(
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()) { const auto type = error.type();
strong->showToast(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(); }).send();
} }
void ShowGiftTransferredToast( void ShowGiftTransferredToast(
base::weak_ptr<Window::SessionController> weak, base::weak_ptr<Window::SessionController> weak,
not_null<PeerData*> to, not_null<PeerData*> to,
const MTPUpdates &result) { const Data::UniqueGift &gift) {
const auto gift = FindUniqueGift(&to->session(), result); if (const auto strong = weak.get()) {
if (const auto strong = gift ? weak.get() : nullptr) {
strong->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,
lt_name, lt_name,
Text::Bold(Data::UniqueGiftName(*gift)), Text::Bold(Data::UniqueGiftName(gift)),
lt_recipient, lt_recipient,
Text::Bold(to->shortName()), Text::Bold(to->shortName()),
Ui::Text::WithEntities), Ui::Text::WithEntities),

View file

@ -108,6 +108,6 @@ void RequestStarsFormAndSubmit(
void ShowGiftTransferredToast( void ShowGiftTransferredToast(
base::weak_ptr<Window::SessionController> weak, base::weak_ptr<Window::SessionController> weak,
not_null<PeerData*> to, not_null<PeerData*> to,
const MTPUpdates &result); const Data::UniqueGift &gift);
} // namespace Ui } // namespace Ui

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_cloud_password.h" #include "api/api_cloud_password.h"
#include "base/unixtime.h" #include "base/unixtime.h"
#include "boxes/passcode_box.h" #include "boxes/passcode_box.h"
#include "data/data_session.h"
#include "data/data_star_gift.h" #include "data/data_star_gift.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "boxes/filters/edit_filter_chats_list.h" // CreatePe...tionSubtitle. #include "boxes/filters/edit_filter_chats_list.h" // CreatePe...tionSubtitle.
@ -47,9 +48,9 @@ public:
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,
Fn<void(not_null<PeerData*>)> choose); Fn<void(not_null<PeerData*>, Fn<void()>)> choose);
void initExport(not_null<PeerListBox*> box); void init(not_null<PeerListBox*> box);
void noSearchSubmit(); void noSearchSubmit();
@ -68,8 +69,9 @@ 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 _giftId; const Data::SavedStarGiftId _giftId;
const Fn<void(not_null<PeerData*>)> _choose; const Fn<void(not_null<PeerData*>, Fn<void()>)> _choose;
ExportOption _exportOption; ExportOption _exportOption;
QPointer<PeerListBox> _box;
}; };
@ -351,7 +353,7 @@ 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 giftId, Data::SavedStarGiftId giftId,
Fn<void(not_null<PeerData*>)> choose) Fn<void(not_null<PeerData*>, Fn<void()>)> choose)
: ContactsBoxController(&window->session()) : ContactsBoxController(&window->session())
, _window(window) , _window(window)
, _gift(std::move(gift)) , _gift(std::move(gift))
@ -362,7 +364,8 @@ Controller::Controller(
} }
} }
void Controller::initExport(not_null<PeerListBox*> box) { void Controller::init(not_null<PeerListBox*> box) {
_box = box;
if (const auto when = _gift->exportAt) { if (const auto when = _gift->exportAt) {
_exportOption = MakeExportOption(_window, box, _gift, _giftId, when); _exportOption = MakeExportOption(_window, box, _gift, _giftId, when);
delegate()->peerListSetAboveWidget(std::move(_exportOption.content)); delegate()->peerListSetAboveWidget(std::move(_exportOption.content));
@ -402,7 +405,11 @@ std::unique_ptr<PeerListRow> Controller::createRow(
} }
void Controller::rowClicked(not_null<PeerListRow*> row) { void Controller::rowClicked(not_null<PeerListRow*> row) {
_choose(row->peer()); _choose(row->peer(), [parentBox = _box] {
if (const auto strong = parentBox.data()) {
strong->closeBox();
}
});
} }
void TransferGift( void TransferGift(
@ -418,12 +425,16 @@ void TransferGift(
auto formDone = [=]( auto formDone = [=](
Payments::CheckoutResult result, Payments::CheckoutResult result,
const MTPUpdates *updates) { const MTPUpdates *updates) {
if (result == Payments::CheckoutResult::Paid && updates) { done(result);
if (result == Payments::CheckoutResult::Paid) {
if (const auto strong = weak.get()) { 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) { if (gift->starsForTransfer <= 0) {
session->api().request(MTPpayments_TransferStarGift( session->api().request(MTPpayments_TransferStarGift(
@ -433,10 +444,10 @@ void TransferGift(
session->api().applyUpdates(result); session->api().applyUpdates(result);
formDone(Payments::CheckoutResult::Paid, &result); formDone(Payments::CheckoutResult::Paid, &result);
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
formDone(Payments::CheckoutResult::Failed, nullptr);
if (const auto strong = weak.get()) { if (const auto strong = weak.get()) {
strong->showToast(error.type()); strong->showToast(error.type());
} }
formDone(Payments::CheckoutResult::Failed, nullptr);
}).send(); }).send();
return; return;
} }
@ -452,7 +463,8 @@ void ShowTransferToBox(
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
not_null<PeerData*> peer, not_null<PeerData*> peer,
std::shared_ptr<Data::UniqueGift> gift, std::shared_ptr<Data::UniqueGift> gift,
Data::SavedStarGiftId savedId) { Data::SavedStarGiftId savedId,
Fn<void()> closeParentBox) {
const auto stars = gift->starsForTransfer; const auto stars = gift->starsForTransfer;
controller->show(Box([=](not_null<Ui::GenericBox*> box) { controller->show(Box([=](not_null<Ui::GenericBox*> box) {
box->setTitle(tr::lng_gift_transfer_title( box->setTitle(tr::lng_gift_transfer_title(
@ -478,10 +490,18 @@ void ShowTransferToBox(
state->sent = true; state->sent = true;
const auto weak = Ui::MakeWeak(box); const auto weak = Ui::MakeWeak(box);
const auto done = [=](Payments::CheckoutResult result) { 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; state->sent = false;
} else { } else {
controller->showPeerHistory(peer); if (savedId.isUser()) {
controller->showPeerHistory(peer);
}
closeParentBox();
if (const auto strong = weak.data()) { if (const auto strong = weak.data()) {
strong->closeBox(); strong->closeBox();
} }
@ -525,12 +545,12 @@ void ShowTransferGiftBox(
window, window,
gift, gift,
savedId, savedId,
[=](not_null<PeerData*> peer) { [=](not_null<PeerData*> peer, Fn<void()> done) {
ShowTransferToBox(window, peer, gift, savedId); ShowTransferToBox(window, peer, gift, savedId, done);
}); });
const auto controllerRaw = controller.get(); const auto controllerRaw = controller.get();
auto initBox = [=](not_null<PeerListBox*> box) { auto initBox = [=](not_null<PeerListBox*> box) {
controllerRaw->initExport(box); controllerRaw->init(box);
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });

View file

@ -85,6 +85,7 @@ struct GiftUpdate {
Save, Save,
Unsave, Unsave,
Convert, Convert,
Transfer,
Delete, Delete,
}; };

View file

@ -5505,13 +5505,13 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
const auto service = _from->isServiceUser(); const auto service = _from->isServiceUser();
const auto toChannel = service && peerIsChannel(giftPeer); const auto toChannel = service && peerIsChannel(giftPeer);
const auto peer = isSelf ? _history->peer : _from; 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) { if (toChannel) {
const auto fromId = action.vfrom_id()
? peerFromMTP(*action.vfrom_id())
: PeerId();
const auto channel = peer->owner().channel( const auto channel = peer->owner().channel(
peerToChannel(giftPeer)); peerToChannel(giftPeer));
const auto from = fromId ? peer->owner().peer(fromId) : peer;
result.links.push_back(from->createOpenLink()); result.links.push_back(from->createOpenLink());
result.links.push_back(channel->createOpenLink()); result.links.push_back(channel->createOpenLink());
result.text = (action.is_upgrade() result.text = (action.is_upgrade()
@ -5538,7 +5538,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
: tr::lng_action_gift_transferred))( : tr::lng_action_gift_transferred))(
tr::now, tr::now,
lt_user, lt_user,
Ui::Text::Link(peer->shortName(), 1), // Link 1. Ui::Text::Link(from->shortName(), 1), // Link 1.
Ui::Text::WithEntities); Ui::Text::WithEntities);
} }
return result; return result;

View file

@ -70,6 +70,8 @@ QString PremiumGift::title() {
const auto peer = _parent->history()->peer; const auto peer = _parent->history()->peer;
return peer->isSelf() return peer->isSelf()
? tr::lng_action_gift_self_subtitle(tr::now) ? tr::lng_action_gift_self_subtitle(tr::now)
: peer->isServiceUser()
? tr::lng_gift_link_label_gift(tr::now)
: (outgoingGift() : (outgoingGift()
? tr::lng_action_gift_sent_subtitle ? tr::lng_action_gift_sent_subtitle
: tr::lng_action_gift_got_subtitle)( : tr::lng_action_gift_got_subtitle)(

View file

@ -429,6 +429,8 @@ auto GenerateUniqueGiftMedia(
pushText( pushText(
Ui::Text::Bold(peer->isSelf() Ui::Text::Bold(peer->isSelf()
? tr::lng_action_gift_self_subtitle(tr::now) ? tr::lng_action_gift_self_subtitle(tr::now)
: peer->isServiceUser()
? tr::lng_gift_link_label_gift(tr::now)
: (outgoing : (outgoing
? tr::lng_action_gift_sent_subtitle ? tr::lng_action_gift_sent_subtitle
: tr::lng_action_gift_got_subtitle)( : tr::lng_action_gift_got_subtitle)(

View file

@ -172,6 +172,7 @@ void InnerWidget::subscribeToUpdates() {
const auto index = int(i - begin(_entries)); const auto index = int(i - begin(_entries));
using Action = Data::GiftUpdate::Action; using Action = Data::GiftUpdate::Action;
if (update.action == Action::Convert if (update.action == Action::Convert
|| update.action == Action::Transfer
|| update.action == Action::Delete) { || update.action == Action::Delete) {
_entries.erase(i); _entries.erase(i);
if (_totalCount > 0) { if (_totalCount > 0) {

View file

@ -176,7 +176,9 @@ private:
[[nodiscard]] Data::SavedStarGiftId EntryToSavedStarGiftId( [[nodiscard]] Data::SavedStarGiftId EntryToSavedStarGiftId(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const Data::CreditsHistoryEntry &entry) { const Data::CreditsHistoryEntry &entry) {
return (entry.bareGiftListPeerId && entry.giftSavedId) return !entry.stargift
? Data::SavedStarGiftId()
: (entry.bareGiftListPeerId && entry.giftSavedId)
? Data::SavedStarGiftId::Chat( ? Data::SavedStarGiftId::Chat(
session->data().peer(PeerId(entry.bareGiftListPeerId)), session->data().peer(PeerId(entry.bareGiftListPeerId)),
entry.giftSavedId) entry.giftSavedId)
@ -979,6 +981,15 @@ void GenericCreditsEntryBox(
&& starGiftSender; && starGiftSender;
const auto canConvert = forConvert && !timeExceeded; 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->setStyle(st.box ? *st.box : st::giveawayGiftCodeBox);
box->setWidth(st::boxWideWidth); box->setWidth(st::boxWideWidth);
box->setNoContentMargin(true); box->setNoContentMargin(true);