Added support of special sticker pack for currency history entries.

This commit is contained in:
23rd 2025-06-29 20:58:40 +03:00
parent d1796a515e
commit a809ccf229
4 changed files with 82 additions and 36 deletions

View file

@ -36,38 +36,61 @@ int GiftBoxPack::monthsForStars(int stars) const {
}
}
DocumentData *GiftBoxPack::lookup(int months) const {
const auto it = ranges::lower_bound(_localMonths, months);
const auto fallback = _documents.empty() ? nullptr : _documents[0];
if (it == begin(_localMonths)) {
return fallback;
} else if (it == end(_localMonths)) {
return _documents.back();
DocumentData *GiftBoxPack::lookup(int months, Type type) const {
const auto it = _setsData.find(type);
if (it == _setsData.end() || it->second.documents.empty()) {
return nullptr;
}
const auto left = *(it - 1);
const auto right = *it;
const auto& documents = it->second.documents;
const auto itMonths = ranges::lower_bound(_localMonths, months);
const auto fallback = documents[0];
if (itMonths == begin(_localMonths)) {
return fallback;
} else if (itMonths == end(_localMonths)) {
return documents.back();
}
const auto left = *(itMonths - 1);
const auto right = *itMonths;
const auto shift = (std::abs(months - left) < std::abs(months - right))
? -1
: 0;
const auto index = int(std::distance(begin(_localMonths), it - shift));
return (index >= _documents.size()) ? fallback : _documents[index];
const auto index = int(
std::distance(begin(_localMonths), itMonths - shift));
return (index >= documents.size()) ? fallback : documents[index];
}
Data::FileOrigin GiftBoxPack::origin() const {
return Data::FileOriginStickerSet(_setId, _accessHash);
Data::FileOrigin GiftBoxPack::origin(Type type) const {
const auto it = _setsData.find(type);
if (it == _setsData.end()) {
return Data::FileOrigin();
}
return Data::FileOriginStickerSet(
it->second.setId,
it->second.accessHash);
}
void GiftBoxPack::load() {
if (_requestId || !_documents.empty()) {
void GiftBoxPack::load(Type type) {
if (_requestId) {
return;
}
const auto it = _setsData.find(type);
if (it != _setsData.end() && !it->second.documents.empty()) {
return;
}
_requestId = _session->api().request(MTPmessages_GetStickerSet(
MTP_inputStickerSetPremiumGifts(),
type == Type::Currency
? MTP_inputStickerSetTonGifts()
: MTP_inputStickerSetPremiumGifts(),
MTP_int(0) // Hash.
)).done([=](const MTPmessages_StickerSet &result) {
_requestId = 0;
result.match([&](const MTPDmessages_stickerSet &data) {
applySet(data);
applySet(data, type);
}, [](const MTPDmessages_stickerSetNotModified &) {
LOG(("API Error: Unexpected messages.stickerSetNotModified."));
});
@ -76,21 +99,24 @@ void GiftBoxPack::load() {
}).send();
}
void GiftBoxPack::applySet(const MTPDmessages_stickerSet &data) {
_setId = data.vset().data().vid().v;
_accessHash = data.vset().data().vaccess_hash().v;
void GiftBoxPack::applySet(const MTPDmessages_stickerSet &data, Type type) {
auto setData = SetData();
setData.setId = data.vset().data().vid().v;
setData.accessHash = data.vset().data().vaccess_hash().v;
auto documents = base::flat_map<DocumentId, not_null<DocumentData*>>();
for (const auto &sticker : data.vdocuments().v) {
const auto document = _session->data().processDocument(sticker);
if (document->sticker()) {
documents.emplace(document->id, document);
if (_documents.empty()) {
if (setData.documents.empty()) {
// Fallback.
_documents.resize(1);
_documents[0] = document;
setData.documents.resize(1);
setData.documents[0] = document;
}
}
}
for (const auto &pack : data.vpacks().v) {
pack.match([&](const MTPDstickerPack &data) {
const auto emoji = qs(data.vemoticon());
@ -106,16 +132,18 @@ void GiftBoxPack::applySet(const MTPDmessages_stickerSet &data) {
if (index < 0 || index >= _localMonths.size()) {
return;
}
if ((index + 1) > _documents.size()) {
_documents.resize((index + 1));
if ((index + 1) > setData.documents.size()) {
setData.documents.resize((index + 1));
}
_documents[index] = (*document);
setData.documents[index] = (*document);
}
}
}
}
});
}
_setsData[type] = std::move(setData);
_updated.fire({});
}

View file

@ -21,26 +21,37 @@ namespace Stickers {
class GiftBoxPack final {
public:
enum class Type {
Gifts,
Currency,
};
explicit GiftBoxPack(not_null<Main::Session*> session);
~GiftBoxPack();
void load();
void load(Type type = Type::Gifts);
[[nodiscard]] int monthsForStars(int stars) const;
[[nodiscard]] DocumentData *lookup(int months) const;
[[nodiscard]] Data::FileOrigin origin() const;
[[nodiscard]] DocumentData *lookup(
int months,
Type type = Type::Gifts) const;
[[nodiscard]] Data::FileOrigin origin(Type type = Type::Gifts) const;
[[nodiscard]] rpl::producer<> updated() const;
private:
using SetId = uint64;
void applySet(const MTPDmessages_stickerSet &data);
struct SetData {
SetId setId = 0;
uint64 accessHash = 0;
std::vector<DocumentData*> documents;
};
void applySet(const MTPDmessages_stickerSet &data, Type type);
const not_null<Main::Session*> _session;
const std::vector<int> _localMonths;
rpl::event_stream<> _updated;
std::vector<DocumentData*> _documents;
SetId _setId = 0;
uint64 _accessHash = 0;
base::flat_map<Type, SetData> _setsData;
mtpRequestId _requestId = 0;
};

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/star_gift_box.h"
#include "boxes/gift_credits_box.h"
#include "boxes/gift_premium_box.h"
#include "chat_helpers/stickers_gift_box_pack.h"
#include "core/click_handler_types.h"
#include "data/components/credits.h"
#include "data/data_file_origin.h"
@ -120,6 +121,8 @@ Credits::Credits(
st::tonFieldIconSize,
st::windowActiveTextFg->c)
: Ui::GenerateStars(st::creditsBalanceStarHeight, 1)) {
_controller->session().giftBoxStickersPacks().load(
Stickers::GiftBoxPack::Type::Currency);
setupContent();
_controller->session().premiumPossibleValue(

View file

@ -1311,9 +1311,13 @@ void GenericCreditsEntryBox(
auto &packs = session->giftBoxStickersPacks();
const auto document = starGiftSticker
? starGiftSticker
: packs.lookup(e.premiumMonthsForStars
? e.premiumMonthsForStars
: packs.monthsForStars(e.credits.whole()));
: packs.lookup(
e.premiumMonthsForStars
? e.premiumMonthsForStars
: packs.monthsForStars(e.credits.whole()),
e.credits.stars()
? Stickers::GiftBoxPack::Type::Gifts
: Stickers::GiftBoxPack::Type::Currency);
if (document && document->sticker()) {
state->sticker = document;
state->media = document->createMediaView();