Handle t.me/nft/slug links.

This commit is contained in:
John Preston 2025-01-07 11:07:49 +04:00
parent 409389a994
commit 017535cf7b
4 changed files with 91 additions and 0 deletions

View file

@ -1344,6 +1344,59 @@ bool ResolveChatLink(
return true;
}
bool ResolveUniqueGift(
Window::SessionController *controller,
const Match &match,
const QVariant &context) {
if (!controller) {
return false;
}
const auto slug = match->captured(1);
if (slug.isEmpty()) {
return false;
}
struct Request {
base::weak_ptr<Window::SessionController> weak;
QString slug;
mtpRequestId id = 0;
};
static auto request = Request();
if (request.weak.get() == controller && request.slug == slug) {
return true;
} else if (const auto strong = request.weak.get()) {
strong->session().api().request(request.id).cancel();
}
const auto weak = request.weak = controller;
request.slug = slug;
const auto clear = [slug](not_null<Window::SessionController*> window) {
if (request.weak.get() == window && request.slug == slug) {
request = {};
}
};
request.id = controller->session().api().request(
MTPpayments_GetUniqueStarGift(MTP_string(slug))
).done([=](const MTPpayments_UniqueStarGift &result) {
if (const auto strong = weak.get()) {
clear(strong);
const auto &data = result.data();
const auto session = &strong->session();
session->data().processUsers(data.vusers());
if (const auto gift = Api::FromTL(session, data.vgift())) {
using namespace ::Settings;
strong->show(Box(GlobalStarGiftBox, strong, *gift));
}
}
}).fail([=](const MTP::Error &error) {
if (const auto strong = weak.get()) {
clear(strong);
strong->showToast(u"Error: "_q + error.type());
}
}).send();
return true;
}
} // namespace
const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
@ -1436,6 +1489,10 @@ const std::vector<LocalUrlHandler> &LocalUrlHandlers() {
u"^stars_topup/?\\?(.+)(#|$)"_q,
ResolveTopUp
},
{
u"^nft/?\\?slug=([a-zA-Z0-9\\.\\_\\-]+)(&|$)"_q,
ResolveUniqueGift
},
{
u"^([^\\?]+)(\\?|#|$)"_q,
HandleUnknown
@ -1585,6 +1642,9 @@ QString TryConvertUrlToLocal(QString url) {
} else if (const auto chatlinkMatch = regex_match(u"^m/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"_q, query, matchOptions)) {
const auto slug = chatlinkMatch->captured(1);
return u"tg://message?slug="_q + slug;
} else if (const auto nftMatch = regex_match(u"^nft/([a-zA-Z0-9\\.\\_\\-]+)(\\?|$)"_q, query, matchOptions)) {
const auto slug = nftMatch->captured(1);
return u"tg://nft?slug="_q + slug;
} else if (const auto privateMatch = regex_match(u"^"
"c/(\\-?\\d+)"
"("

View file

@ -89,6 +89,7 @@ struct CreditsHistoryEntry final {
bool giftUpgraded : 1 = false;
bool savedToProfile : 1 = false;
bool fromGiftsList : 1 = false;
bool fromGiftSlug : 1 = false;
bool soldOutInfo : 1 = false;
bool canUpgradeGift : 1 = false;
bool hasGiftComment : 1 = false;

View file

@ -1689,6 +1689,31 @@ void CreditsPrizeBox(
Data::SubscriptionEntry());
}
void GlobalStarGiftBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> controller,
const Data::StarGift &data) {
const auto ownerId = data.unique ? data.unique->ownerId.value : 0;
Settings::ReceiptCreditsBox(
box,
controller,
Data::CreditsHistoryEntry{
.credits = StarsAmount(data.stars),
.bareGiftStickerId = data.document->id,
.bareGiftOwnerId = ownerId,
.stargiftId = data.id,
.uniqueGift = data.unique,
.peerType = Data::CreditsHistoryEntry::PeerType::Peer,
.limitedCount = data.limitedCount,
.limitedLeft = data.limitedLeft,
.stargift = true,
.fromGiftSlug = true,
.in = (ownerId == controller->session().userPeerId().value),
.gift = true,
},
Data::SubscriptionEntry());
}
void UserStarGiftBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> controller,

View file

@ -19,6 +19,7 @@ struct SubscriptionEntry;
struct GiftCode;
struct CreditTopupOption;
struct UserStarGift;
struct StarGift;
} // namespace Data
namespace Main {
@ -97,6 +98,10 @@ void CreditsPrizeBox(
not_null<Window::SessionController*> controller,
const Data::GiftCode &data,
TimeId date);
void GlobalStarGiftBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> controller,
const Data::StarGift &data);
void UserStarGiftBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> controller,