emoji_interactions.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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. class PeerData;
  10. class HistoryItem;
  11. class DocumentData;
  12. namespace Data {
  13. class DocumentMedia;
  14. } // namespace Data
  15. namespace Main {
  16. class Session;
  17. } // namespace Main
  18. namespace HistoryView {
  19. class Element;
  20. } // namespace HistoryView
  21. namespace ChatHelpers {
  22. struct EmojiInteractionPlayRequest {
  23. QString emoticon;
  24. not_null<HistoryItem*> item;
  25. std::shared_ptr<Data::DocumentMedia> media;
  26. crl::time shouldHaveStartedAt = 0;
  27. bool incoming = false;
  28. };
  29. struct EmojiInteractionsBunch {
  30. struct Single {
  31. int index = 0;
  32. double time = 0;
  33. };
  34. std::vector<Single> interactions;
  35. };
  36. struct EmojiInteractionSeen {
  37. not_null<PeerData*> peer;
  38. QString emoticon;
  39. };
  40. class EmojiInteractions final {
  41. public:
  42. explicit EmojiInteractions(not_null<Main::Session*> session);
  43. ~EmojiInteractions();
  44. using PlayRequest = EmojiInteractionPlayRequest;
  45. void startOutgoing(not_null<const HistoryView::Element*> view);
  46. void startIncoming(
  47. not_null<PeerData*> peer,
  48. MsgId messageId,
  49. const QString &emoticon,
  50. EmojiInteractionsBunch &&bunch);
  51. void seenOutgoing(not_null<PeerData*> peer, const QString &emoticon);
  52. [[nodiscard]] rpl::producer<EmojiInteractionSeen> seen() const {
  53. return _seen.events();
  54. }
  55. [[nodiscard]] rpl::producer<PlayRequest> playRequests() const {
  56. return _playRequests.events();
  57. }
  58. void playStarted(not_null<PeerData*> peer, QString emoji);
  59. [[nodiscard]] static EmojiInteractionsBunch Parse(const QByteArray &json);
  60. [[nodiscard]] static QByteArray ToJson(
  61. const EmojiInteractionsBunch &bunch);
  62. private:
  63. struct Animation {
  64. QString emoticon;
  65. not_null<EmojiPtr> emoji;
  66. not_null<DocumentData*> document;
  67. std::shared_ptr<Data::DocumentMedia> media;
  68. crl::time scheduledAt = 0;
  69. crl::time startedAt = 0;
  70. bool incoming = false;
  71. int index = 0;
  72. };
  73. struct PlaySent {
  74. mtpRequestId lastRequestId = 0;
  75. crl::time lastDoneReceivedAt = 0;
  76. };
  77. struct CheckResult {
  78. crl::time nextCheckAt = 0;
  79. bool waitingForDownload = false;
  80. };
  81. [[nodiscard]] static CheckResult Combine(CheckResult a, CheckResult b);
  82. void check(crl::time now = 0);
  83. [[nodiscard]] CheckResult checkAnimations(crl::time now);
  84. [[nodiscard]] CheckResult checkAnimations(
  85. crl::time now,
  86. base::flat_map<not_null<HistoryItem*>, std::vector<Animation>> &map);
  87. [[nodiscard]] CheckResult checkAccumulated(crl::time now);
  88. void sendAccumulatedOutgoing(
  89. crl::time now,
  90. not_null<HistoryItem*> item,
  91. std::vector<Animation> &animations);
  92. void clearAccumulatedIncoming(
  93. crl::time now,
  94. std::vector<Animation> &animations);
  95. void setWaitingForDownload(bool waiting);
  96. void checkSeenRequests(crl::time now);
  97. void checkSentRequests(crl::time now);
  98. void checkEdition(
  99. not_null<HistoryItem*> item,
  100. base::flat_map<not_null<HistoryItem*>, std::vector<Animation>> &map);
  101. const not_null<Main::Session*> _session;
  102. base::flat_map<not_null<HistoryItem*>, std::vector<Animation>> _outgoing;
  103. base::flat_map<not_null<HistoryItem*>, std::vector<Animation>> _incoming;
  104. base::Timer _checkTimer;
  105. rpl::event_stream<PlayRequest> _playRequests;
  106. base::flat_map<
  107. not_null<PeerData*>,
  108. base::flat_map<QString, crl::time>> _playStarted;
  109. base::flat_map<
  110. not_null<PeerData*>,
  111. base::flat_map<not_null<EmojiPtr>, PlaySent>> _playsSent;
  112. rpl::event_stream<EmojiInteractionSeen> _seen;
  113. bool _waitingForDownload = false;
  114. rpl::lifetime _downloadCheckLifetime;
  115. rpl::lifetime _lifetime;
  116. };
  117. } // namespace ChatHelpers