storage_user_photos.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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 <rpl/event_stream.h>
  9. #include "storage/storage_facade.h"
  10. namespace Storage {
  11. struct UserPhotosSetBack {
  12. UserPhotosSetBack(UserId userId, PhotoId photoId)
  13. : userId(userId), photoId(photoId) {
  14. }
  15. UserId userId = 0;
  16. PhotoId photoId = 0;
  17. };
  18. struct UserPhotosAddNew {
  19. UserPhotosAddNew(UserId userId, PhotoId photoId)
  20. : userId(userId), photoId(photoId) {
  21. }
  22. UserId userId = 0;
  23. PhotoId photoId = 0;
  24. };
  25. struct UserPhotosAddSlice {
  26. UserPhotosAddSlice(
  27. UserId userId,
  28. std::vector<PhotoId> &&photoIds,
  29. int count)
  30. : userId(userId)
  31. , photoIds(std::move(photoIds))
  32. , count(count) {
  33. }
  34. UserId userId = 0;
  35. std::vector<PhotoId> photoIds;
  36. int count = 0;
  37. };
  38. struct UserPhotosRemoveOne {
  39. UserPhotosRemoveOne(
  40. UserId userId,
  41. PhotoId photoId)
  42. : userId(userId)
  43. , photoId(photoId) {
  44. }
  45. UserId userId = 0;
  46. PhotoId photoId = 0;
  47. };
  48. struct UserPhotosRemoveAfter {
  49. UserPhotosRemoveAfter(
  50. UserId userId,
  51. PhotoId photoId)
  52. : userId(userId)
  53. , photoId(photoId) {
  54. }
  55. UserId userId = 0;
  56. PhotoId photoId = 0;
  57. };
  58. struct UserPhotosKey {
  59. UserPhotosKey(
  60. UserId userId,
  61. PhotoId photoId)
  62. : userId(userId)
  63. , photoId(photoId) {
  64. }
  65. UserPhotosKey(UserId userId, bool back) : userId(userId), back(back) {
  66. }
  67. bool operator==(const UserPhotosKey &other) const {
  68. return (userId == other.userId)
  69. && (photoId == other.photoId)
  70. && (back == other.back);
  71. }
  72. bool operator!=(const UserPhotosKey &other) const {
  73. return !(*this == other);
  74. }
  75. UserId userId = 0;
  76. PhotoId photoId = 0;
  77. bool back = false;
  78. };
  79. struct UserPhotosQuery {
  80. UserPhotosQuery(
  81. UserPhotosKey key,
  82. int limitBefore,
  83. int limitAfter)
  84. : key(key)
  85. , limitBefore(limitBefore)
  86. , limitAfter(limitAfter) {
  87. }
  88. UserPhotosKey key;
  89. int limitBefore = 0;
  90. int limitAfter = 0;
  91. };
  92. struct UserPhotosResult {
  93. std::optional<int> count;
  94. std::optional<int> skippedBefore;
  95. int skippedAfter = 0;
  96. std::deque<PhotoId> photoIds;
  97. };
  98. struct UserPhotosSliceUpdate {
  99. UserPhotosSliceUpdate(
  100. UserId userId,
  101. const std::deque<PhotoId> *photoIds,
  102. std::optional<int> count)
  103. : userId(userId)
  104. , photoIds(photoIds)
  105. , count(count) {
  106. }
  107. UserId userId = 0;
  108. const std::deque<PhotoId> *photoIds = nullptr;
  109. std::optional<int> count;
  110. };
  111. class UserPhotos {
  112. public:
  113. void add(UserPhotosSetBack &&query);
  114. void add(UserPhotosAddNew &&query);
  115. void add(UserPhotosAddSlice &&query);
  116. void remove(UserPhotosRemoveOne &&query);
  117. void remove(UserPhotosRemoveAfter &&query);
  118. rpl::producer<UserPhotosResult> query(UserPhotosQuery &&query) const;
  119. rpl::producer<UserPhotosSliceUpdate> sliceUpdated() const;
  120. private:
  121. class List {
  122. public:
  123. void setBack(PhotoId photoId);
  124. void addNew(PhotoId photoId);
  125. void addSlice(
  126. std::vector<PhotoId> &&photoIds,
  127. int count);
  128. void removeOne(PhotoId photoId);
  129. void removeAfter(PhotoId photoId);
  130. rpl::producer<UserPhotosResult> query(UserPhotosQuery &&query) const;
  131. struct SliceUpdate {
  132. const std::deque<PhotoId> *photoIds = nullptr;
  133. std::optional<int> count;
  134. };
  135. rpl::producer<SliceUpdate> sliceUpdated() const;
  136. private:
  137. void sendUpdate();
  138. void detachBack();
  139. void attachBack();
  140. std::optional<int> _count;
  141. std::deque<PhotoId> _photoIds;
  142. PhotoId _backPhotoId = PhotoId(0);
  143. rpl::event_stream<SliceUpdate> _sliceUpdated;
  144. };
  145. using SliceUpdate = List::SliceUpdate;
  146. std::map<UserId, List>::iterator enforceLists(UserId user);
  147. std::map<UserId, List> _lists;
  148. rpl::event_stream<UserPhotosSliceUpdate> _sliceUpdated;
  149. rpl::lifetime _lifetime;
  150. };
  151. } // namespace Storage