history_widget.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  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 "history/view/controls/history_view_compose_media_edit_manager.h"
  9. #include "history/view/history_view_corner_buttons.h"
  10. #include "history/history_drag_area.h"
  11. #include "history/history_item_helpers.h"
  12. #include "history/history_view_highlight_manager.h"
  13. #include "history/history_view_top_toast.h"
  14. #include "history/history.h"
  15. #include "chat_helpers/field_characters_count_manager.h"
  16. #include "data/data_report.h"
  17. #include "window/section_widget.h"
  18. #include "window/window_session_controller.h"
  19. #include "ui/widgets/fields/input_field.h"
  20. #include "mtproto/sender.h"
  21. enum class SendMediaType;
  22. class MessageLinksParser;
  23. struct InlineBotQuery;
  24. namespace MTP {
  25. class Error;
  26. } // namespace MTP
  27. namespace Data {
  28. class PhotoMedia;
  29. struct SendError;
  30. } // namespace Data
  31. namespace SendMenu {
  32. struct Details;
  33. } // namespace SendMenu
  34. namespace Api {
  35. struct MessageToSend;
  36. struct SendOptions;
  37. struct SendAction;
  38. } // namespace Api
  39. namespace InlineBots {
  40. namespace Layout {
  41. class Widget;
  42. } // namespace Layout
  43. struct ResultSelected;
  44. } // namespace InlineBots
  45. namespace Support {
  46. class Autocomplete;
  47. struct Contact;
  48. } // namespace Support
  49. namespace Ui {
  50. class InnerDropdown;
  51. class DropdownMenu;
  52. class PlainShadow;
  53. class IconButton;
  54. class EmojiButton;
  55. class SendButton;
  56. class SilentToggle;
  57. class FlatButton;
  58. class RoundButton;
  59. class PinnedBar;
  60. class GroupCallBar;
  61. class RequestsBar;
  62. struct PreparedList;
  63. struct PreparedBundle;
  64. class SendFilesWay;
  65. class SendAsButton;
  66. class SpoilerAnimation;
  67. class ChooseThemeController;
  68. class ContinuousScroll;
  69. struct ChatPaintHighlight;
  70. template <typename Widget>
  71. class SlideWrap;
  72. } // namespace Ui
  73. namespace Ui::Emoji {
  74. class SuggestionsController;
  75. } // namespace Ui::Emoji
  76. namespace Webrtc {
  77. enum class RecordAvailability : uchar;
  78. } // namespace Webrtc
  79. namespace ChatHelpers {
  80. class TabbedPanel;
  81. class TabbedSelector;
  82. class FieldAutocomplete;
  83. struct FileChosen;
  84. } // namespace ChatHelpers
  85. namespace HistoryView {
  86. class StickerToast;
  87. class PaidReactionToast;
  88. class TopBarWidget;
  89. class PaysStatus;
  90. class ContactStatus;
  91. class BusinessBotStatus;
  92. class Element;
  93. class PinnedTracker;
  94. class TranslateBar;
  95. class ComposeSearch;
  96. struct SelectedQuote;
  97. } // namespace HistoryView
  98. namespace HistoryView::Controls {
  99. class RecordLock;
  100. class VoiceRecordBar;
  101. class ForwardPanel;
  102. class TTLButton;
  103. class WebpageProcessor;
  104. class CharactersLimitLabel;
  105. class PhotoEditSpoilerManager;
  106. struct VoiceToSend;
  107. } // namespace HistoryView::Controls
  108. class BotKeyboard;
  109. class HistoryInner;
  110. class HistoryWidget final
  111. : public Window::AbstractSectionWidget
  112. , private HistoryView::CornerButtonsDelegate {
  113. public:
  114. using FieldHistoryAction = Ui::InputField::HistoryAction;
  115. using RecordLock = HistoryView::Controls::RecordLock;
  116. using VoiceRecordBar = HistoryView::Controls::VoiceRecordBar;
  117. using ForwardPanel = HistoryView::Controls::ForwardPanel;
  118. HistoryWidget(
  119. QWidget *parent,
  120. not_null<Window::SessionController*> controller);
  121. void historyLoaded();
  122. [[nodiscard]] bool preventsClose(Fn<void()> &&continueCallback) const;
  123. // When resizing the widget with top edge moved up or down and we
  124. // want to add this top movement to the scroll position, so inner
  125. // content will not move.
  126. void setGeometryWithTopMoved(const QRect &newGeometry, int topDelta);
  127. void windowShown();
  128. [[nodiscard]] bool markingMessagesRead() const;
  129. [[nodiscard]] bool markingContentsRead() const;
  130. bool skipItemRepaint();
  131. void checkActivation();
  132. void leaveToChildEvent(QEvent *e, QWidget *child) override;
  133. bool isItemCompletelyHidden(HistoryItem *item) const;
  134. void updateTopBarSelection();
  135. void updateTopBarChooseForReport();
  136. void loadMessages();
  137. void loadMessagesDown();
  138. void firstLoadMessages();
  139. void delayedShowAt(MsgId showAtMsgId, const Window::SectionShow &params);
  140. bool updateReplaceMediaButton();
  141. void updateFieldPlaceholder();
  142. bool confirmSendingFiles(const QStringList &files);
  143. bool confirmSendingFiles(not_null<const QMimeData*> data);
  144. void updateControlsVisibility();
  145. void updateControlsGeometry();
  146. History *history() const;
  147. PeerData *peer() const;
  148. void setMsgId(MsgId showAtMsgId, const Window::SectionShow &params = {});
  149. MsgId msgId() const;
  150. bool hasTopBarShadow() const {
  151. return peer() != nullptr;
  152. }
  153. void showAnimated(
  154. Window::SlideDirection direction,
  155. const Window::SectionSlideParams &params);
  156. void finishAnimating();
  157. void doneShow();
  158. QPoint clampMousePosition(QPoint point);
  159. bool touchScroll(const QPoint &delta);
  160. void enqueueMessageHighlight(const HistoryView::SelectedQuote &quote);
  161. [[nodiscard]] Ui::ChatPaintHighlight itemHighlight(
  162. not_null<const HistoryItem*> item) const;
  163. MessageIdsList getSelectedItems() const;
  164. void itemEdited(not_null<HistoryItem*> item);
  165. void replyToMessage(FullReplyTo id);
  166. void replyToMessage(
  167. not_null<HistoryItem*> item,
  168. TextWithEntities quote = {},
  169. int quoteOffset = 0);
  170. void editMessage(
  171. not_null<HistoryItem*> item,
  172. const TextSelection &selection);
  173. void fillSenderUserpicMenu(
  174. not_null<Ui::PopupMenu*> menu,
  175. not_null<PeerData*> peer);
  176. [[nodiscard]] FullReplyTo replyTo() const;
  177. bool lastForceReplyReplied(const FullMsgId &replyTo) const;
  178. bool lastForceReplyReplied() const;
  179. bool cancelReply(bool lastKeyboardUsed = false);
  180. void cancelEdit();
  181. void updateForwarding();
  182. void pushReplyReturn(not_null<HistoryItem*> item);
  183. [[nodiscard]] QVector<FullMsgId> replyReturns() const;
  184. void setReplyReturns(PeerId peer, QVector<FullMsgId> replyReturns);
  185. void escape();
  186. void sendBotCommand(const Bot::SendCommandRequest &request);
  187. void hideSingleUseKeyboard(FullMsgId replyToId);
  188. bool insertBotCommand(const QString &cmd);
  189. bool eventFilter(QObject *obj, QEvent *e) override;
  190. // With force=true the markup is updated even if it is
  191. // already shown for the passed history item.
  192. void updateBotKeyboard(History *h = nullptr, bool force = false);
  193. void botCallbackSent(not_null<HistoryItem*> item);
  194. void fastShowAtEnd(not_null<History*> history);
  195. bool applyDraft(
  196. FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
  197. void showHistory(
  198. PeerId peerId,
  199. MsgId showAtMsgId,
  200. const Window::SectionShow &params = {});
  201. void setChooseReportMessagesDetails(
  202. Data::ReportInput reportInput,
  203. Fn<void(std::vector<MsgId>)> callback);
  204. void clearAllLoadRequests();
  205. void clearSupportPreloadRequest();
  206. void clearDelayedShowAtRequest();
  207. void clearDelayedShowAt();
  208. void toggleChooseChatTheme(
  209. not_null<PeerData*> peer,
  210. std::optional<bool> show = std::nullopt);
  211. [[nodiscard]] Ui::ChatTheme *customChatTheme() const;
  212. void applyCloudDraft(History *history);
  213. void activate();
  214. void setInnerFocus();
  215. [[nodiscard]] rpl::producer<> cancelRequests() const {
  216. return _cancelRequests.events();
  217. }
  218. bool searchInChatEmbedded(
  219. QString query,
  220. Dialogs::Key chat,
  221. PeerData *searchFrom = nullptr);
  222. void updateNotifyControls();
  223. bool contentOverlapped(const QRect &globalRect);
  224. QPixmap grabForShowAnimation(const Window::SectionSlideParams &params);
  225. void forwardSelected();
  226. void confirmDeleteSelected();
  227. void clearSelected();
  228. [[nodiscard]] SendMenu::Details sendMenuDetails() const;
  229. [[nodiscard]] SendMenu::Details saveMenuDetails() const;
  230. bool sendExistingDocument(
  231. not_null<DocumentData*> document,
  232. Api::MessageToSend messageToSend,
  233. std::optional<MsgId> localId = std::nullopt);
  234. bool sendExistingPhoto(
  235. not_null<PhotoData*> photo,
  236. Api::SendOptions options);
  237. void showInfoTooltip(
  238. const TextWithEntities &text,
  239. Fn<void()> hiddenCallback);
  240. void showPremiumStickerTooltip(
  241. not_null<const HistoryView::Element*> view);
  242. void showPremiumToast(not_null<DocumentData*> document);
  243. // Tabbed selector management.
  244. bool pushTabbedSelectorToThirdSection(
  245. not_null<Data::Thread*> thread,
  246. const Window::SectionShow &params) override;
  247. bool returnTabbedSelector() override;
  248. // Float player interface.
  249. bool floatPlayerHandleWheelEvent(QEvent *e) override;
  250. QRect floatPlayerAvailableRect() override;
  251. bool notify_switchInlineBotButtonReceived(const QString &query, UserData *samePeerBot, MsgId samePeerReplyTo);
  252. void tryProcessKeyInput(not_null<QKeyEvent*> e);
  253. ~HistoryWidget();
  254. protected:
  255. void resizeEvent(QResizeEvent *e) override;
  256. void keyPressEvent(QKeyEvent *e) override;
  257. void mousePressEvent(QMouseEvent *e) override;
  258. void paintEvent(QPaintEvent *e) override;
  259. void leaveEventHook(QEvent *e) override;
  260. void mouseReleaseEvent(QMouseEvent *e) override;
  261. void mouseMoveEvent(QMouseEvent *e) override;
  262. private:
  263. using TabbedPanel = ChatHelpers::TabbedPanel;
  264. using TabbedSelector = ChatHelpers::TabbedSelector;
  265. using VoiceToSend = HistoryView::Controls::VoiceToSend;
  266. enum ScrollChangeType {
  267. ScrollChangeNone,
  268. // When we toggle a pinned message.
  269. ScrollChangeAdd,
  270. // When loading a history part while scrolling down.
  271. ScrollChangeNoJumpToBottom,
  272. };
  273. struct ScrollChange {
  274. ScrollChangeType type;
  275. int value;
  276. };
  277. struct ChooseMessagesForReport {
  278. Data::ReportInput reportInput;
  279. Fn<void(std::vector<MsgId>)> callback;
  280. bool active = false;
  281. };
  282. struct ItemRevealAnimation {
  283. Ui::Animations::Simple animation;
  284. int startHeight = 0;
  285. };
  286. enum class TextUpdateEvent {
  287. SaveDraft = (1 << 0),
  288. SendTyping = (1 << 1),
  289. };
  290. using TextUpdateEvents = base::flags<TextUpdateEvent>;
  291. friend inline constexpr bool is_flag_type(TextUpdateEvent) { return true; };
  292. void cornerButtonsShowAtPosition(
  293. Data::MessagePosition position) override;
  294. Data::Thread *cornerButtonsThread() override;
  295. FullMsgId cornerButtonsCurrentId() override;
  296. bool cornerButtonsIgnoreVisibility() override;
  297. std::optional<bool> cornerButtonsDownShown() override;
  298. bool cornerButtonsUnreadMayBeShown() override;
  299. bool cornerButtonsHas(HistoryView::CornerButtonType type) override;
  300. [[nodiscard]] bool checkSendPayment(
  301. int messagesCount,
  302. int starsApproved,
  303. Fn<void(int)> withPaymentApproved);
  304. void checkSuggestToGigagroup();
  305. void processReply();
  306. void setReplyFieldsFromProcessing();
  307. void initTabbedSelector();
  308. void initVoiceRecordBar();
  309. void refreshTabbedPanel();
  310. void createTabbedPanel();
  311. void setTabbedPanel(std::unique_ptr<TabbedPanel> panel);
  312. void updateField();
  313. void fieldChanged();
  314. void fieldTabbed();
  315. void fieldFocused();
  316. void fieldResized();
  317. void initFieldAutocomplete();
  318. void cancelInlineBot();
  319. void saveDraft(bool delayed = false);
  320. void saveCloudDraft();
  321. void saveDraftDelayed();
  322. void showMembersDropdown();
  323. void windowIsVisibleChanged();
  324. void saveFieldToHistoryLocalDraft();
  325. void fileChosen(ChatHelpers::FileChosen &&data);
  326. void updateFieldSubmitSettings();
  327. bool clearMaybeSendStart();
  328. // Checks if we are too close to the top or to the bottom
  329. // in the scroll area and preloads history if needed.
  330. void preloadHistoryIfNeeded();
  331. void handleScroll();
  332. void updateHistoryItemsByTimer();
  333. [[nodiscard]] Dialogs::EntryState computeDialogsEntryState() const;
  334. void refreshTopBarActiveChat();
  335. void refreshJoinChannelText();
  336. void refreshGiftToChannelShown();
  337. void requestMessageData(MsgId msgId);
  338. void messageDataReceived(not_null<PeerData*> peer, MsgId msgId);
  339. [[nodiscard]] Api::SendAction prepareSendAction(
  340. Api::SendOptions options) const;
  341. void sendVoice(const VoiceToSend &data);
  342. void send(Api::SendOptions options);
  343. void sendWithModifiers(Qt::KeyboardModifiers modifiers);
  344. void sendScheduled(Api::SendOptions initialOptions);
  345. [[nodiscard]] SendMenu::Details sendButtonMenuDetails() const;
  346. [[nodiscard]] SendMenu::Details sendButtonDefaultDetails() const;
  347. void handlePendingHistoryUpdate();
  348. void fullInfoUpdated();
  349. void toggleTabbedSelectorMode();
  350. void recountChatWidth();
  351. void handlePeerUpdate();
  352. bool updateCanSendMessage();
  353. void setMembersShowAreaActive(bool active);
  354. void handleHistoryChange(not_null<const History*> history);
  355. void showAboutTopPromotion();
  356. void hideFieldIfVisible();
  357. void unreadCountUpdated();
  358. void closeCurrent();
  359. [[nodiscard]] int computeMaxFieldHeight() const;
  360. void toggleMuteUnmute();
  361. void reportSelectedMessages();
  362. void showKeyboardHideButton();
  363. void toggleKeyboard(bool manual = true);
  364. void startBotCommand();
  365. void hidePinnedMessage();
  366. void cancelFieldAreaState();
  367. void unblockUser();
  368. void sendBotStartCommand();
  369. void joinChannel();
  370. void supportInitAutocomplete();
  371. void supportInsertText(const QString &text);
  372. void supportShareContact(Support::Contact contact);
  373. auto computeSendButtonType() const;
  374. void showFinished();
  375. void updateOverStates(QPoint pos);
  376. void chooseAttach(std::optional<bool> overrideSendImagesAsPhotos = {});
  377. void sendButtonClicked();
  378. void newItemAdded(not_null<HistoryItem*> item);
  379. void maybeMarkReactionsRead(not_null<HistoryItem*> item);
  380. bool canSendFiles(not_null<const QMimeData*> data) const;
  381. bool confirmSendingFiles(
  382. const QStringList &files,
  383. const QString &insertTextOnCancel);
  384. bool confirmSendingFiles(
  385. QImage &&image,
  386. QByteArray &&content,
  387. std::optional<bool> overrideSendImagesAsPhotos = std::nullopt,
  388. const QString &insertTextOnCancel = QString());
  389. bool confirmSendingFiles(
  390. not_null<const QMimeData*> data,
  391. std::optional<bool> overrideSendImagesAsPhotos,
  392. const QString &insertTextOnCancel = QString());
  393. bool confirmSendingFiles(
  394. Ui::PreparedList &&list,
  395. const QString &insertTextOnCancel = QString());
  396. bool showSendingFilesError(const Ui::PreparedList &list) const;
  397. bool showSendingFilesError(
  398. const Ui::PreparedList &list,
  399. std::optional<bool> compress) const;
  400. bool showSendMessageError(
  401. const TextWithTags &textWithTags,
  402. bool ignoreSlowmodeCountdown,
  403. Fn<void(int starsApproved)> withPaymentApproved = nullptr,
  404. int starsApproved = 0);
  405. void sendingFilesConfirmed(
  406. Ui::PreparedList &&list,
  407. Ui::SendFilesWay way,
  408. TextWithTags &&caption,
  409. Api::SendOptions options,
  410. bool ctrlShiftEnter);
  411. void sendingFilesConfirmed(
  412. std::shared_ptr<Ui::PreparedBundle> bundle,
  413. Api::SendOptions options);
  414. void sendBotCommand(
  415. const Bot::SendCommandRequest &request,
  416. Api::SendOptions options);
  417. void uploadFile(const QByteArray &fileContent, SendMediaType type);
  418. void itemRemoved(not_null<const HistoryItem*> item);
  419. // Updates position of controls around the message field,
  420. // like send button, emoji button and others.
  421. void moveFieldControls();
  422. void updateFieldSize();
  423. [[nodiscard]] MsgId resolveReplyToTopicRootId();
  424. [[nodiscard]] Data::ForumTopic *resolveReplyToTopic();
  425. [[nodiscard]] bool canWriteMessage() const;
  426. void orderWidgets();
  427. [[nodiscard]] InlineBotQuery parseInlineBotQuery() const;
  428. void clearInlineBot();
  429. void inlineBotChanged();
  430. // Look in the _field for the inline bot and query string.
  431. void updateInlineBotQuery();
  432. // Request to show results in the emoji panel.
  433. void applyInlineBotQuery(UserData *bot, const QString &query);
  434. void cancelReplyAfterMediaSend(bool lastKeyboardUsed);
  435. bool replyToPreviousMessage();
  436. bool replyToNextMessage();
  437. [[nodiscard]] bool showSlowmodeError();
  438. void hideChildWidgets();
  439. void hideSelectorControlsAnimated();
  440. int countMembersDropdownHeightMax() const;
  441. void updateReplyToName();
  442. [[nodiscard]] bool editingMessage() const {
  443. return _editMsgId != 0;
  444. }
  445. void setupShortcuts();
  446. void setupGiftToChannelButton();
  447. void handlePeerMigration();
  448. void updateReplyEditTexts(bool force = false);
  449. void updateReplyEditText(not_null<HistoryItem*> item);
  450. void updatePinnedViewer();
  451. void setupTranslateBar();
  452. void setupPinnedTracker();
  453. void checkPinnedBarState();
  454. void clearHidingPinnedBar();
  455. void refreshPinnedBarButton(bool many, HistoryItem *item);
  456. void checkLastPinnedClickedIdReset(
  457. int wasScrollTop,
  458. int nowScrollTop);
  459. void checkMessagesTTL();
  460. void setupGroupCallBar();
  461. void setupRequestsBar();
  462. void checkSponsoredMessageBar();
  463. [[nodiscard]] bool checkSponsoredMessageBarVisibility() const;
  464. void requestSponsoredMessageBar();
  465. void createSponsoredMessageBar();
  466. void sendInlineResult(InlineBots::ResultSelected result);
  467. void drawField(Painter &p, const QRect &rect);
  468. void paintEditHeader(
  469. Painter &p,
  470. const QRect &rect,
  471. int left,
  472. int top) const;
  473. bool paintShowAnimationFrame();
  474. void updateMouseTracking();
  475. // destroys _history and _migrated unread bars
  476. void destroyUnreadBar();
  477. void destroyUnreadBarOnClose();
  478. void createUnreadBarIfBelowVisibleArea(int withScrollTop);
  479. [[nodiscard]] bool insideJumpToEndInsteadOfToUnread() const;
  480. void createUnreadBarAndResize();
  481. [[nodiscard]] TextWithEntities prepareTextForEditMsg() const;
  482. void saveEditMsg();
  483. void setupPreview();
  484. void editDraftOptions();
  485. void jumpToReply(FullReplyTo to);
  486. void messagesReceived(not_null<PeerData*> peer, const MTPmessages_Messages &messages, int requestId);
  487. void messagesFailed(const MTP::Error &error, int requestId);
  488. void addMessagesToFront(not_null<PeerData*> peer, const QVector<MTPMessage> &messages);
  489. void addMessagesToBack(not_null<PeerData*> peer, const QVector<MTPMessage> &messages);
  490. void updateSendRestriction();
  491. [[nodiscard]] Data::SendError computeSendRestriction() const;
  492. void updateHistoryGeometry(bool initial = false, bool loadedDown = false, const ScrollChange &change = { ScrollChangeNone, 0 });
  493. void updateListSize();
  494. void startItemRevealAnimations();
  495. void revealItemsCallback();
  496. void startMessageSendingAnimation(not_null<HistoryItem*> item);
  497. // Does any of the shown histories has this flag set.
  498. bool hasPendingResizedItems() const;
  499. // Counts scrollTop for placing the scroll right at the unread
  500. // messages bar, choosing from _history and _migrated unreadBar.
  501. std::optional<int> unreadBarTop() const;
  502. int itemTopForHighlight(not_null<HistoryView::Element*> view) const;
  503. void scrollToCurrentVoiceMessage(FullMsgId fromId, FullMsgId toId);
  504. // Scroll to current y without updating the _lastUserScrolled time.
  505. // Used to distinguish between user scrolls and syntetic scrolls.
  506. // This one is syntetic.
  507. void synteticScrollToY(int y);
  508. void writeDrafts();
  509. void writeDraftTexts();
  510. void writeDraftCursors();
  511. void setFieldText(
  512. const TextWithTags &textWithTags,
  513. TextUpdateEvents events = 0,
  514. FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
  515. void clearFieldText(
  516. TextUpdateEvents events = 0,
  517. FieldHistoryAction fieldHistoryAction = FieldHistoryAction::Clear);
  518. [[nodiscard]] int fieldHeight() const;
  519. [[nodiscard]] bool fieldOrDisabledShown() const;
  520. void unregisterDraftSources();
  521. void registerDraftSource();
  522. void setHistory(History *history);
  523. void setEditMsgId(MsgId msgId);
  524. HistoryItem *getItemFromHistoryOrMigrated(MsgId genericMsgId) const;
  525. void animatedScrollToItem(MsgId msgId);
  526. void animatedScrollToY(int scrollTo, HistoryItem *attachTo = nullptr);
  527. // when scroll position or scroll area size changed this method
  528. // updates the boundings of the visible area in HistoryInner
  529. [[nodiscard]] bool hasSavedScroll() const;
  530. void visibleAreaUpdated();
  531. int countInitialScrollTop();
  532. int countAutomaticScrollTop();
  533. void preloadHistoryByScroll();
  534. void checkReplyReturns();
  535. void scrollToAnimationCallback(FullMsgId attachToId, int relativeTo);
  536. [[nodiscard]] bool readyToForward() const;
  537. [[nodiscard]] bool hasSilentToggle() const;
  538. void checkSupportPreload(bool force = false);
  539. void handleSupportSwitch(not_null<History*> updated);
  540. [[nodiscard]] bool isRecording() const;
  541. [[nodiscard]] bool isSearching() const;
  542. [[nodiscard]] bool isBotStart() const;
  543. [[nodiscard]] bool isBlocked() const;
  544. [[nodiscard]] bool isJoinChannel() const;
  545. [[nodiscard]] bool isMuteUnmute() const;
  546. [[nodiscard]] bool isReportMessages() const;
  547. bool updateCmdStartShown();
  548. void updateSendButtonType();
  549. [[nodiscard]] bool showRecordButton() const;
  550. [[nodiscard]] bool showInlineBotCancel() const;
  551. void refreshSilentToggle();
  552. void setupFastButtonMode();
  553. [[nodiscard]] bool isChoosingTheme() const;
  554. void setupScheduledToggle();
  555. void refreshScheduledToggle();
  556. void setupSendAsToggle();
  557. void refreshSendAsToggle();
  558. void refreshAttachBotsMenu();
  559. void injectSponsoredMessages() const;
  560. bool kbWasHidden() const;
  561. void switchToSearch(QString query);
  562. void checkCharsCount();
  563. void checkCharsLimitation();
  564. MTP::Sender _api;
  565. FullReplyTo _replyTo;
  566. Ui::Text::String _replyToName;
  567. FullReplyTo _processingReplyTo;
  568. HistoryItem *_processingReplyItem = nullptr;
  569. MsgId _editMsgId = 0;
  570. std::shared_ptr<Data::PhotoMedia> _photoEditMedia;
  571. bool _canReplaceMedia = false;
  572. bool _canAddMedia = false;
  573. HistoryView::MediaEditManager _mediaEditManager;
  574. HistoryItem *_replyEditMsg = nullptr;
  575. Ui::Text::String _replyEditMsgText;
  576. std::unique_ptr<Ui::SpoilerAnimation> _replySpoiler;
  577. mutable base::Timer _updateEditTimeLeftDisplay;
  578. object_ptr<Ui::IconButton> _fieldBarCancel;
  579. std::unique_ptr<HistoryView::TranslateBar> _translateBar;
  580. int _translateBarHeight = 0;
  581. std::unique_ptr<HistoryView::PinnedTracker> _pinnedTracker;
  582. std::unique_ptr<Ui::PinnedBar> _pinnedBar;
  583. std::unique_ptr<Ui::PinnedBar> _hidingPinnedBar;
  584. int _pinnedBarHeight = 0;
  585. FullMsgId _pinnedClickedId;
  586. std::optional<FullMsgId> _minPinnedId;
  587. std::unique_ptr<Ui::GroupCallBar> _groupCallBar;
  588. int _groupCallBarHeight = 0;
  589. std::unique_ptr<Ui::RequestsBar> _requestsBar;
  590. int _requestsBarHeight = 0;
  591. base::unique_qptr<Ui::SlideWrap<Ui::RpWidget>> _sponsoredMessageBar;
  592. int _sponsoredMessageBarHeight = 0;
  593. bool _preserveScrollTop = false;
  594. bool _repaintFieldScheduled = false;
  595. bool _sentFromScheduledTip = false;
  596. mtpRequestId _saveEditMsgRequestId = 0;
  597. std::unique_ptr<HistoryView::Controls::WebpageProcessor> _preview;
  598. Fn<bool(QPainter &p, QRect to)> _previewDrawPreview;
  599. Ui::Text::String _previewTitle;
  600. Ui::Text::String _previewDescription;
  601. PeerData *_peer = nullptr;
  602. bool _canSendMessages = false;
  603. bool _canSendTexts = false;
  604. MsgId _showAtMsgId = ShowAtUnreadMsgId;
  605. base::flat_set<MsgId> _topicsRequested;
  606. Window::SectionShow _showAtMsgParams;
  607. bool _showAndMaybeSendStart = false;
  608. int _firstLoadRequest = 0; // Not real mtpRequestId.
  609. int _preloadRequest = 0; // Not real mtpRequestId.
  610. int _preloadDownRequest = 0; // Not real mtpRequestId.
  611. MsgId _delayedShowAtMsgId = -1;
  612. Window::SectionShow _delayedShowAtMsgParams;
  613. int _delayedShowAtRequest = 0; // Not real mtpRequestId.
  614. History *_supportPreloadHistory = nullptr;
  615. int _supportPreloadRequest = 0; // Not real mtpRequestId.
  616. object_ptr<HistoryView::TopBarWidget> _topBar;
  617. object_ptr<Ui::ContinuousScroll> _scroll;
  618. QPointer<HistoryInner> _list;
  619. History *_migrated = nullptr;
  620. History *_history = nullptr;
  621. rpl::lifetime _historySponsoredPreloading;
  622. // Initial updateHistoryGeometry() was called.
  623. bool _historyInited = false;
  624. // If updateListSize() was called without updateHistoryGeometry().
  625. bool _updateHistoryGeometryRequired = false;
  626. int _lastScrollTop = 0; // gifs optimization
  627. crl::time _lastScrolled = 0;
  628. base::Timer _updateHistoryItems;
  629. crl::time _lastUserScrolled = 0;
  630. bool _synteticScrollEvent = false;
  631. Ui::Animations::Simple _scrollToAnimation;
  632. HistoryView::CornerButtons _cornerButtons;
  633. std::unique_ptr<ChatHelpers::FieldAutocomplete> _autocomplete;
  634. std::unique_ptr<Ui::Emoji::SuggestionsController> _emojiSuggestions;
  635. object_ptr<Support::Autocomplete> _supportAutocomplete;
  636. UserData *_inlineBot = nullptr;
  637. QString _inlineBotUsername;
  638. bool _inlineLookingUpBot = false;
  639. mtpRequestId _inlineBotResolveRequestId = 0;
  640. bool _isInlineBot = false;
  641. Webrtc::RecordAvailability _recordAvailability = {};
  642. std::unique_ptr<HistoryView::PaysStatus> _paysStatus;
  643. std::unique_ptr<HistoryView::ContactStatus> _contactStatus;
  644. std::unique_ptr<HistoryView::BusinessBotStatus> _businessBotStatus;
  645. const std::shared_ptr<Ui::SendButton> _send;
  646. object_ptr<Ui::FlatButton> _unblock;
  647. object_ptr<Ui::FlatButton> _botStart;
  648. object_ptr<Ui::FlatButton> _joinChannel;
  649. object_ptr<Ui::FlatButton> _muteUnmute;
  650. QPointer<Ui::IconButton> _giftToChannelIn;
  651. QPointer<Ui::IconButton> _giftToChannelOut;
  652. object_ptr<Ui::FlatButton> _reportMessages;
  653. struct {
  654. object_ptr<Ui::RoundButton> button = { nullptr };
  655. QString text;
  656. bool small = false;
  657. } _botMenu;
  658. object_ptr<Ui::IconButton> _attachToggle;
  659. object_ptr<Ui::IconButton> _replaceMedia = { nullptr };
  660. object_ptr<Ui::SendAsButton> _sendAs = { nullptr };
  661. object_ptr<Ui::EmojiButton> _tabbedSelectorToggle;
  662. object_ptr<Ui::IconButton> _botKeyboardShow;
  663. object_ptr<Ui::IconButton> _botKeyboardHide;
  664. object_ptr<Ui::IconButton> _botCommandStart;
  665. object_ptr<Ui::SilentToggle> _silent = { nullptr };
  666. object_ptr<Ui::IconButton> _scheduled = { nullptr };
  667. std::unique_ptr<HistoryView::Controls::TTLButton> _ttlInfo;
  668. const std::unique_ptr<VoiceRecordBar> _voiceRecordBar;
  669. const std::unique_ptr<ForwardPanel> _forwardPanel;
  670. std::unique_ptr<HistoryView::ComposeSearch> _composeSearch;
  671. bool _cmdStartShown = false;
  672. object_ptr<Ui::InputField> _field;
  673. base::unique_qptr<Ui::RpWidget> _fieldDisabled;
  674. base::unique_qptr<Ui::RpWidget> _sendRestriction;
  675. using CharactersLimitLabel = HistoryView::Controls::CharactersLimitLabel;
  676. base::unique_qptr<CharactersLimitLabel> _charsLimitation;
  677. QString _sendRestrictionKey;
  678. Ui::Animations::Simple _inPhotoEditOver;
  679. bool _inDetails = false;
  680. bool _inPhotoEdit = false;
  681. bool _inClickable = false;
  682. bool _kbShown = false;
  683. bool _fieldIsEmpty = true;
  684. HistoryItem *_kbReplyTo = nullptr;
  685. object_ptr<Ui::ScrollArea> _kbScroll;
  686. const not_null<BotKeyboard*> _keyboard;
  687. FieldCharsCountManager _fieldCharsCountManager;
  688. std::unique_ptr<Ui::ChooseThemeController> _chooseTheme;
  689. object_ptr<Ui::InnerDropdown> _membersDropdown = { nullptr };
  690. base::Timer _membersDropdownShowTimer;
  691. object_ptr<InlineBots::Layout::Widget> _inlineResults = { nullptr };
  692. std::unique_ptr<TabbedPanel> _tabbedPanel;
  693. std::unique_ptr<Ui::DropdownMenu> _attachBotsMenu;
  694. DragArea::Areas _attachDragAreas;
  695. bool _nonEmptySelection = false;
  696. TextUpdateEvents _textUpdateEvents = (TextUpdateEvents() | TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping);
  697. QString _confirmSource;
  698. std::unique_ptr<Window::SlideAnimation> _showAnimation;
  699. HistoryView::ElementHighlighter _highlighter;
  700. crl::time _saveDraftStart = 0;
  701. bool _saveDraftText = false;
  702. base::Timer _saveDraftTimer;
  703. base::Timer _saveCloudDraftTimer;
  704. HistoryView::InfoTooltip _topToast;
  705. std::unique_ptr<HistoryView::StickerToast> _stickerToast;
  706. std::unique_ptr<ChooseMessagesForReport> _chooseForReport;
  707. std::unique_ptr<HistoryView::PaidReactionToast> _paidReactionToast;
  708. base::flat_set<not_null<HistoryItem*>> _itemRevealPending;
  709. base::flat_map<
  710. not_null<HistoryItem*>,
  711. ItemRevealAnimation> _itemRevealAnimations;
  712. int _itemsRevealHeight = 0;
  713. bool _sponsoredMessagesStateKnown = false;
  714. bool _justMarkingAsRead = false;
  715. object_ptr<Ui::PlainShadow> _topShadow;
  716. bool _inGrab = false;
  717. int _topDelta = 0;
  718. SendPaymentHelper _sendPayment;
  719. rpl::event_stream<> _cancelRequests;
  720. };