diff --git a/Telegram/SourceFiles/api/api_send_progress.cpp b/Telegram/SourceFiles/api/api_send_progress.cpp index 9d4531a79..e96b11da0 100644 --- a/Telegram/SourceFiles/api/api_send_progress.cpp +++ b/Telegram/SourceFiles/api/api_send_progress.cpp @@ -16,6 +16,7 @@ namespace Api { namespace { constexpr auto kCancelTypingActionTimeout = crl::time(5000); +constexpr auto kSetMyActionForMs = 10 * crl::time(1000); } // namespace @@ -27,7 +28,14 @@ SendProgressManager::SendProgressManager(not_null session) void SendProgressManager::cancel( not_null history, SendProgressType type) { - const auto i = _requests.find({ history, type }); + cancel(history, 0, type); +} + +void SendProgressManager::cancel( + not_null history, + MsgId topMsgId, + SendProgressType type) { + const auto i = _requests.find(Key{ history, topMsgId, type }); if (i != _requests.end()) { _session->api().request(i->second).cancel(); _requests.erase(i); @@ -42,29 +50,58 @@ void SendProgressManager::cancelTyping(not_null history) { void SendProgressManager::update( not_null history, SendProgressType type, - int32 progress) { + int progress) { + update(history, 0, type, progress); +} + +void SendProgressManager::update( + not_null history, + MsgId topMsgId, + SendProgressType type, + int progress) { const auto peer = history->peer; if (peer->isSelf() || (peer->isChannel() && !peer->isMegagroup())) { return; } const auto doing = (progress >= 0); - if (history->mySendActionUpdated(type, doing)) { - cancel(history, type); + const auto key = Key{ history, topMsgId, type }; + if (updated(key, doing)) { + cancel(history, topMsgId, type); if (doing) { - send(history, type, progress); + send(key, progress); } } } -void SendProgressManager::send( - not_null history, - SendProgressType type, - int32 progress) { +bool SendProgressManager::updated(const Key &key, bool doing) { + const auto now = crl::now(); + const auto i = _updated.find(key); + if (doing) { + if (i == end(_updated)) { + _updated.emplace(key, now + kSetMyActionForMs); + } else if (i->second > now + (kSetMyActionForMs / 2)) { + return false; + } else { + i->second = now + kSetMyActionForMs; + } + } else { + if (i == end(_updated)) { + return false; + } else if (i->second <= now) { + return false; + } else { + _updated.erase(i); + } + } + return true; +} + +void SendProgressManager::send(const Key &key, int progress) { using Type = SendProgressType; const auto action = [&]() -> MTPsendMessageAction { const auto p = MTP_int(progress); - switch (type) { + switch (key.type) { case Type::Typing: return MTP_sendMessageTypingAction(); case Type::RecordVideo: return MTP_sendMessageRecordVideoAction(); case Type::UploadVideo: return MTP_sendMessageUploadVideoAction(p); @@ -81,17 +118,19 @@ void SendProgressManager::send( } }(); const auto requestId = _session->api().request(MTPmessages_SetTyping( - MTP_flags(0), - history->peer->input, - MTP_int(0), // top_msg_id + MTP_flags(key.topMsgId + ? MTPmessages_SetTyping::Flag::f_top_msg_id + : MTPmessages_SetTyping::Flag(0)), + key.history->peer->input, + MTP_int(key.topMsgId), action )).done([=](const MTPBool &result, mtpRequestId requestId) { done(result, requestId); }).send(); - _requests.emplace(Key{ history, type }, requestId); + _requests.emplace(key, requestId); - if (type == Type::Typing) { - _stopTypingHistory = history; + if (key.type == Type::Typing) { + _stopTypingHistory = key.history; _stopTypingTimer.callOnce(kCancelTypingActionTimeout); } } diff --git a/Telegram/SourceFiles/api/api_send_progress.h b/Telegram/SourceFiles/api/api_send_progress.h index 14b409a43..dc5dc7802 100644 --- a/Telegram/SourceFiles/api/api_send_progress.h +++ b/Telegram/SourceFiles/api/api_send_progress.h @@ -55,7 +55,16 @@ public: void update( not_null history, SendProgressType type, - int32 progress = 0); + int progress = 0); + void update( + not_null history, + MsgId topMsgId, + SendProgressType type, + int progress = 0); + void cancel( + not_null history, + MsgId topMsgId, + SendProgressType type); void cancel( not_null history, SendProgressType type); @@ -64,22 +73,26 @@ public: private: struct Key { not_null history; + MsgId topMsgId = 0; SendProgressType type = SendProgressType(); inline bool operator<(const Key &other) const { return (history < other.history) - || (history == other.history && type < other.type); + || (history == other.history && topMsgId < other.topMsgId) + || (history == other.history + && topMsgId == other.topMsgId + && type < other.type); } }; - void send( - not_null history, - SendProgressType type, - int32 progress); + bool updated(const Key &key, bool doing); + + void send(const Key &key, int progress); void done(const MTPBool &result, mtpRequestId requestId); const not_null _session; base::flat_map _requests; + base::flat_map _updated; base::Timer _stopTypingTimer; History *_stopTypingHistory = nullptr; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 6b583a8e9..9a19378e4 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -62,7 +62,6 @@ constexpr auto kStatusShowClientsideUploadFile = 6000; constexpr auto kStatusShowClientsideChooseLocation = 6000; constexpr auto kStatusShowClientsideChooseContact = 6000; constexpr auto kStatusShowClientsidePlayGame = 10000; -constexpr auto kSetMyActionForMs = 10000; constexpr auto kNewBlockEachMessage = 50; constexpr auto kSkipCloudDraftsFor = TimeId(3); @@ -421,29 +420,6 @@ bool History::updateSendActionNeedsAnimating( return updateSendActionNeedsAnimating(now, true); } -bool History::mySendActionUpdated(Api::SendProgressType type, bool doing) { - const auto now = crl::now(); - const auto i = _mySendActions.find(type); - if (doing) { - if (i == end(_mySendActions)) { - _mySendActions.emplace(type, now + kSetMyActionForMs); - } else if (i->second > now + (kSetMyActionForMs / 2)) { - return false; - } else { - i->second = now + kSetMyActionForMs; - } - } else { - if (i == end(_mySendActions)) { - return false; - } else if (i->second <= now) { - return false; - } else { - _mySendActions.erase(i); - } - } - return true; -} - bool History::paintSendAction( Painter &p, int x, diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 3006e59a2..392178442 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -276,7 +276,6 @@ public: bool hasPendingResizedItems() const; void setHasPendingResizedItems(); - bool mySendActionUpdated(Api::SendProgressType type, bool doing); bool paintSendAction( Painter &p, int x, @@ -587,7 +586,6 @@ private: QString _sendActionString; Ui::Text::String _sendActionText; Ui::SendActionAnimation _sendActionAnimation; - base::flat_map _mySendActions; std::deque> _notifications;