Add support for star gifts API.

This commit is contained in:
John Preston 2024-09-16 13:34:53 +04:00
parent 46c8a55f56
commit 71deef61f5
3 changed files with 101 additions and 26 deletions

View file

@ -589,6 +589,51 @@ Data::PremiumSubscriptionOptions PremiumGiftCodeOptions::options(int amount) {
}
}
auto PremiumGiftCodeOptions::requestStarGifts()
-> rpl::producer<rpl::no_value, QString> {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
_api.request(MTPpayments_GetStarGifts(
MTP_int(0)
)).done([=](const MTPpayments_StarGifts &result) {
result.match([&](const MTPDpayments_starGifts &data) {
_giftsHash = data.vhash().v;
const auto &list = data.vgifts().v;
auto gifts = std::vector<StarGift>();
gifts.reserve(list.size());
for (const auto &gift : list) {
const auto &data = gift.data();
const auto document = _peer->owner().processDocument(
data.vsticker());
const auto remaining = data.vavailability_remains();
const auto total = data.vavailability_total();
if (document->sticker()) {
gifts.push_back(StarGift{
.id = uint64(data.vid().v),
.stars = int64(data.vstars().v),
.document = document,
.limitedLeft = remaining.value_or_empty(),
.limitedCount = total.value_or_empty(),
});
}
}
_gifts = std::move(gifts);
}, [&](const MTPDpayments_starGiftsNotModified &) {
});
consumer.put_done();
}).fail([=](const MTP::Error &error) {
consumer.put_error_copy(error.type());
}).send();
return lifetime;
};
}
const std::vector<StarGift> &PremiumGiftCodeOptions::starGifts() const {
return _gifts;
}
int PremiumGiftCodeOptions::giveawayBoostsPerPremium() const {
constexpr auto kFallbackCount = 4;
return _peer->session().appConfig().get<int>(

View file

@ -73,6 +73,14 @@ struct GiftOptionData {
int months = 0;
};
struct StarGift {
uint64 id = 0;
int64 stars = 0;
not_null<DocumentData*> document;
int limitedLeft = 0;
int limitedCount = 0;
};
class Premium final {
public:
explicit Premium(not_null<ApiWrap*> api);
@ -194,6 +202,9 @@ public:
[[nodiscard]] int giveawayPeriodMax() const;
[[nodiscard]] bool giveawayGiftsPurchaseAvailable() const;
[[nodiscard]] rpl::producer<rpl::no_value, QString> requestStarGifts();
[[nodiscard]] const std::vector<StarGift> &starGifts() const;
private:
struct Token final {
int users = 0;
@ -221,6 +232,9 @@ private:
base::flat_map<Token, Store> _stores;
int32 _giftsHash = 0;
std::vector<StarGift> _gifts;
MTP::Sender _api;
};

View file

@ -84,8 +84,9 @@ struct GiftTypePremium {
};
struct GiftTypeStars {
uint64 id = 0;
int64 stars = 0;
DocumentData *document = nullptr;
int stars = 0;
bool limited = false;
[[nodiscard]] friend inline bool operator==(
@ -409,8 +410,11 @@ void PreviewWrap::paintEvent(QPaintEvent *e) {
}
}
ranges::sort(list, ranges::less(), &GiftTypePremium::months);
Map[session].last = list;
consumer.put_next_copy(list);
auto &map = Map[session];
if (map.last != list) {
map.last = list;
consumer.put_next_copy(list);
}
}, lifetime);
return lifetime;
@ -420,34 +424,46 @@ void PreviewWrap::paintEvent(QPaintEvent *e) {
[[nodiscard]] rpl::producer<std::vector<GiftTypeStars>> GiftsStars(
not_null<Main::Session*> session,
not_null<PeerData*> peer) {
//struct Session {
// std::vector<GiftTypeStars> last;
//};
//static auto Map = base::flat_map<not_null<Main::Session*>, Session>();
struct Session {
std::vector<GiftTypeStars> last;
};
static auto Map = base::flat_map<not_null<Main::Session*>, Session>();
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
auto list = std::vector<GiftTypeStars>();
auto i = Map.find(session);
if (i == end(Map)) {
i = Map.emplace(session, Session()).first;
session->lifetime().add([=] { Map.remove(session); });
}
if (!i->second.last.empty()) {
consumer.put_next_copy(i->second.last);
}
const auto add = [&](uint64 setId, int price, bool limited) {
auto &sets = session->data().stickers().setsRef();
const auto i = sets.find(setId);
if (i != end(sets)) {
for (const auto document : i->second->stickers) {
price = document->isPremiumSticker() ? 1000 : price;
list.push_back({
.document = document,
.stars = price,
.limited = limited,
});
}
using namespace Api;
const auto api = lifetime.make_state<PremiumGiftCodeOptions>(peer);
api->requestStarGifts(
) | rpl::start_with_error_done([=](QString error) {
consumer.put_next({});
}, [=] {
auto list = std::vector<GiftTypeStars>();
const auto &gifts = api->starGifts();
list.reserve(gifts.size());
for (auto &gift : gifts) {
list.push_back({
.id = gift.id,
.stars = gift.stars,
.document = gift.document,
.limited = (gift.limitedCount > 0),
});
}
};
add(Data::Stickers::CloudRecentSetId, 100, false);
add(Data::Stickers::RecentSetId, 250, false);
add(Data::Stickers::FavedSetId, 50, true);
consumer.put_next(std::move(list));
auto &map = Map[session];
if (map.last != list) {
map.last = list;
consumer.put_next_copy(list);
}
}, lifetime);
return lifetime;
};