1 /* 2 This file is part of Telegram Desktop, 3 the official desktop application for the Telegram messaging service. 4 5 For license and copyright information please follow this link: 6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7 */ 8 #pragma once 9 10 #include "dialogs/dialogs_key.h" 11 #include "window/section_widget.h" 12 #include "ui/effects/animations.h" 13 #include "ui/widgets/scroll_area.h" 14 #include "ui/special_buttons.h" 15 #include "mtproto/sender.h" 16 #include "api/api_single_message_search.h" 17 18 #include <QtCore/QTimer> 19 20 namespace MTP { 21 class Error; 22 } // namespace MTP 23 24 namespace Main { 25 class Session; 26 } // namespace Main 27 28 namespace HistoryView { 29 class TopBarWidget; 30 } // namespace HistoryView 31 32 namespace Ui { 33 class IconButton; 34 class PopupMenu; 35 class DropdownMenu; 36 class FlatButton; 37 class FlatInput; 38 class CrossButton; 39 template <typename Widget> 40 class FadeWrapScaled; 41 } // namespace Ui 42 43 namespace Window { 44 class SessionController; 45 class ConnectionState; 46 } // namespace Window 47 48 namespace Dialogs { 49 50 struct RowDescriptor; 51 class Row; 52 class FakeRow; 53 class Key; 54 struct ChosenRow; 55 class InnerWidget; 56 enum class SearchRequestType; 57 58 class Widget final : public Window::AbstractSectionWidget { 59 Q_OBJECT 60 61 public: 62 Widget(QWidget *parent, not_null<Window::SessionController*> controller); 63 64 // When resizing the widget with top edge moved up or down and we 65 // want to add this top movement to the scroll position, so inner 66 // content will not move. 67 void setGeometryWithTopMoved(const QRect &newGeometry, int topDelta); 68 69 void updateDragInScroll(bool inScroll); 70 71 void searchInChat(Key chat); 72 void setInnerFocus(); 73 74 void jumpToTop(); 75 76 void startWidthAnimation(); 77 void stopWidthAnimation(); 78 hasTopBarShadow()79 bool hasTopBarShadow() const { 80 return true; 81 } 82 void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms); 83 void showFast(); 84 85 void scrollToEntry(const RowDescriptor &entry); 86 87 void searchMessages(const QString &query, Key inChat = {}); 88 void onSearchMore(); 89 90 void updateForwardBar(); 91 92 [[nodiscard]] rpl::producer<> closeForwardBarRequests() const; 93 94 // Float player interface. 95 bool floatPlayerHandleWheelEvent(QEvent *e) override; 96 QRect floatPlayerAvailableRect() override; 97 98 ~Widget(); 99 100 Q_SIGNALS: 101 void cancelled(); 102 103 public Q_SLOTS: 104 void onDraggingScrollDelta(int delta); 105 106 void onListScroll(); 107 bool onCancelSearch(); 108 void onCancelSearchInChat(); 109 110 void onFilterCursorMoved(int from = -1, int to = -1); 111 void onCompleteHashtag(QString tag); 112 113 void onDialogMoved(int movedFrom, int movedTo); 114 bool onSearchMessages(bool searchCache = false); 115 void onNeedSearchMessages(); 116 117 void onChooseByDrag(); 118 119 private Q_SLOTS: 120 void onDraggingScrollTimer(); 121 122 protected: 123 void dragEnterEvent(QDragEnterEvent *e) override; 124 void dragMoveEvent(QDragMoveEvent *e) override; 125 void dragLeaveEvent(QDragLeaveEvent *e) override; 126 void dropEvent(QDropEvent *e) override; 127 void resizeEvent(QResizeEvent *e) override; 128 void keyPressEvent(QKeyEvent *e) override; 129 void paintEvent(QPaintEvent *e) override; 130 131 private: 132 enum class ShowAnimation { 133 External, 134 Internal, 135 }; 136 137 void animationCallback(); 138 void searchReceived( 139 SearchRequestType type, 140 const MTPmessages_Messages &result, 141 mtpRequestId requestId); 142 void peerSearchReceived( 143 const MTPcontacts_Found &result, 144 mtpRequestId requestId); 145 void escape(); 146 void cancelSearchRequest(); 147 148 void setupSupportMode(); 149 void setupConnectingWidget(); 150 void setupMainMenuToggle(); 151 bool searchForPeersRequired(const QString &query) const; 152 void setSearchInChat(Key chat, PeerData *from = nullptr); 153 void showJumpToDate(); 154 void showSearchFrom(); 155 void showMainMenu(); 156 void clearSearchCache(); 157 void updateControlsVisibility(bool fast = false); 158 void updateLockUnlockVisibility(); 159 void updateLoadMoreChatsVisibility(); 160 void updateJumpToDateVisibility(bool fast = false); 161 void updateSearchFromVisibility(bool fast = false); 162 void updateControlsGeometry(); 163 void refreshFolderTopBar(); 164 void checkUpdateStatus(); 165 void changeOpenedFolder(Data::Folder *folder, anim::type animated); 166 QPixmap grabForFolderSlideAnimation(); 167 void startSlideAnimation(); 168 169 void fullSearchRefreshOn(rpl::producer<> events); 170 void applyFilterUpdate(bool force = false); 171 void refreshLoadMoreButton(bool mayBlock, bool isBlocked); 172 void loadMoreBlockedByDate(); 173 174 void searchFailed( 175 SearchRequestType type, 176 const MTP::Error &error, 177 mtpRequestId requestId); 178 void peopleFailed(const MTP::Error &error, mtpRequestId requestId); 179 180 void scrollToTop(); 181 void setupScrollUpButton(); 182 void updateScrollUpVisibility(); 183 void startScrollUpButtonAnimation(bool shown); 184 void updateScrollUpPosition(); 185 186 MTP::Sender _api; 187 188 bool _dragInScroll = false; 189 bool _dragForward = false; 190 QTimer _chooseByDragTimer; 191 192 object_ptr<Ui::IconButton> _forwardCancel = { nullptr }; 193 object_ptr<Ui::RpWidget> _searchControls; 194 object_ptr<HistoryView::TopBarWidget> _folderTopBar = { nullptr } ; 195 object_ptr<Ui::IconButton> _mainMenuToggle; 196 object_ptr<Ui::IconButton> _searchForNarrowFilters; 197 object_ptr<Ui::FlatInput> _filter; 198 object_ptr<Ui::FadeWrapScaled<Ui::IconButton>> _chooseFromUser; 199 object_ptr<Ui::FadeWrapScaled<Ui::IconButton>> _jumpToDate; 200 object_ptr<Ui::CrossButton> _cancelSearch; 201 object_ptr<Ui::IconButton> _lockUnlock; 202 object_ptr<Ui::ScrollArea> _scroll; 203 QPointer<InnerWidget> _inner; 204 class BottomButton; 205 object_ptr<BottomButton> _updateTelegram = { nullptr }; 206 object_ptr<BottomButton> _loadMoreChats = { nullptr }; 207 std::unique_ptr<Window::ConnectionState> _connecting; 208 209 Ui::Animations::Simple _scrollToAnimation; 210 Ui::Animations::Simple _a_show; 211 Window::SlideDirection _showDirection = Window::SlideDirection(); 212 QPixmap _cacheUnder, _cacheOver; 213 ShowAnimation _showAnimationType = ShowAnimation::External; 214 215 Ui::Animations::Simple _scrollToTopShown; 216 bool _scrollToTopIsShown = false; 217 object_ptr<Ui::HistoryDownButton> _scrollToTop; 218 219 Data::Folder *_openedFolder = nullptr; 220 Dialogs::Key _searchInChat; 221 History *_searchInMigrated = nullptr; 222 PeerData *_searchFromAuthor = nullptr; 223 QString _lastFilterText; 224 225 QTimer _searchTimer; 226 227 QString _peerSearchQuery; 228 bool _peerSearchFull = false; 229 mtpRequestId _peerSearchRequest = 0; 230 231 QString _searchQuery; 232 PeerData *_searchQueryFrom = nullptr; 233 int32 _searchNextRate = 0; 234 bool _searchFull = false; 235 bool _searchFullMigrated = false; 236 int _searchInHistoryRequest = 0; // Not real mtpRequestId. 237 mtpRequestId _searchRequest = 0; 238 239 base::flat_map<QString, MTPmessages_Messages> _searchCache; 240 Api::SingleMessageSearch _singleMessageSearch; 241 base::flat_map<mtpRequestId, QString> _searchQueries; 242 base::flat_map<QString, MTPcontacts_Found> _peerSearchCache; 243 base::flat_map<mtpRequestId, QString> _peerSearchQueries; 244 245 QPixmap _widthAnimationCache; 246 247 object_ptr<QTimer> _draggingScrollTimer = { nullptr }; 248 int _draggingScrollDelta = 0; 249 250 int _topDelta = 0; 251 252 rpl::event_stream<> _closeForwardBarRequests; 253 254 }; 255 256 } // namespace Dialogs 257