dialogs_suggestions.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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 "base/object_ptr.h"
  9. #include "base/timer.h"
  10. #include "dialogs/ui/top_peers_strip.h"
  11. #include "ui/effects/animations.h"
  12. #include "ui/rp_widget.h"
  13. class PeerListContent;
  14. namespace Data {
  15. class Thread;
  16. } // namespace Data
  17. namespace Info {
  18. class WrapWidget;
  19. } // namespace Info
  20. namespace Main {
  21. class Session;
  22. } // namespace Main
  23. namespace Storage {
  24. enum class SharedMediaType : signed char;
  25. } // namespace Storage
  26. namespace Ui {
  27. class BoxContent;
  28. class ScrollArea;
  29. class ElasticScroll;
  30. class SettingsSlider;
  31. class VerticalLayout;
  32. template <typename Widget>
  33. class SlideWrap;
  34. } // namespace Ui
  35. namespace Window {
  36. class SessionController;
  37. } // namespace Window
  38. namespace Dialogs {
  39. enum class SearchEmptyIcon;
  40. struct RecentPeersList {
  41. std::vector<not_null<PeerData*>> list;
  42. };
  43. class Suggestions final : public Ui::RpWidget {
  44. public:
  45. Suggestions(
  46. not_null<QWidget*> parent,
  47. not_null<Window::SessionController*> controller,
  48. rpl::producer<TopPeersList> topPeers,
  49. RecentPeersList recentPeers);
  50. ~Suggestions();
  51. void selectJump(Qt::Key direction, int pageSize = 0);
  52. void chooseRow();
  53. bool consumeSearchQuery(const QString &query);
  54. [[nodiscard]] rpl::producer<> clearSearchQueryRequests() const;
  55. [[nodiscard]] Data::Thread *updateFromParentDrag(QPoint globalPosition);
  56. void dragLeft();
  57. void show(anim::type animated, Fn<void()> finish);
  58. void hide(anim::type animated, Fn<void()> finish);
  59. [[nodiscard]] float64 shownOpacity() const;
  60. [[nodiscard]] bool persist() const;
  61. void clearPersistance();
  62. [[nodiscard]] rpl::producer<not_null<PeerData*>> topPeerChosen() const {
  63. return _topPeerChosen.events();
  64. }
  65. [[nodiscard]] auto recentPeerChosen() const
  66. -> rpl::producer<not_null<PeerData*>> {
  67. return _recent->chosen.events();
  68. }
  69. [[nodiscard]] auto myChannelChosen() const
  70. -> rpl::producer<not_null<PeerData*>> {
  71. return _myChannels->chosen.events();
  72. }
  73. [[nodiscard]] auto recommendationChosen() const
  74. -> rpl::producer<not_null<PeerData*>> {
  75. return _recommendations->chosen.events();
  76. }
  77. [[nodiscard]] auto recentAppChosen() const
  78. -> rpl::producer<not_null<PeerData*>> {
  79. return _recentApps->chosen.events();
  80. }
  81. [[nodiscard]] auto popularAppChosen() const
  82. -> rpl::producer<not_null<PeerData*>> {
  83. return _popularApps->chosen.events();
  84. }
  85. [[nodiscard]] auto openBotMainAppRequests() const
  86. -> rpl::producer<not_null<PeerData*>> {
  87. return _openBotMainAppRequests.events();
  88. }
  89. class ObjectListController;
  90. private:
  91. using MediaType = Storage::SharedMediaType;
  92. enum class Tab : uchar {
  93. Chats,
  94. Channels,
  95. Apps,
  96. Media,
  97. Downloads,
  98. };
  99. enum class JumpResult : uchar {
  100. NotApplied,
  101. Applied,
  102. AppliedAndOut,
  103. };
  104. struct Key {
  105. Tab tab = Tab::Chats;
  106. MediaType mediaType = {};
  107. friend inline auto operator<=>(Key, Key) = default;
  108. friend inline bool operator==(Key, Key) = default;
  109. };
  110. struct ObjectList {
  111. not_null<Ui::SlideWrap<PeerListContent>*> wrap;
  112. rpl::variable<int> count;
  113. Fn<bool()> choose;
  114. Fn<JumpResult(Qt::Key, int)> selectJump;
  115. Fn<uint64(QPoint)> updateFromParentDrag;
  116. Fn<void()> dragLeft;
  117. Fn<bool(not_null<QTouchEvent*>)> processTouch;
  118. rpl::event_stream<not_null<PeerData*>> chosen;
  119. };
  120. struct MediaList {
  121. Info::WrapWidget *wrap = nullptr;
  122. rpl::variable<int> count;
  123. };
  124. [[nodiscard]] static std::vector<Key> TabKeysFor(
  125. not_null<Window::SessionController*> controller);
  126. void paintEvent(QPaintEvent *e) override;
  127. void resizeEvent(QResizeEvent *e) override;
  128. void setupTabs();
  129. void setupChats();
  130. void setupChannels();
  131. void setupApps();
  132. void selectJumpChats(Qt::Key direction, int pageSize);
  133. void selectJumpChannels(Qt::Key direction, int pageSize);
  134. void selectJumpApps(Qt::Key direction, int pageSize);
  135. [[nodiscard]] Data::Thread *updateFromChatsDrag(QPoint globalPosition);
  136. [[nodiscard]] Data::Thread *updateFromChannelsDrag(
  137. QPoint globalPosition);
  138. [[nodiscard]] Data::Thread *updateFromAppsDrag(QPoint globalPosition);
  139. [[nodiscard]] Data::Thread *fromListId(uint64 peerListRowId);
  140. [[nodiscard]] std::unique_ptr<ObjectList> setupRecentPeers(
  141. RecentPeersList recentPeers);
  142. [[nodiscard]] auto setupEmptyRecent()
  143. -> object_ptr<Ui::SlideWrap<Ui::RpWidget>>;
  144. [[nodiscard]] std::unique_ptr<ObjectList> setupMyChannels();
  145. [[nodiscard]] std::unique_ptr<ObjectList> setupRecommendations();
  146. [[nodiscard]] auto setupEmptyChannels()
  147. -> object_ptr<Ui::SlideWrap<Ui::RpWidget>>;
  148. [[nodiscard]] std::unique_ptr<ObjectList> setupRecentApps();
  149. [[nodiscard]] std::unique_ptr<ObjectList> setupPopularApps();
  150. [[nodiscard]] std::unique_ptr<ObjectList> setupObjectList(
  151. not_null<Ui::ElasticScroll*> scroll,
  152. not_null<Ui::VerticalLayout*> parent,
  153. not_null<ObjectListController*> controller,
  154. Fn<int()> addToScroll = nullptr);
  155. [[nodiscard]] object_ptr<Ui::SlideWrap<Ui::RpWidget>> setupEmpty(
  156. not_null<QWidget*> parent,
  157. SearchEmptyIcon icon,
  158. rpl::producer<QString> text);
  159. void switchTab(Key key);
  160. void startShownAnimation(bool shown, Fn<void()> finish);
  161. void startSlideAnimation(Key was, Key now);
  162. void ensureContent(Key key);
  163. void finishShow();
  164. void handlePressForChatPreview(PeerId id, Fn<void(bool)> callback);
  165. void updateControlsGeometry();
  166. void applySearchQuery();
  167. const not_null<Window::SessionController*> _controller;
  168. const std::unique_ptr<Ui::ScrollArea> _tabsScroll;
  169. const not_null<Ui::SettingsSlider*> _tabs;
  170. Ui::Animations::Simple _tabsScrollAnimation;
  171. const std::vector<Key> _tabKeys;
  172. rpl::variable<Key> _key;
  173. const std::unique_ptr<Ui::ElasticScroll> _chatsScroll;
  174. const not_null<Ui::VerticalLayout*> _chatsContent;
  175. const not_null<Ui::SlideWrap<TopPeersStrip>*> _topPeersWrap;
  176. const not_null<TopPeersStrip*> _topPeers;
  177. rpl::event_stream<not_null<PeerData*>> _topPeerChosen;
  178. rpl::event_stream<not_null<PeerData*>> _openBotMainAppRequests;
  179. const std::unique_ptr<ObjectList> _recent;
  180. const not_null<Ui::SlideWrap<Ui::RpWidget>*> _emptyRecent;
  181. const std::unique_ptr<Ui::ElasticScroll> _channelsScroll;
  182. const not_null<Ui::VerticalLayout*> _channelsContent;
  183. const std::unique_ptr<ObjectList> _myChannels;
  184. const std::unique_ptr<ObjectList> _recommendations;
  185. const not_null<Ui::SlideWrap<Ui::RpWidget>*> _emptyChannels;
  186. const std::unique_ptr<Ui::ElasticScroll> _appsScroll;
  187. const not_null<Ui::VerticalLayout*> _appsContent;
  188. rpl::producer<> _recentAppsRefreshed;
  189. Fn<bool(not_null<PeerData*>)> _recentAppsShows;
  190. const std::unique_ptr<ObjectList> _recentApps;
  191. const std::unique_ptr<ObjectList> _popularApps;
  192. base::flat_map<Key, MediaList> _mediaLists;
  193. rpl::event_stream<> _clearSearchQueryRequests;
  194. QString _searchQuery;
  195. base::Timer _searchQueryTimer;
  196. Ui::Animations::Simple _shownAnimation;
  197. Fn<void()> _showFinished;
  198. bool _hidden = false;
  199. bool _persist = false;
  200. QPixmap _cache;
  201. Ui::Animations::Simple _slideAnimation;
  202. QPixmap _slideLeft;
  203. QPixmap _slideRight;
  204. int _slideLeftTop = 0;
  205. int _slideRightTop = 0;
  206. };
  207. [[nodiscard]] rpl::producer<TopPeersList> TopPeersContent(
  208. not_null<Main::Session*> session);
  209. [[nodiscard]] RecentPeersList RecentPeersContent(
  210. not_null<Main::Session*> session);
  211. [[nodiscard]] object_ptr<Ui::BoxContent> StarsExamplesBox(
  212. not_null<Window::SessionController*> window);
  213. [[nodiscard]] object_ptr<Ui::BoxContent> PopularAppsAboutBox(
  214. not_null<Window::SessionController*> window);
  215. } // namespace Dialogs