mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Parse unique gift fields.
This commit is contained in:
parent
d874829b06
commit
5f3db95cbd
12 changed files with 249 additions and 113 deletions
|
@ -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
|
||||||
|
|
|
@ -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{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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>(
|
||||||
|
|
77
Telegram/SourceFiles/data/data_star_gift.h
Normal file
77
Telegram/SourceFiles/data/data_star_gift.h
Normal 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
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue