Parse unique gift fields.

This commit is contained in:
John Preston 2024-12-25 13:04:07 +04:00
parent d874829b06
commit 5f3db95cbd
12 changed files with 249 additions and 113 deletions

View file

@ -628,6 +628,7 @@ PRIVATE
data/data_shared_media.h data/data_shared_media.h
data/data_sparse_ids.cpp data/data_sparse_ids.cpp
data/data_sparse_ids.h data/data_sparse_ids.h
data/data_star_gift.h
data/data_statistics.h data/data_statistics.h
data/data_stories.cpp data/data_stories.cpp
data/data_stories.h data/data_stories.h

View file

@ -601,7 +601,7 @@ auto PremiumGiftCodeOptions::requestStarGifts()
_giftsHash = data.vhash().v; _giftsHash = data.vhash().v;
const auto &list = data.vgifts().v; const auto &list = data.vgifts().v;
const auto session = &_peer->session(); const auto session = &_peer->session();
auto gifts = std::vector<StarGift>(); auto gifts = std::vector<Data::StarGift>();
gifts.reserve(list.size()); gifts.reserve(list.size());
for (const auto &gift : list) { for (const auto &gift : list) {
if (auto parsed = FromTL(session, gift)) { if (auto parsed = FromTL(session, gift)) {
@ -620,7 +620,8 @@ auto PremiumGiftCodeOptions::requestStarGifts()
}; };
} }
const std::vector<StarGift> &PremiumGiftCodeOptions::starGifts() const { auto PremiumGiftCodeOptions::starGifts() const
-> const std::vector<Data::StarGift> & {
return _gifts; return _gifts;
} }
@ -758,7 +759,7 @@ rpl::producer<DocumentData*> RandomHelloStickerValue(
}) | rpl::take(1) | rpl::map(random)); }) | rpl::take(1) | rpl::map(random));
} }
std::optional<StarGift> FromTL( std::optional<Data::StarGift> FromTL(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const MTPstarGift &gift) { const MTPstarGift &gift) {
return gift.match([&](const MTPDstarGift &data) { return gift.match([&](const MTPDstarGift &data) {
@ -767,13 +768,13 @@ std::optional<StarGift> FromTL(
const auto remaining = data.vavailability_remains(); const auto remaining = data.vavailability_remains();
const auto total = data.vavailability_total(); const auto total = data.vavailability_total();
if (!document->sticker()) { if (!document->sticker()) {
return std::optional<StarGift>(); return std::optional<Data::StarGift>();
} }
return std::optional<StarGift>(StarGift{ return std::optional<Data::StarGift>(Data::StarGift{
.id = uint64(data.vid().v), .id = uint64(data.vid().v),
.stars = int64(data.vstars().v), .stars = int64(data.vstars().v),
.starsConverted = int64(data.vconvert_stars().v), .starsConverted = int64(data.vconvert_stars().v),
.document = document, .stickerId = document->id,
.limitedLeft = remaining.value_or_empty(), .limitedLeft = remaining.value_or_empty(),
.limitedCount = total.value_or_empty(), .limitedCount = total.value_or_empty(),
.firstSaleDate = data.vfirst_sale_date().value_or_empty(), .firstSaleDate = data.vfirst_sale_date().value_or_empty(),
@ -781,11 +782,54 @@ std::optional<StarGift> FromTL(
.birthday = data.is_birthday(), .birthday = data.is_birthday(),
}); });
}, [&](const MTPDstarGiftUnique &data) { }, [&](const MTPDstarGiftUnique &data) {
return std::optional<StarGift>(); const auto total = data.vavailability_total().v;
auto result = Data::StarGift{
.id = uint64(data.vid().v),
.unique = std::make_shared<Data::UniqueGift>(Data::UniqueGift{
.title = qs(data.vtitle()),
.number = data.vnum().v,
.ownerId = peerFromUser(UserId(data.vowner_id().v)),
}),
.limitedLeft = (total - data.vavailability_issued().v),
.limitedCount = total,
};
const auto unique = result.unique.get();
for (const auto &attribute : data.vattributes().v) {
attribute.match([&](const MTPDstarGiftAttributeModel &data) {
unique->model.name = qs(data.vname());
unique->model.rarityPermille = data.vrarity_permille().v;
result.stickerId = data.vdocument_id().v;
}, [&](const MTPDstarGiftAttributePattern &data) {
unique->pattern.name = qs(data.vname());
unique->pattern.rarityPermille = data.vrarity_permille().v;
unique->pattern.documentId = data.vdocument_id().v;
}, [&](const MTPDstarGiftAttributeBackdrop &data) {
unique->backdrop.name = qs(data.vname());
unique->backdrop.rarityPermille = data.vrarity_permille().v;
unique->backdrop.centerColor = Ui::ColorFromSerialized(
data.vcenter_color());
unique->backdrop.edgeColor = Ui::ColorFromSerialized(
data.vedge_color());
unique->backdrop.patternColor = Ui::ColorFromSerialized(
data.vpattern_color());
unique->backdrop.textColor = Ui::ColorFromSerialized(
data.vtext_color());
}, [&](const MTPDstarGiftAttributeOriginalDetails &data) {
unique->originalDetails.date = data.vdate().v;
unique->originalDetails.senderId = peerFromUser(
UserId(data.vsender_id().value_or_empty()));
unique->originalDetails.recipientId = peerFromUser(
UserId(data.vrecipient_id().v));
unique->originalDetails.message = data.vmessage()
? Api::ParseTextWithEntities(session, *data.vmessage())
: TextWithEntities();
});
}
return result.stickerId ? result : std::optional<Data::StarGift>();
}); });
} }
std::optional<UserStarGift> FromTL( std::optional<Data::UserStarGift> FromTL(
not_null<UserData*> to, not_null<UserData*> to,
const MTPuserStarGift &gift) { const MTPuserStarGift &gift) {
const auto session = &to->session(); const auto session = &to->session();
@ -794,7 +838,7 @@ std::optional<UserStarGift> FromTL(
if (!parsed) { if (!parsed) {
return {}; return {};
} }
return UserStarGift{ return Data::UserStarGift{
.info = std::move(*parsed), .info = std::move(*parsed),
.message = (data.vmessage() .message = (data.vmessage()
? TextWithEntities{ ? TextWithEntities{

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "data/data_premium_subscription_option.h" #include "data/data_premium_subscription_option.h"
#include "data/data_star_gift.h"
#include "mtproto/sender.h" #include "mtproto/sender.h"
class History; class History;
@ -73,34 +74,6 @@ struct GiftOptionData {
int months = 0; int months = 0;
}; };
struct StarGift {
uint64 id = 0;
int64 stars = 0;
int64 starsConverted = 0;
not_null<DocumentData*> document;
int limitedLeft = 0;
int limitedCount = 0;
TimeId firstSaleDate = 0;
TimeId lastSaleDate = 0;
bool birthday = false;
friend inline bool operator==(
const StarGift &,
const StarGift &) = default;
};
struct UserStarGift {
StarGift info;
TextWithEntities message;
int64 starsConverted = 0;
PeerId fromId = 0;
MsgId messageId = 0;
TimeId date = 0;
bool anonymous = false;
bool hidden = false;
bool mine = false;
};
class Premium final { class Premium final {
public: public:
explicit Premium(not_null<ApiWrap*> api); explicit Premium(not_null<ApiWrap*> api);
@ -223,7 +196,7 @@ public:
[[nodiscard]] bool giveawayGiftsPurchaseAvailable() const; [[nodiscard]] bool giveawayGiftsPurchaseAvailable() const;
[[nodiscard]] rpl::producer<rpl::no_value, QString> requestStarGifts(); [[nodiscard]] rpl::producer<rpl::no_value, QString> requestStarGifts();
[[nodiscard]] const std::vector<StarGift> &starGifts() const; [[nodiscard]] const std::vector<Data::StarGift> &starGifts() const;
private: private:
struct Token final { struct Token final {
@ -253,7 +226,7 @@ private:
base::flat_map<Token, Store> _stores; base::flat_map<Token, Store> _stores;
int32 _giftsHash = 0; int32 _giftsHash = 0;
std::vector<StarGift> _gifts; std::vector<Data::StarGift> _gifts;
MTP::Sender _api; MTP::Sender _api;
@ -283,10 +256,10 @@ enum class RequirePremiumState {
[[nodiscard]] rpl::producer<DocumentData*> RandomHelloStickerValue( [[nodiscard]] rpl::producer<DocumentData*> RandomHelloStickerValue(
not_null<Main::Session*> session); not_null<Main::Session*> session);
[[nodiscard]] std::optional<StarGift> FromTL( [[nodiscard]] std::optional<Data::StarGift> FromTL(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const MTPstarGift &gift); const MTPstarGift &gift);
[[nodiscard]] std::optional<UserStarGift> FromTL( [[nodiscard]] std::optional<Data::UserStarGift> FromTL(
not_null<UserData*> to, not_null<UserData*> to,
const MTPuserStarGift &gift); const MTPuserStarGift &gift);

View file

@ -139,6 +139,7 @@ private:
const std::unique_ptr<Ui::ChatStyle> _style; const std::unique_ptr<Ui::ChatStyle> _style;
const std::unique_ptr<PreviewDelegate> _delegate; const std::unique_ptr<PreviewDelegate> _delegate;
AdminLog::OwnedItem _item; AdminLog::OwnedItem _item;
rpl::lifetime _itemLifetime;
QPoint _position; QPoint _position;
}; };
@ -160,7 +161,7 @@ private:
return is(now) || is(now.addDays(1)) || is(now.addDays(-1)); return is(now) || is(now.addDays(1)) || is(now.addDays(-1));
} }
[[nodiscard]] bool IsSoldOut(const Api::StarGift &info) { [[nodiscard]] bool IsSoldOut(const Data::StarGift &info) {
return info.limitedCount && !info.limitedLeft; return info.limitedCount && !info.limitedLeft;
} }
@ -188,7 +189,9 @@ Context PreviewDelegate::elementContext() {
auto GenerateGiftMedia( auto GenerateGiftMedia(
not_null<Element*> parent, not_null<Element*> parent,
Element *replacing, Element *replacing,
const GiftDetails &data) const GiftDetails &data,
Fn<void()> requestResize,
not_null<rpl::lifetime*> onLifetime)
-> Fn<void(Fn<void(std::unique_ptr<MediaGenericPart>)>)> { -> Fn<void(Fn<void(std::unique_ptr<MediaGenericPart>)>)> {
return [=](Fn<void(std::unique_ptr<MediaGenericPart>)> push) { return [=](Fn<void(std::unique_ptr<MediaGenericPart>)> push) {
const auto &descriptor = data.descriptor; const auto &descriptor = data.descriptor;
@ -206,12 +209,20 @@ auto GenerateGiftMedia(
links, links,
context)); context));
}; };
const auto resolved = onLifetime->make_state<DocumentData*>(nullptr);
GiftStickerValue(
&parent->history()->session(),
descriptor
) | rpl::start_with_next([=](not_null<DocumentData*> document) {
*resolved = document;
requestResize();
}, *onLifetime);
const auto sticker = [=] { const auto sticker = [=] {
using Tag = ChatHelpers::StickerLottieSize; using Tag = ChatHelpers::StickerLottieSize;
const auto session = &parent->history()->session();
const auto sticker = LookupGiftSticker(session, descriptor);
return StickerInBubblePart::Data{ return StickerInBubblePart::Data{
.sticker = sticker, .sticker = *resolved,
.size = st::chatIntroStickerSize, .size = st::chatIntroStickerSize,
.cacheTag = Tag::ChatIntroHelloSticker, .cacheTag = Tag::ChatIntroHelloSticker,
.singleTimePlayback = v::is<GiftTypePremium>(descriptor), .singleTimePlayback = v::is<GiftTypePremium>(descriptor),
@ -296,9 +307,10 @@ void ShowSentToast(
const auto &st = st::historyPremiumToast; const auto &st = st::historyPremiumToast;
const auto skip = st.padding.top(); const auto skip = st.padding.top();
const auto size = st.style.font->height * 2; const auto size = st.style.font->height * 2;
const auto document = LookupGiftSticker(&window->session(), descriptor); const auto stickerId = GiftStickerId(&window->session(), descriptor);
const auto leftSkip = document const auto stickerSize = skip + size + skip;
? (skip + size + skip - st.padding.left()) const auto leftSkip = stickerId
? (stickerSize - st.padding.left())
: 0; : 0;
auto text = v::match(descriptor, [&](const GiftTypePremium &gift) { auto text = v::match(descriptor, [&](const GiftTypePremium &gift) {
return tr::lng_action_gift_premium_about( return tr::lng_action_gift_premium_about(
@ -319,40 +331,31 @@ void ShowSentToast(
.attach = RectPart::Top, .attach = RectPart::Top,
.duration = kSentToastDuration, .duration = kSentToastDuration,
}).get(); }).get();
if (!strong || !document) { if (!strong || !stickerId) {
return; return;
} }
const auto widget = strong->widget(); const auto widget = strong->widget();
const auto preview = Ui::CreateChild<Ui::RpWidget>(widget.get()); const auto preview = Ui::CreateChild<Ui::RpWidget>(widget.get());
preview->moveToLeft(skip, skip); preview->moveToLeft(0, 0);
preview->resize(size, size); preview->resize(stickerSize, stickerSize);
preview->show(); preview->show();
const auto bytes = document->createMediaView()->bytes(); const auto tag = Data::CustomEmojiManager::SizeTag::Isolated;
const auto filepath = document->filepath(); const auto manager = &window->session().data().customEmojiManager();
const auto ratio = style::DevicePixelRatio(); const auto emoji = std::shared_ptr<Ui::Text::CustomEmoji>(
const auto player = preview->lifetime().make_state<Lottie::SinglePlayer>( manager->create(stickerId, [=] { preview->update(); }, tag));
Lottie::ReadContent(bytes, filepath),
Lottie::FrameRequest{ QSize(size, size) * ratio },
Lottie::Quality::Default);
preview->paintRequest( preview->paintRequest(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
if (!player->ready()) { auto p = Painter(preview);
return; const auto frame = Data::FrameSizeFromTag(tag)
} / style::DevicePixelRatio();
const auto image = player->frame(); const auto delta = (stickerSize - frame) / 2;
QPainter(preview).drawImage( emoji->paint(p, {
QRect(QPoint(), image.size() / ratio), .textColor = st::toastFg->c,
image); .now = crl::now(),
if (player->frameIndex() + 1 != player->framesCount()) { .position = QPoint(delta, delta),
player->markFrameShown(); });
}
}, preview->lifetime());
player->updates(
) | rpl::start_with_next([=] {
preview->update();
}, preview->lifetime()); }, preview->lifetime());
} }
@ -362,6 +365,8 @@ PreviewWrap::~PreviewWrap() {
void PreviewWrap::prepare(rpl::producer<GiftDetails> details) { void PreviewWrap::prepare(rpl::producer<GiftDetails> details) {
std::move(details) | rpl::start_with_next([=](GiftDetails details) { std::move(details) | rpl::start_with_next([=](GiftDetails details) {
_itemLifetime.destroy();
const auto &descriptor = details.descriptor; const auto &descriptor = details.descriptor;
const auto cost = v::match(descriptor, [&](GiftTypePremium data) { const auto cost = v::match(descriptor, [&](GiftTypePremium data) {
return FillAmountAndCurrency(data.cost, data.currency, true); return FillAmountAndCurrency(data.cost, data.currency, true);
@ -388,7 +393,12 @@ void PreviewWrap::prepare(rpl::producer<GiftDetails> details) {
auto owned = AdminLog::OwnedItem(_delegate.get(), item); auto owned = AdminLog::OwnedItem(_delegate.get(), item);
owned->overrideMedia(std::make_unique<MediaGeneric>( owned->overrideMedia(std::make_unique<MediaGeneric>(
owned.get(), owned.get(),
GenerateGiftMedia(owned.get(), _item.get(), details), GenerateGiftMedia(
owned.get(),
_item.get(),
details,
[=] { item->history()->owner().requestItemResize(item); },
&_itemLifetime),
MediaGenericDescriptor{ MediaGenericDescriptor{
.maxWidth = st::chatIntroWidth, .maxWidth = st::chatIntroWidth,
.service = true, .service = true,
@ -406,6 +416,13 @@ void PreviewWrap::prepare(rpl::producer<GiftDetails> details) {
}) | rpl::start_with_next([=](int width) { }) | rpl::start_with_next([=](int width) {
resizeTo(width); resizeTo(width);
}, lifetime()); }, lifetime());
_history->owner().itemResizeRequest(
) | rpl::start_with_next([=](not_null<const HistoryItem*> item) {
if (_item && item == _item->data() && width() >= st::msgMinWidth) {
resizeTo(width());
}
}, lifetime());
} }
void PreviewWrap::resizeTo(int width) { void PreviewWrap::resizeTo(int width) {
@ -959,7 +976,7 @@ void SoldOutBox(
.firstSaleDate = base::unixtime::parse(gift.info.firstSaleDate), .firstSaleDate = base::unixtime::parse(gift.info.firstSaleDate),
.lastSaleDate = base::unixtime::parse(gift.info.lastSaleDate), .lastSaleDate = base::unixtime::parse(gift.info.lastSaleDate),
.credits = StarsAmount(gift.info.stars), .credits = StarsAmount(gift.info.stars),
.bareGiftStickerId = gift.info.document->id, .bareGiftStickerId = gift.info.stickerId,
.peerType = Data::CreditsHistoryEntry::PeerType::Peer, .peerType = Data::CreditsHistoryEntry::PeerType::Peer,
.limitedCount = gift.info.limitedCount, .limitedCount = gift.info.limitedCount,
.limitedLeft = gift.info.limitedLeft, .limitedLeft = gift.info.limitedLeft,
@ -967,7 +984,6 @@ void SoldOutBox(
.gift = true, .gift = true,
}, },
Data::SubscriptionEntry()); Data::SubscriptionEntry());
} }
void SendGiftBox( void SendGiftBox(
@ -1009,10 +1025,6 @@ void SendGiftBox(
.descriptor = descriptor, .descriptor = descriptor,
.randomId = base::RandomValue<uint64>(), .randomId = base::RandomValue<uint64>(),
}; };
const auto document = LookupGiftSticker(&window->session(), descriptor);
if ((state->media = document ? document->createMediaView() : nullptr)) {
state->media->checkStickerLarge();
}
const auto container = box->verticalLayout(); const auto container = box->verticalLayout();
container->add(object_ptr<PreviewWrap>( container->add(object_ptr<PreviewWrap>(

View file

@ -0,0 +1,77 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Data {
struct UniqueGiftAttribute {
QString name;
int rarityPermille = 0;
};
struct UniqueGiftModel : UniqueGiftAttribute {
};
struct UniqueGiftPattern : UniqueGiftAttribute {
DocumentId documentId = 0;
};
struct UniqueGiftBackdrop : UniqueGiftAttribute {
QColor centerColor;
QColor edgeColor;
QColor patternColor;
QColor textColor;
};
struct UniqueGiftOriginalDetails {
PeerId senderId = 0;
PeerId recipientId = 0;
TimeId date = 0;
TextWithEntities message;
};
struct UniqueGift {
QString title;
int number = 0;
PeerId ownerId = 0;
UniqueGiftModel model;
UniqueGiftPattern pattern;
UniqueGiftBackdrop backdrop;
UniqueGiftOriginalDetails originalDetails;
};
struct StarGift {
uint64 id = 0;
std::shared_ptr<UniqueGift> unique;
int64 stars = 0;
int64 starsConverted = 0;
DocumentId stickerId = 0;
int limitedLeft = 0;
int limitedCount = 0;
TimeId firstSaleDate = 0;
TimeId lastSaleDate = 0;
bool birthday = false;
friend inline bool operator==(
const StarGift &,
const StarGift &) = default;
};
struct UserStarGift {
StarGift info;
TextWithEntities message;
int64 starsConverted = 0;
PeerId fromId = 0;
MsgId messageId = 0;
TimeId date = 0;
bool anonymous = false;
bool hidden = false;
bool mine = false;
};
} // namespace Data

View file

@ -202,7 +202,7 @@ void ServiceBox::draw(Painter &p, const PaintContext &context) const {
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
const auto twidth = font->width(tag); const auto twidth = font->width(tag);
const auto pos = QPoint(_innerSize.width() - twidth, font->height); const auto pos = QPoint(_innerSize.width() - twidth, font->height);
const auto add = style::ConvertScale(2); const auto add = 0;// style::ConvertScale(2);
p.save(); p.save();
p.setClipRect( p.setClipRect(
-add, -add,

View file

@ -108,9 +108,11 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor) {
_stars.setColorOverride(Ui::Premium::CreditsIconGradientStops()); _stars.setColorOverride(Ui::Premium::CreditsIconGradientStops());
} }
}); });
if (const auto document = _delegate->lookupSticker(descriptor)) { _delegate->sticker(
descriptor
) | rpl::start_with_next([=](not_null<DocumentData*> document) {
setDocument(document); setDocument(document);
} }, lifetime());
const auto buttonw = _price.maxWidth(); const auto buttonw = _price.maxWidth();
const auto buttonh = st::semiboldFont->height; const auto buttonh = st::semiboldFont->height;
@ -186,12 +188,6 @@ void GiftButton::resizeEvent(QResizeEvent *e) {
} }
void GiftButton::paintEvent(QPaintEvent *e) { void GiftButton::paintEvent(QPaintEvent *e) {
if (!documentResolved()) {
if (const auto document = _delegate->lookupSticker(_descriptor)) {
setDocument(document);
}
}
auto p = QPainter(this); auto p = QPainter(this);
const auto hidden = v::is<GiftTypeStars>(_descriptor) const auto hidden = v::is<GiftTypeStars>(_descriptor)
&& v::get<GiftTypeStars>(_descriptor).hidden;; && v::get<GiftTypeStars>(_descriptor).hidden;;
@ -447,24 +443,54 @@ QImage Delegate::background() {
return _bg; return _bg;
} }
DocumentData *Delegate::lookupSticker(const GiftDescriptor &descriptor) { rpl::producer<not_null<DocumentData*>> Delegate::sticker(
return LookupGiftSticker(&_window->session(), descriptor); const GiftDescriptor &descriptor) {
return GiftStickerValue(&_window->session(), descriptor);
} }
not_null<StickerPremiumMark*> Delegate::hiddenMark() { not_null<StickerPremiumMark*> Delegate::hiddenMark() {
return _hiddenMark.get(); return _hiddenMark.get();
} }
DocumentData *LookupGiftSticker( DocumentId GiftStickerId(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const GiftDescriptor &descriptor) { const GiftDescriptor &descriptor) {
auto &packs = session->giftBoxStickersPacks();
packs.load();
return v::match(descriptor, [&](GiftTypePremium data) { return v::match(descriptor, [&](GiftTypePremium data) {
return packs.lookup(data.months); auto &packs = session->giftBoxStickersPacks();
packs.load();
const auto document = packs.lookup(data.months);
return document ? document->id : DocumentId();
}, [&](GiftTypeStars data) { }, [&](GiftTypeStars data) {
return data.info.document.get(); return data.info.stickerId;
}); });
} }
rpl::producer<not_null<DocumentData*>> GiftStickerValue(
not_null<Main::Session*> session,
const GiftDescriptor &descriptor) {
return v::match(descriptor, [&](GiftTypePremium data) {
const auto months = data.months;
auto &packs = session->giftBoxStickersPacks();
packs.load();
if (const auto result = packs.lookup(months)) {
return result->sticker()
? (rpl::single(not_null(result)) | rpl::type_erased())
: rpl::never<not_null<DocumentData*>>();
}
return packs.updated(
) | rpl::map([=] {
return session->giftBoxStickersPacks().lookup(data.months);
}) | rpl::filter([](DocumentData *document) {
return document && document->sticker();
}) | rpl::take(1) | rpl::map([=](DocumentData *document) {
return not_null(document);
}) | rpl::type_erased();
}, [&](GiftTypeStars data) {
return session->data().customEmojiManager().resolve(
data.info.stickerId
) | rpl::map_error_to_done();
});
}
} // namespace Info::PeerGifts } // namespace Info::PeerGifts

View file

@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
#include "api/api_premium.h" #include "data/data_star_gift.h"
#include "ui/abstract_button.h" #include "ui/abstract_button.h"
#include "ui/effects/premium_stars_colored.h" #include "ui/effects/premium_stars_colored.h"
#include "ui/text/text.h" #include "ui/text/text.h"
@ -44,7 +44,7 @@ struct GiftTypePremium {
}; };
struct GiftTypeStars { struct GiftTypeStars {
Api::StarGift info; Data::StarGift info;
PeerData *from = nullptr; PeerData *from = nullptr;
bool userpic = false; bool userpic = false;
bool hidden = false; bool hidden = false;
@ -70,7 +70,7 @@ public:
[[nodiscard]] virtual QSize buttonSize() = 0; [[nodiscard]] virtual QSize buttonSize() = 0;
[[nodiscard]] virtual QMargins buttonExtend() = 0; [[nodiscard]] virtual QMargins buttonExtend() = 0;
[[nodiscard]] virtual QImage background() = 0; [[nodiscard]] virtual QImage background() = 0;
[[nodiscard]] virtual DocumentData *lookupSticker( [[nodiscard]] virtual rpl::producer<not_null<DocumentData*>> sticker(
const GiftDescriptor &descriptor) = 0; const GiftDescriptor &descriptor) = 0;
[[nodiscard]] virtual not_null<StickerPremiumMark*> hiddenMark() = 0; [[nodiscard]] virtual not_null<StickerPremiumMark*> hiddenMark() = 0;
}; };
@ -120,7 +120,8 @@ public:
QSize buttonSize() override; QSize buttonSize() override;
QMargins buttonExtend() override; QMargins buttonExtend() override;
QImage background() override; QImage background() override;
DocumentData *lookupSticker(const GiftDescriptor &descriptor) override; rpl::producer<not_null<DocumentData*>> sticker(
const GiftDescriptor &descriptor) override;
not_null<StickerPremiumMark*> hiddenMark() override; not_null<StickerPremiumMark*> hiddenMark() override;
private: private:
@ -131,7 +132,11 @@ private:
}; };
[[nodiscard]] DocumentData *LookupGiftSticker( [[nodiscard]] DocumentId GiftStickerId(
not_null<Main::Session*> session,
const GiftDescriptor &descriptor);
[[nodiscard]] rpl::producer<not_null<DocumentData*>> GiftStickerValue(
not_null<Main::Session*> session, not_null<Main::Session*> session,
const GiftDescriptor &descriptor); const GiftDescriptor &descriptor);

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "info/peer_gifts/info_peer_gifts_widget.h" #include "info/peer_gifts/info_peer_gifts_widget.h"
#include "api/api_premium.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "info/peer_gifts/info_peer_gifts_common.h" #include "info/peer_gifts/info_peer_gifts_common.h"
@ -32,7 +33,7 @@ constexpr auto kPerPage = 50;
[[nodiscard]] GiftDescriptor DescriptorForGift( [[nodiscard]] GiftDescriptor DescriptorForGift(
not_null<UserData*> to, not_null<UserData*> to,
const Api::UserStarGift &gift) { const Data::UserStarGift &gift) {
return GiftTypeStars{ return GiftTypeStars{
.info = gift.info, .info = gift.info,
.from = ((gift.anonymous || !gift.fromId) .from = ((gift.anonymous || !gift.fromId)
@ -62,7 +63,7 @@ public:
private: private:
struct Entry { struct Entry {
Api::UserStarGift gift; Data::UserStarGift gift;
GiftDescriptor descriptor; GiftDescriptor descriptor;
}; };
struct View { struct View {

View file

@ -7,7 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
#include "api/api_premium.h" #include "data/data_star_gift.h"
#include "info/info_content_widget.h" #include "info/info_content_widget.h"
class UserData; class UserData;
@ -16,7 +16,7 @@ struct PeerListState;
namespace Info::PeerGifts { namespace Info::PeerGifts {
struct ListState { struct ListState {
std::vector<Api::UserStarGift> list; std::vector<Data::UserStarGift> list;
QString offset; QString offset;
}; };

View file

@ -1574,7 +1574,7 @@ void CreditsPrizeBox(
void UserStarGiftBox( void UserStarGiftBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
const Api::UserStarGift &data) { const Data::UserStarGift &data) {
Settings::ReceiptCreditsBox( Settings::ReceiptCreditsBox(
box, box,
controller, controller,
@ -1584,7 +1584,7 @@ void UserStarGiftBox(
.credits = StarsAmount(data.info.stars), .credits = StarsAmount(data.info.stars),
.bareMsgId = uint64(data.messageId.bare), .bareMsgId = uint64(data.messageId.bare),
.barePeerId = data.fromId.value, .barePeerId = data.fromId.value,
.bareGiftStickerId = data.info.document->id, .bareGiftStickerId = data.info.stickerId,
.peerType = Data::CreditsHistoryEntry::PeerType::Peer, .peerType = Data::CreditsHistoryEntry::PeerType::Peer,
.limitedCount = data.info.limitedCount, .limitedCount = data.info.limitedCount,
.limitedLeft = data.info.limitedLeft, .limitedLeft = data.info.limitedLeft,

View file

@ -12,16 +12,13 @@ class object_ptr;
class PeerData; class PeerData;
namespace Api {
struct UserStarGift;
} // namespace Api
namespace Data { namespace Data {
struct Boost; struct Boost;
struct CreditsHistoryEntry; struct CreditsHistoryEntry;
struct SubscriptionEntry; struct SubscriptionEntry;
struct GiftCode; struct GiftCode;
struct CreditTopupOption; struct CreditTopupOption;
struct UserStarGift;
} // namespace Data } // namespace Data
namespace Main { namespace Main {
@ -103,7 +100,7 @@ void CreditsPrizeBox(
void UserStarGiftBox( void UserStarGiftBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
const Api::UserStarGift &data); const Data::UserStarGift &data);
void StarGiftViewBox( void StarGiftViewBox(
not_null<Ui::GenericBox*> box, not_null<Ui::GenericBox*> box,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,