dialogs_widget.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  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/timer.h"
  9. #include "dialogs/dialogs_key.h"
  10. #include "window/section_widget.h"
  11. #include "ui/controls/swipe_handler_data.h"
  12. #include "ui/effects/animations.h"
  13. #include "ui/userpic_view.h"
  14. #include "mtproto/sender.h"
  15. #include "api/api_single_message_search.h"
  16. namespace MTP {
  17. class Error;
  18. } // namespace MTP
  19. namespace Data {
  20. class Forum;
  21. enum class StorySourcesList : uchar;
  22. struct ReactionId;
  23. } // namespace Data
  24. namespace Main {
  25. class Session;
  26. } // namespace Main
  27. namespace HistoryView {
  28. class TopBarWidget;
  29. class ContactStatus;
  30. } // namespace HistoryView
  31. namespace Ui {
  32. class AbstractButton;
  33. class IconButton;
  34. class PopupMenu;
  35. class DropdownMenu;
  36. class FlatButton;
  37. class InputField;
  38. class CrossButton;
  39. class PlainShadow;
  40. class DownloadBar;
  41. class GroupCallBar;
  42. class RequestsBar;
  43. class MoreChatsBar;
  44. class JumpDownButton;
  45. class ElasticScroll;
  46. template <typename Widget>
  47. class FadeWrapScaled;
  48. } // namespace Ui
  49. namespace Window {
  50. class SessionController;
  51. class ConnectionState;
  52. struct SectionShow;
  53. struct SeparateId;
  54. } // namespace Window
  55. namespace Dialogs::Stories {
  56. class List;
  57. struct Content;
  58. } // namespace Dialogs::Stories
  59. namespace Dialogs {
  60. extern const char kOptionForumHideChatsList[];
  61. struct RowDescriptor;
  62. class Row;
  63. class FakeRow;
  64. class Key;
  65. struct ChosenRow;
  66. class InnerWidget;
  67. struct SearchRequestType;
  68. enum class SearchRequestDelay : uchar;
  69. class Suggestions;
  70. class ChatSearchIn;
  71. enum class ChatSearchTab : uchar;
  72. enum class HashOrCashtag : uchar;
  73. class Widget final : public Window::AbstractSectionWidget {
  74. public:
  75. enum class Layout {
  76. Main,
  77. Child,
  78. };
  79. Widget(
  80. QWidget *parent,
  81. not_null<Window::SessionController*> controller,
  82. Layout layout);
  83. // When resizing the widget with top edge moved up or down and we
  84. // want to add this top movement to the scroll position, so inner
  85. // content will not move.
  86. void setGeometryWithTopMoved(const QRect &newGeometry, int topDelta);
  87. void updateDragInScroll(bool inScroll);
  88. void showForum(
  89. not_null<Data::Forum*> forum,
  90. const Window::SectionShow &params);
  91. void setInnerFocus(bool unfocusSearch = false);
  92. [[nodiscard]] bool searchHasFocus() const;
  93. void jumpToTop(bool belowPinned = false);
  94. void raiseWithTooltip();
  95. [[nodiscard]] QPixmap grabNonNarrowScrollFrame();
  96. void startWidthAnimation();
  97. void stopWidthAnimation();
  98. bool hasTopBarShadow() const {
  99. return true;
  100. }
  101. void showAnimated(
  102. Window::SlideDirection direction,
  103. const Window::SectionSlideParams &params);
  104. void showFast();
  105. [[nodiscard]] rpl::producer<float64> shownProgressValue() const;
  106. void scrollToEntry(const RowDescriptor &entry);
  107. void searchMessages(SearchState state);
  108. [[nodiscard]] RowDescriptor resolveChatNext(RowDescriptor from = {}) const;
  109. [[nodiscard]] RowDescriptor resolveChatPrevious(RowDescriptor from = {}) const;
  110. void updateHasFocus(not_null<QWidget*> focused);
  111. void toggleFiltersMenu(bool value);
  112. // Float player interface.
  113. bool floatPlayerHandleWheelEvent(QEvent *e) override;
  114. QRect floatPlayerAvailableRect() override;
  115. bool cancelSearchByMouseBack();
  116. QVariant inputMethodQuery(Qt::InputMethodQuery query) const override;
  117. ~Widget();
  118. protected:
  119. void dragEnterEvent(QDragEnterEvent *e) override;
  120. void dragMoveEvent(QDragMoveEvent *e) override;
  121. void dragLeaveEvent(QDragLeaveEvent *e) override;
  122. void dropEvent(QDropEvent *e) override;
  123. void resizeEvent(QResizeEvent *e) override;
  124. void keyPressEvent(QKeyEvent *e) override;
  125. void inputMethodEvent(QInputMethodEvent *e) override;
  126. void paintEvent(QPaintEvent *e) override;
  127. private:
  128. struct SearchProcessState {
  129. base::flat_map<QString, MTPmessages_Messages> cache;
  130. base::flat_map<mtpRequestId, QString> queries;
  131. PeerData *lastPeer = nullptr;
  132. MsgId lastId = 0;
  133. int32 nextRate = 0;
  134. mtpRequestId requestId = 0;
  135. bool full = false;
  136. };
  137. void chosenRow(const ChosenRow &row);
  138. void listScrollUpdated();
  139. void searchCursorMoved();
  140. void completeHashtag(QString tag);
  141. void requestPublicPosts(bool fromStart);
  142. void requestMessages(bool fromStart);
  143. [[nodiscard]] not_null<SearchProcessState*> currentSearchProcess();
  144. [[nodiscard]] bool computeSearchWithPostsPreview() const;
  145. [[nodiscard]] QString currentSearchQuery() const;
  146. [[nodiscard]] int currentSearchQueryCursorPosition() const;
  147. void clearSearchField();
  148. void searchRequested(SearchRequestDelay delay);
  149. bool search(bool inCache = false, SearchRequestDelay after = {});
  150. void searchTopics();
  151. void searchMore();
  152. void slideFinished();
  153. void searchReceived(
  154. SearchRequestType type,
  155. const MTPmessages_Messages &result,
  156. not_null<SearchProcessState*> process,
  157. bool cacheResults = false);
  158. void peerSearchReceived(
  159. const MTPcontacts_Found &result,
  160. mtpRequestId requestId);
  161. void escape();
  162. void submit();
  163. void cancelSearchRequest();
  164. [[nodiscard]] PeerData *searchInPeer() const;
  165. [[nodiscard]] Data::ForumTopic *searchInTopic() const;
  166. [[nodiscard]] PeerData *searchFromPeer() const;
  167. [[nodiscard]] const std::vector<Data::ReactionId> &searchInTags() const;
  168. void setupSupportMode();
  169. void setupTouchChatPreview();
  170. void setupConnectingWidget();
  171. void setupMainMenuToggle();
  172. void setupMoreChatsBar();
  173. void setupDownloadBar();
  174. void setupShortcuts();
  175. void setupStories();
  176. void setupSwipeBack();
  177. void storiesExplicitCollapse();
  178. void collectStoriesUserpicsViews(Data::StorySourcesList list);
  179. void storiesToggleExplicitExpand(bool expand);
  180. void trackScroll(not_null<Ui::RpWidget*> widget);
  181. [[nodiscard]] bool searchForPeersRequired(const QString &query) const;
  182. [[nodiscard]] bool searchForTopicsRequired(const QString &query) const;
  183. // Child list may be unable to set specific search state.
  184. bool applySearchState(SearchState state);
  185. void showCalendar();
  186. void showSearchFrom();
  187. void showMainMenu();
  188. void clearSearchCache(bool clearPosts);
  189. void setSearchQuery(const QString &query, int cursorPosition = -1);
  190. void updateControlsVisibility(bool fast = false);
  191. void updateLockUnlockVisibility(
  192. anim::type animated = anim::type::instant);
  193. void updateLoadMoreChatsVisibility();
  194. void updateStoriesVisibility();
  195. void updateJumpToDateVisibility(bool fast = false);
  196. void updateSearchFromVisibility(bool fast = false);
  197. void updateControlsGeometry();
  198. void refreshTopBars();
  199. void showSearchInTopBar(anim::type animated);
  200. void checkUpdateStatus();
  201. void openBotMainApp(not_null<UserData*> bot);
  202. void changeOpenedSubsection(
  203. FnMut<void()> change,
  204. bool fromRight,
  205. anim::type animated);
  206. void changeOpenedFolder(Data::Folder *folder, anim::type animated);
  207. void changeOpenedForum(Data::Forum *forum, anim::type animated);
  208. void hideChildList();
  209. void destroyChildListCanvas();
  210. [[nodiscard]] QPixmap grabForFolderSlideAnimation();
  211. void startSlideAnimation(
  212. QPixmap oldContentCache,
  213. QPixmap newContentCache,
  214. Window::SlideDirection direction);
  215. void openChildList(
  216. not_null<Data::Forum*> forum,
  217. const Window::SectionShow &params);
  218. void closeChildList(anim::type animated);
  219. void fullSearchRefreshOn(rpl::producer<> events);
  220. void updateCancelSearch();
  221. [[nodiscard]] QString validateSearchQuery();
  222. void applySearchUpdate();
  223. void refreshLoadMoreButton(bool mayBlock, bool isBlocked);
  224. void loadMoreBlockedByDate();
  225. void searchFailed(
  226. SearchRequestType type,
  227. const MTP::Error &error,
  228. not_null<SearchProcessState*> process);
  229. void peerSearchFailed(const MTP::Error &error, mtpRequestId requestId);
  230. void searchApplyEmpty(
  231. SearchRequestType type,
  232. not_null<SearchProcessState*> process);
  233. void peerSearchApplyEmpty(mtpRequestId id);
  234. void updateForceDisplayWide();
  235. void scrollToDefault(bool verytop = false);
  236. void scrollToDefaultChecked(bool verytop = false);
  237. void setupScrollUpButton();
  238. void updateScrollUpVisibility();
  239. void startScrollUpButtonAnimation(bool shown);
  240. void updateScrollUpPosition();
  241. void updateLockUnlockPosition();
  242. void updateSuggestions(anim::type animated);
  243. void processSearchFocusChange();
  244. [[nodiscard]] bool redirectToSearchPossible() const;
  245. [[nodiscard]] bool redirectKeyToSearch(QKeyEvent *e) const;
  246. [[nodiscard]] bool redirectImeToSearch() const;
  247. struct CancelSearchOptions {
  248. bool forceFullCancel = false;
  249. bool jumpBackToSearchedChat = false;
  250. };
  251. bool cancelSearch(CancelSearchOptions options);
  252. MTP::Sender _api;
  253. bool _dragInScroll = false;
  254. bool _dragForward = false;
  255. base::Timer _chooseByDragTimer;
  256. const Layout _layout = Layout::Main;
  257. int _narrowWidth = 0;
  258. object_ptr<Ui::RpWidget> _searchControls;
  259. object_ptr<HistoryView::TopBarWidget> _subsectionTopBar = { nullptr };
  260. struct {
  261. object_ptr<Ui::IconButton> toggle;
  262. object_ptr<Ui::AbstractButton> under;
  263. } _mainMenu;
  264. object_ptr<Ui::IconButton> _searchForNarrowLayout;
  265. object_ptr<Ui::InputField> _search;
  266. object_ptr<Ui::FadeWrapScaled<Ui::IconButton>> _chooseFromUser;
  267. object_ptr<Ui::FadeWrapScaled<Ui::IconButton>> _jumpToDate;
  268. object_ptr<Ui::CrossButton> _cancelSearch;
  269. object_ptr< Ui::FadeWrapScaled<Ui::IconButton>> _lockUnlock;
  270. std::unique_ptr<Ui::MoreChatsBar> _moreChatsBar;
  271. std::unique_ptr<Ui::PlainShadow> _forumTopShadow;
  272. std::unique_ptr<Ui::GroupCallBar> _forumGroupCallBar;
  273. std::unique_ptr<Ui::RequestsBar> _forumRequestsBar;
  274. std::unique_ptr<HistoryView::ContactStatus> _forumReportBar;
  275. base::unique_qptr<Ui::RpWidget> _chatFilters;
  276. object_ptr<Ui::ElasticScroll> _scroll;
  277. QPointer<InnerWidget> _inner;
  278. std::unique_ptr<Suggestions> _suggestions;
  279. std::vector<std::unique_ptr<Suggestions>> _hidingSuggestions;
  280. class BottomButton;
  281. object_ptr<BottomButton> _updateTelegram = { nullptr };
  282. object_ptr<BottomButton> _loadMoreChats = { nullptr };
  283. std::unique_ptr<Ui::DownloadBar> _downloadBar;
  284. std::unique_ptr<Window::ConnectionState> _connecting;
  285. Ui::Animations::Simple _scrollToAnimation;
  286. int _scrollAnimationTo = 0;
  287. std::unique_ptr<Window::SlideAnimation> _showAnimation;
  288. rpl::variable<float64> _shownProgressValue;
  289. Ui::Animations::Simple _scrollToTopShown;
  290. object_ptr<Ui::JumpDownButton> _scrollToTop;
  291. bool _scrollToTopIsShown = false;
  292. bool _forumSearchRequested = false;
  293. HashOrCashtag _searchHashOrCashtag = {};
  294. bool _searchWithPostsPreview = false;
  295. Data::Folder *_openedFolder = nullptr;
  296. Data::Forum *_openedForum = nullptr;
  297. SearchState _searchState;
  298. History *_searchInMigrated = nullptr;
  299. rpl::lifetime _searchTagsLifetime;
  300. QString _lastSearchText;
  301. bool _searchSuggestionsLocked = false;
  302. bool _searchHasFocus = false;
  303. bool _processingSearch = false;
  304. rpl::event_stream<rpl::producer<Stories::Content>> _storiesContents;
  305. base::flat_map<PeerId, Ui::PeerUserpicView> _storiesUserpicsViewsHidden;
  306. base::flat_map<PeerId, Ui::PeerUserpicView> _storiesUserpicsViewsShown;
  307. Fn<void()> _updateScrollGeometryCached;
  308. std::unique_ptr<Stories::List> _stories;
  309. Ui::Animations::Simple _storiesExplicitExpandAnimation;
  310. rpl::variable<int> _storiesExplicitExpandValue = 0;
  311. int _storiesExplicitExpandScrollTop = 0;
  312. int _aboveScrollAdded = 0;
  313. bool _storiesExplicitExpand = false;
  314. bool _postponeProcessSearchFocusChange = false;
  315. base::Timer _searchTimer;
  316. QString _peerSearchQuery;
  317. bool _peerSearchFull = false;
  318. mtpRequestId _peerSearchRequest = 0;
  319. QString _topicSearchQuery;
  320. TimeId _topicSearchOffsetDate = 0;
  321. MsgId _topicSearchOffsetId = 0;
  322. MsgId _topicSearchOffsetTopicId = 0;
  323. bool _topicSearchFull = false;
  324. mtpRequestId _topicSearchRequest = 0;
  325. QString _searchQuery;
  326. PeerData *_searchQueryFrom = nullptr;
  327. std::vector<Data::ReactionId> _searchQueryTags;
  328. ChatSearchTab _searchQueryTab = {};
  329. ChatTypeFilter _searchQueryFilter = {};
  330. Ui::Controls::SwipeBackResult _swipeBackData;
  331. bool _swipeBackMirrored = false;
  332. bool _swipeBackIconMirrored = false;
  333. SearchProcessState _searchProcess;
  334. SearchProcessState _migratedProcess;
  335. SearchProcessState _postsProcess;
  336. int _historiesRequest = 0; // Not real mtpRequestId.
  337. Api::SingleMessageSearch _singleMessageSearch;
  338. base::flat_map<QString, MTPcontacts_Found> _peerSearchCache;
  339. base::flat_map<mtpRequestId, QString> _peerSearchQueries;
  340. QPixmap _widthAnimationCache;
  341. int _topDelta = 0;
  342. std::unique_ptr<Widget> _childList;
  343. std::unique_ptr<Ui::RpWidget> _childListShadow;
  344. rpl::variable<float64> _childListShown;
  345. rpl::variable<PeerId> _childListPeerId;
  346. std::unique_ptr<Ui::RpWidget> _hideChildListCanvas;
  347. };
  348. } // namespace Dialogs