data_shared_media.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  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. #pragma once
  8. #include "storage/storage_shared_media.h"
  9. #include "base/weak_ptr.h"
  10. #include "base/qt/qt_compare.h"
  11. #include "data/data_sparse_ids.h"
  12. namespace Main {
  13. class Session;
  14. } // namespace Main
  15. [[nodiscard]] std::optional<Storage::SharedMediaType> SharedMediaOverviewType(
  16. Storage::SharedMediaType type);
  17. bool SharedMediaAllowSearch(Storage::SharedMediaType type);
  18. rpl::producer<SparseIdsSlice> SharedMediaViewer(
  19. not_null<Main::Session*> session,
  20. Storage::SharedMediaKey key,
  21. int limitBefore,
  22. int limitAfter);
  23. struct SharedMediaMergedKey {
  24. using Type = Storage::SharedMediaType;
  25. SharedMediaMergedKey(
  26. SparseIdsMergedSlice::Key mergedKey,
  27. Type type)
  28. : mergedKey(mergedKey)
  29. , type(type) {
  30. }
  31. bool operator==(const SharedMediaMergedKey &other) const {
  32. return (mergedKey == other.mergedKey)
  33. && (type == other.type);
  34. }
  35. SparseIdsMergedSlice::Key mergedKey;
  36. Type type = Type::kCount;
  37. };
  38. rpl::producer<SparseIdsMergedSlice> SharedScheduledMediaViewer(
  39. not_null<Main::Session*> session,
  40. SharedMediaMergedKey key,
  41. int limitBefore,
  42. int limitAfter);
  43. rpl::producer<SparseIdsMergedSlice> SharedMediaMergedViewer(
  44. not_null<Main::Session*> session,
  45. SharedMediaMergedKey key,
  46. int limitBefore,
  47. int limitAfter);
  48. class SharedMediaWithLastSlice {
  49. public:
  50. using Type = Storage::SharedMediaType;
  51. using Value = std::variant<FullMsgId, not_null<PhotoData*>>;
  52. using MessageId = SparseIdsMergedSlice::UniversalMsgId;
  53. using UniversalMsgId = std::variant<
  54. MessageId,
  55. not_null<PhotoData*>>;
  56. static constexpr auto kScheduledTopicId
  57. = SparseIdsMergedSlice::kScheduledTopicId;
  58. struct Key {
  59. Key(
  60. PeerId peerId,
  61. MsgId topicRootId,
  62. PeerId migratedPeerId,
  63. Type type,
  64. UniversalMsgId universalId)
  65. : peerId(peerId)
  66. , topicRootId(topicRootId)
  67. , migratedPeerId(migratedPeerId)
  68. , type(type)
  69. , universalId(universalId) {
  70. Expects(v::is<MessageId>(universalId) || type == Type::ChatPhoto);
  71. }
  72. friend inline constexpr auto operator<=>(
  73. const Key&,
  74. const Key&) = default;
  75. PeerId peerId = 0;
  76. MsgId topicRootId = 0;
  77. PeerId migratedPeerId = 0;
  78. Type type = Type::kCount;
  79. UniversalMsgId universalId;
  80. };
  81. SharedMediaWithLastSlice(
  82. not_null<Main::Session*> session,
  83. Key key);
  84. SharedMediaWithLastSlice(
  85. not_null<Main::Session*> session,
  86. Key key,
  87. SparseIdsMergedSlice slice,
  88. std::optional<SparseIdsMergedSlice> ending);
  89. std::optional<int> fullCount() const;
  90. std::optional<int> skippedBefore() const;
  91. std::optional<int> skippedAfter() const;
  92. std::optional<int> indexOf(Value fullId) const;
  93. int size() const;
  94. Value operator[](int index) const;
  95. std::optional<int> distance(const Key &a, const Key &b) const;
  96. void reverse();
  97. static SparseIdsMergedSlice::Key ViewerKey(const Key &key) {
  98. return {
  99. key.peerId,
  100. key.topicRootId,
  101. key.migratedPeerId,
  102. v::is<MessageId>(key.universalId)
  103. ? v::get<MessageId>(key.universalId)
  104. : ServerMaxMsgId - 1
  105. };
  106. }
  107. static SparseIdsMergedSlice::Key EndingKey(const Key &key) {
  108. return {
  109. key.peerId,
  110. key.topicRootId,
  111. key.migratedPeerId,
  112. ServerMaxMsgId - 1
  113. };
  114. }
  115. private:
  116. static std::optional<SparseIdsMergedSlice> EndingSlice(const Key &key) {
  117. return v::is<MessageId>(key.universalId)
  118. ? base::make_optional(SparseIdsMergedSlice(EndingKey(key)))
  119. : std::nullopt;
  120. }
  121. static std::optional<PhotoId> LastPeerPhotoId(
  122. not_null<Main::Session*> session,
  123. PeerId peerId);
  124. static std::optional<bool> IsLastIsolated(
  125. not_null<Main::Session*> session,
  126. const SparseIdsMergedSlice &slice,
  127. const std::optional<SparseIdsMergedSlice> &ending,
  128. std::optional<PhotoId> lastPeerPhotoId);
  129. static std::optional<FullMsgId> LastFullMsgId(
  130. const SparseIdsMergedSlice &slice);
  131. static std::optional<int> Add(
  132. const std::optional<int> &a,
  133. const std::optional<int> &b) {
  134. return (a && b) ? base::make_optional(*a + *b) : std::nullopt;
  135. }
  136. static Value ComputeId(PeerId peerId, MsgId msgId) {
  137. return FullMsgId(peerId, msgId);
  138. }
  139. static Value ComputeId(const Key &key) {
  140. if (const auto messageId = std::get_if<MessageId>(&key.universalId)) {
  141. return (*messageId >= 0)
  142. ? ComputeId(key.peerId, *messageId)
  143. : ComputeId(key.migratedPeerId, ServerMaxMsgId + *messageId);
  144. }
  145. return v::get<not_null<PhotoData*>>(key.universalId);
  146. }
  147. bool isolatedInSlice() const {
  148. return (_slice.skippedAfter() != 0);
  149. }
  150. std::optional<int> lastPhotoSkip() const {
  151. return _isolatedLastPhoto
  152. | [](bool isolated) { return isolated ? 1 : 0; };
  153. }
  154. std::optional<int> skippedBeforeImpl() const;
  155. std::optional<int> skippedAfterImpl() const;
  156. std::optional<int> indexOfImpl(Value fullId) const;
  157. not_null<Main::Session*> _session;
  158. Key _key;
  159. SparseIdsMergedSlice _slice;
  160. std::optional<SparseIdsMergedSlice> _ending;
  161. std::optional<PhotoId> _lastPhotoId;
  162. std::optional<bool> _isolatedLastPhoto;
  163. bool _reversed = false;
  164. };
  165. rpl::producer<SharedMediaWithLastSlice> SharedMediaWithLastViewer(
  166. not_null<Main::Session*> session,
  167. SharedMediaWithLastSlice::Key key,
  168. int limitBefore,
  169. int limitAfter);
  170. rpl::producer<SharedMediaWithLastSlice> SharedMediaWithLastReversedViewer(
  171. not_null<Main::Session*> session,
  172. SharedMediaWithLastSlice::Key key,
  173. int limitBefore,
  174. int limitAfter);