stickers_gift_box_pack.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "chat_helpers/stickers_gift_box_pack.h"
  8. #include "apiwrap.h"
  9. #include "data/data_document.h"
  10. #include "data/data_file_origin.h"
  11. #include "data/data_session.h"
  12. #include "main/main_session.h"
  13. namespace Stickers {
  14. GiftBoxPack::GiftBoxPack(not_null<Main::Session*> session)
  15. : _session(session)
  16. , _localMonths({ 1, 3, 6, 12, 24 }) {
  17. }
  18. GiftBoxPack::~GiftBoxPack() = default;
  19. rpl::producer<> GiftBoxPack::updated() const {
  20. return _updated.events();
  21. }
  22. int GiftBoxPack::monthsForStars(int stars) const {
  23. if (stars <= 1000) {
  24. return 3;
  25. } else if (stars < 2500) {
  26. return 6;
  27. } else {
  28. return 12;
  29. }
  30. }
  31. DocumentData *GiftBoxPack::lookup(int months) const {
  32. const auto it = ranges::lower_bound(_localMonths, months);
  33. const auto fallback = _documents.empty() ? nullptr : _documents[0];
  34. if (it == begin(_localMonths)) {
  35. return fallback;
  36. } else if (it == end(_localMonths)) {
  37. return _documents.back();
  38. }
  39. const auto left = *(it - 1);
  40. const auto right = *it;
  41. const auto shift = (std::abs(months - left) < std::abs(months - right))
  42. ? -1
  43. : 0;
  44. const auto index = int(std::distance(begin(_localMonths), it - shift));
  45. return (index >= _documents.size()) ? fallback : _documents[index];
  46. }
  47. Data::FileOrigin GiftBoxPack::origin() const {
  48. return Data::FileOriginStickerSet(_setId, _accessHash);
  49. }
  50. void GiftBoxPack::load() {
  51. if (_requestId || !_documents.empty()) {
  52. return;
  53. }
  54. _requestId = _session->api().request(MTPmessages_GetStickerSet(
  55. MTP_inputStickerSetPremiumGifts(),
  56. MTP_int(0) // Hash.
  57. )).done([=](const MTPmessages_StickerSet &result) {
  58. _requestId = 0;
  59. result.match([&](const MTPDmessages_stickerSet &data) {
  60. applySet(data);
  61. }, [](const MTPDmessages_stickerSetNotModified &) {
  62. LOG(("API Error: Unexpected messages.stickerSetNotModified."));
  63. });
  64. }).fail([=] {
  65. _requestId = 0;
  66. }).send();
  67. }
  68. void GiftBoxPack::applySet(const MTPDmessages_stickerSet &data) {
  69. _setId = data.vset().data().vid().v;
  70. _accessHash = data.vset().data().vaccess_hash().v;
  71. auto documents = base::flat_map<DocumentId, not_null<DocumentData*>>();
  72. for (const auto &sticker : data.vdocuments().v) {
  73. const auto document = _session->data().processDocument(sticker);
  74. if (document->sticker()) {
  75. documents.emplace(document->id, document);
  76. if (_documents.empty()) {
  77. // Fallback.
  78. _documents.resize(1);
  79. _documents[0] = document;
  80. }
  81. }
  82. }
  83. for (const auto &pack : data.vpacks().v) {
  84. pack.match([&](const MTPDstickerPack &data) {
  85. const auto emoji = qs(data.vemoticon());
  86. if (emoji.isEmpty()) {
  87. return;
  88. }
  89. for (const auto &id : data.vdocuments().v) {
  90. if (const auto document = documents.take(id.v)) {
  91. if (const auto sticker = (*document)->sticker()) {
  92. if (!sticker->alt.isEmpty()) {
  93. const auto ch = int(sticker->alt[0].unicode());
  94. const auto index = (ch - '1'); // [0, 4];
  95. if (index < 0 || index >= _localMonths.size()) {
  96. return;
  97. }
  98. if ((index + 1) > _documents.size()) {
  99. _documents.resize((index + 1));
  100. }
  101. _documents[index] = (*document);
  102. }
  103. }
  104. }
  105. }
  106. });
  107. }
  108. _updated.fire({});
  109. }
  110. } // namespace Stickers