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);
});
}).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<Window::SessionController> weak,
not_null<PeerData*> 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),

View file

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

View file

@ -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::SessionController*> window,
std::shared_ptr<Data::UniqueGift> gift,
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();
@ -68,8 +69,9 @@ private:
const not_null<Window::SessionController*> _window;
const std::shared_ptr<Data::UniqueGift> _gift;
const Data::SavedStarGiftId _giftId;
const Fn<void(not_null<PeerData*>)> _choose;
const Fn<void(not_null<PeerData*>, Fn<void()>)> _choose;
ExportOption _exportOption;
QPointer<PeerListBox> _box;
};
@ -351,7 +353,7 @@ Controller::Controller(
not_null<Window::SessionController*> window,
std::shared_ptr<Data::UniqueGift> gift,
Data::SavedStarGiftId giftId,
Fn<void(not_null<PeerData*>)> choose)
Fn<void(not_null<PeerData*>, Fn<void()>)> choose)
: ContactsBoxController(&window->session())
, _window(window)
, _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) {
_exportOption = MakeExportOption(_window, box, _gift, _giftId, when);
delegate()->peerListSetAboveWidget(std::move(_exportOption.content));
@ -402,7 +405,11 @@ std::unique_ptr<PeerListRow> Controller::createRow(
}
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(
@ -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<Window::SessionController*> controller,
not_null<PeerData*> peer,
std::shared_ptr<Data::UniqueGift> gift,
Data::SavedStarGiftId savedId) {
Data::SavedStarGiftId savedId,
Fn<void()> closeParentBox) {
const auto stars = gift->starsForTransfer;
controller->show(Box([=](not_null<Ui::GenericBox*> 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<PeerData*> peer) {
ShowTransferToBox(window, peer, gift, savedId);
[=](not_null<PeerData*> peer, Fn<void()> done) {
ShowTransferToBox(window, peer, gift, savedId, done);
});
const auto controllerRaw = controller.get();
auto initBox = [=](not_null<PeerListBox*> box) {
controllerRaw->initExport(box);
controllerRaw->init(box);
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });

View file

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

View file

@ -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;

View file

@ -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)(

View file

@ -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)(

View file

@ -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) {

View file

@ -176,7 +176,9 @@ private:
[[nodiscard]] Data::SavedStarGiftId EntryToSavedStarGiftId(
not_null<Main::Session*> 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);