data_stickers_set.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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 "data/stickers/data_stickers_set.h"
  8. #include "main/main_session.h"
  9. #include "data/data_session.h"
  10. #include "data/data_file_origin.h"
  11. #include "data/data_document.h"
  12. #include "data/stickers/data_stickers.h"
  13. #include "storage/file_download.h"
  14. #include "ui/image/image.h"
  15. namespace Data {
  16. StickersSetThumbnailView::StickersSetThumbnailView(
  17. not_null<StickersSet*> owner)
  18. : _owner(owner) {
  19. }
  20. not_null<StickersSet*> StickersSetThumbnailView::owner() const {
  21. return _owner;
  22. }
  23. void StickersSetThumbnailView::set(
  24. not_null<Main::Session*> session,
  25. QByteArray content) {
  26. auto image = Images::Read({ .content = content }).image;
  27. if (image.isNull()) {
  28. _content = std::move(content);
  29. } else {
  30. _image = std::make_unique<Image>(std::move(image));
  31. }
  32. session->notifyDownloaderTaskFinished();
  33. }
  34. Image *StickersSetThumbnailView::image() const {
  35. return _image.get();
  36. }
  37. QByteArray StickersSetThumbnailView::content() const {
  38. return _content;
  39. }
  40. StickersSetFlags ParseStickersSetFlags(const MTPDstickerSet &data) {
  41. using Flag = StickersSetFlag;
  42. return (data.is_archived() ? Flag::Archived : Flag())
  43. | (data.is_official() ? Flag::Official : Flag())
  44. | (data.is_masks() ? Flag::Masks : Flag())
  45. | (data.is_emojis() ? Flag::Emoji : Flag())
  46. | (data.vinstalled_date() ? Flag::Installed : Flag())
  47. //| (data.is_videos() ? Flag::Webm : Flag())
  48. | (data.is_text_color() ? Flag::TextColor : Flag())
  49. | (data.is_channel_emoji_status() ? Flag::ChannelStatus : Flag())
  50. | (data.is_creator() ? Flag::AmCreator : Flag());
  51. }
  52. StickersSet::StickersSet(
  53. not_null<Data::Session*> owner,
  54. uint64 id,
  55. uint64 accessHash,
  56. uint64 hash,
  57. const QString &title,
  58. const QString &shortName,
  59. int count,
  60. StickersSetFlags flags,
  61. TimeId installDate)
  62. : id(id)
  63. , accessHash(accessHash)
  64. , hash(hash)
  65. , title(title)
  66. , shortName(shortName)
  67. , count(count)
  68. , flags(flags)
  69. , installDate(installDate)
  70. , _owner(owner) {
  71. }
  72. StickersSet::~StickersSet() = default;
  73. Data::Session &StickersSet::owner() const {
  74. return *_owner;
  75. }
  76. Main::Session &StickersSet::session() const {
  77. return _owner->session();
  78. }
  79. MTPInputStickerSet StickersSet::mtpInput() const {
  80. return (id && accessHash)
  81. ? MTP_inputStickerSetID(MTP_long(id), MTP_long(accessHash))
  82. : MTP_inputStickerSetShortName(MTP_string(shortName));
  83. }
  84. StickerSetIdentifier StickersSet::identifier() const {
  85. return StickerSetIdentifier{
  86. .id = id,
  87. .accessHash = accessHash,
  88. };
  89. }
  90. StickersType StickersSet::type() const {
  91. return (flags & StickersSetFlag::Emoji)
  92. ? StickersType::Emoji
  93. : (flags & StickersSetFlag::Masks)
  94. ? StickersType::Masks
  95. : StickersType::Stickers;
  96. }
  97. bool StickersSet::textColor() const {
  98. return flags & StickersSetFlag::TextColor;
  99. }
  100. bool StickersSet::channelStatus() const {
  101. return flags & StickersSetFlag::ChannelStatus;
  102. }
  103. void StickersSet::setThumbnail(
  104. const ImageWithLocation &data,
  105. StickerType type) {
  106. _thumbnailType = type;
  107. Data::UpdateCloudFile(
  108. _thumbnail,
  109. data,
  110. _owner->cache(),
  111. Data::kImageCacheTag,
  112. [=](Data::FileOrigin origin) { loadThumbnail(); });
  113. if (!data.bytes.isEmpty()) {
  114. if (_thumbnail.loader) {
  115. _thumbnail.loader->cancel();
  116. }
  117. if (const auto view = activeThumbnailView()) {
  118. view->set(&_owner->session(), data.bytes);
  119. }
  120. }
  121. }
  122. bool StickersSet::hasThumbnail() const {
  123. return _thumbnail.location.valid();
  124. }
  125. StickerType StickersSet::thumbnailType() const {
  126. return _thumbnailType;
  127. }
  128. bool StickersSet::thumbnailLoading() const {
  129. return (_thumbnail.loader != nullptr);
  130. }
  131. bool StickersSet::thumbnailFailed() const {
  132. return (_thumbnail.flags & Data::CloudFile::Flag::Failed);
  133. }
  134. void StickersSet::loadThumbnail() {
  135. const auto autoLoading = false;
  136. const auto finalCheck = [=] {
  137. if (const auto active = activeThumbnailView()) {
  138. return !active->image() && active->content().isEmpty();
  139. }
  140. return true;
  141. };
  142. const auto done = [=](QByteArray result) {
  143. if (const auto active = activeThumbnailView()) {
  144. active->set(&_owner->session(), std::move(result));
  145. }
  146. };
  147. Data::LoadCloudFile(
  148. &_owner->session(),
  149. _thumbnail,
  150. Data::FileOriginStickerSet(id, accessHash),
  151. LoadFromCloudOrLocal,
  152. autoLoading,
  153. Data::kImageCacheTag,
  154. finalCheck,
  155. done);
  156. }
  157. const ImageLocation &StickersSet::thumbnailLocation() const {
  158. return _thumbnail.location;
  159. }
  160. Storage::Cache::Key StickersSet::thumbnailBigFileBaseCacheKey() const {
  161. const auto &location = _thumbnail.location.file().data;
  162. if (const auto storage = std::get_if<StorageFileLocation>(&location)) {
  163. return storage->bigFileBaseCacheKey();
  164. }
  165. return {};
  166. }
  167. int StickersSet::thumbnailByteSize() const {
  168. return _thumbnail.byteSize;
  169. }
  170. DocumentData *StickersSet::lookupThumbnailDocument() const {
  171. if (thumbnailDocumentId) {
  172. const auto i = ranges::find(
  173. stickers,
  174. thumbnailDocumentId,
  175. &DocumentData::id);
  176. if (i != stickers.end()) {
  177. return *i;
  178. }
  179. }
  180. return !stickers.empty()
  181. ? stickers.front()
  182. : !covers.empty()
  183. ? covers.front()
  184. : nullptr;
  185. }
  186. std::shared_ptr<StickersSetThumbnailView> StickersSet::createThumbnailView() {
  187. if (auto active = activeThumbnailView()) {
  188. return active;
  189. }
  190. auto view = std::make_shared<StickersSetThumbnailView>(this);
  191. _thumbnailView = view;
  192. return view;
  193. }
  194. std::shared_ptr<StickersSetThumbnailView> StickersSet::activeThumbnailView() {
  195. return _thumbnailView.lock();
  196. }
  197. MTPInputStickerSet InputStickerSet(StickerSetIdentifier id) {
  198. return !id
  199. ? MTP_inputStickerSetEmpty()
  200. : id.id
  201. ? MTP_inputStickerSetID(MTP_long(id.id), MTP_long(id.accessHash))
  202. : MTP_inputStickerSetShortName(MTP_string(id.shortName));
  203. }
  204. StickerSetIdentifier FromInputSet(const MTPInputStickerSet &id) {
  205. return id.match([](const MTPDinputStickerSetID &data) {
  206. return StickerSetIdentifier{
  207. .id = data.vid().v,
  208. .accessHash = data.vaccess_hash().v,
  209. };
  210. }, [](const MTPDinputStickerSetShortName &data) {
  211. return StickerSetIdentifier{ .shortName = qs(data.vshort_name()) };
  212. }, [](const auto &) {
  213. return StickerSetIdentifier();
  214. });
  215. }
  216. } // namespace Stickers