From ba4c521d7a926c37fe450a511ab7d856cb56073a Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 9 Aug 2024 15:58:47 +0200 Subject: [PATCH] Send scheduled paid reactions on quit. --- Telegram/SourceFiles/core/application.cpp | 4 + .../data/data_message_reactions.cpp | 87 +++++++++++++------ .../SourceFiles/data/data_message_reactions.h | 11 ++- 3 files changed, 74 insertions(+), 28 deletions(-) diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index d7df2a9e69..5810e8eb3e 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_forum.h" #include "data/data_photo.h" #include "data/data_document.h" +#include "data/data_message_reactions.h" #include "data/data_session.h" #include "data/data_stories.h" #include "data/data_user.h" @@ -1740,6 +1741,9 @@ bool Application::readyToQuit() { if (session->data().stories().isQuitPrevent()) { prevented = true; } + if (session->data().reactions().isQuitPrevent()) { + prevented = true; + } } } } diff --git a/Telegram/SourceFiles/data/data_message_reactions.cpp b/Telegram/SourceFiles/data/data_message_reactions.cpp index cf783d1ee2..3157fdac34 100644 --- a/Telegram/SourceFiles/data/data_message_reactions.cpp +++ b/Telegram/SourceFiles/data/data_message_reactions.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_message_reactions.h" #include "chat_helpers/stickers_lottie.h" +#include "core/application.h" #include "history/history.h" #include "history/history_item.h" #include "history/history_item_components.h" @@ -304,8 +305,9 @@ Reactions::Reactions(not_null owner) _pollItems.remove(item); _repaintItems.remove(item); _sendPaidItems.remove(item); - if (_sendingPaid == item) { - _sendingPaid = nullptr; + if (const auto i = _sendingPaid.find(item) + ; i != end(_sendingPaid)) { + _sendingPaid.erase(i); _owner->session().credits().invalidate(); crl::on_main(&_owner->session(), [=] { sendPaid(); @@ -1548,6 +1550,23 @@ rpl::producer> Reactions::myTagsValue( ) | rpl::map(list)); } +bool Reactions::isQuitPrevent() { + for (auto i = begin(_sendPaidItems); i != end(_sendPaidItems);) { + const auto item = i->first; + if (_sendingPaid.contains(item)) { + ++i; + } else { + i = _sendPaidItems.erase(i); + sendPaid(item); + } + } + if (_sendingPaid.empty()) { + return false; + } + LOG(("Reactions prevents quit, sending paid...")); + return true; +} + void Reactions::schedulePaid(not_null item) { _sendPaidItems[item] = crl::now() + kPaidAccumulatePeriod; if (!_sendPaidTimer.isActive()) { @@ -1625,7 +1644,8 @@ void Reactions::pollCollected() { } bool Reactions::sending(not_null item) const { - return _sentRequests.contains(item->fullId()) || (_sendingPaid == item); + return _sentRequests.contains(item->fullId()) + || _sendingPaid.contains(item); } bool Reactions::HasUnread(const MTPMessageReactions &data) { @@ -1658,7 +1678,7 @@ void Reactions::CheckUnknownForUnread( } void Reactions::sendPaid() { - if (_sendingPaid) { + if (!_sendingPaid.empty()) { return; } auto next = crl::time(); @@ -1684,48 +1704,65 @@ void Reactions::sendPaid() { } bool Reactions::sendPaid(not_null item) { - Expects(!_sendingPaid); - const auto count = item->startPaidReactionSending(); if (!count) { return false; } - _sendingPaid = item; - sendPaidRequest(count); + sendPaidRequest(item, count); return true; } -void Reactions::sendPaidRequest(int count) { - const auto id = _sendingPaid->fullId(); +void Reactions::sendPaidRequest(not_null item, int count) { + Expects(!_sendingPaid.contains(item)); + + const auto id = item->fullId(); const auto randomId = base::unixtime::mtproto_msg_id(); auto &api = _owner->session().api(); - api.request(MTPmessages_SendPaidReaction( - _sendingPaid->history()->peer->input, + const auto requestId = api.request(MTPmessages_SendPaidReaction( + item->history()->peer->input, MTP_int(id.msg), MTP_int(count), MTP_long(randomId) )).done([=](const MTPUpdates &result) { - sendPaidFinish(id, count, true); - _owner->session().api().applyUpdates(result); - }).fail([=](const MTP::Error &error) { - if (!_sendingPaid - || (_sendingPaid->fullId() != id) - || (error.type() != u"RANDOM_ID_EXPIRED"_q)) { - sendPaidFinish(id, count, false); - } else { - sendPaidRequest(count); + if (const auto item = _owner->message(id)) { + if (_sendingPaid.remove(item)) { + sendPaidFinish(item, count, true); + } } + _owner->session().api().applyUpdates(result); + checkQuitPreventFinished(); + }).fail([=](const MTP::Error &error) { + if (const auto item = _owner->message(id)) { + _sendingPaid.remove(item); + if (error.type() == u"RANDOM_ID_EXPIRED"_q) { + sendPaidRequest(item, count); + } else { + sendPaidFinish(item, count, false); + } + } + checkQuitPreventFinished(); }).send(); + _sendingPaid[item] = requestId; } -void Reactions::sendPaidFinish(FullMsgId id, int count, bool success) { - if (_sendingPaid && _sendingPaid->fullId() == id) { - base::take(_sendingPaid)->finishPaidReactionSending(count, success); - sendPaid(); +void Reactions::checkQuitPreventFinished() { + if (_sendingPaid.empty()) { + if (Core::Quitting()) { + LOG(("Reactions doesn't prevent quit any more.")); + } + Core::App().quitPreventFinished(); } } +void Reactions::sendPaidFinish( + not_null item, + int count, + bool success) { + item->finishPaidReactionSending(count, success); + sendPaid(); +} + MessageReactions::MessageReactions(not_null item) : _item(item) { } diff --git a/Telegram/SourceFiles/data/data_message_reactions.h b/Telegram/SourceFiles/data/data_message_reactions.h index bc61c7c4c7..aa31757927 100644 --- a/Telegram/SourceFiles/data/data_message_reactions.h +++ b/Telegram/SourceFiles/data/data_message_reactions.h @@ -144,6 +144,7 @@ public: [[nodiscard]] rpl::producer> myTagsValue( SavedSublist *sublist = nullptr); + [[nodiscard]] bool isQuitPrevent(); void schedulePaid(not_null item); void undoScheduledPaid(not_null item); [[nodiscard]] crl::time sendingScheduledPaidAt( @@ -249,8 +250,12 @@ private: void sendPaid(); bool sendPaid(not_null item); - void sendPaidRequest(int count); - void sendPaidFinish(FullMsgId id, int count, bool success); + void sendPaidRequest(not_null item, int count); + void sendPaidFinish( + not_null item, + int count, + bool success); + void checkQuitPreventFinished(); const not_null _owner; @@ -333,7 +338,7 @@ private: mtpRequestId _pollRequestId = 0; base::flat_map, crl::time> _sendPaidItems; - HistoryItem *_sendingPaid = nullptr; + base::flat_map, mtpRequestId> _sendingPaid; base::Timer _sendPaidTimer; mtpRequestId _saveFaveRequestId = 0;