diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index bc6788818..082826664 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_user.h" // UserData::name #include "data/data_session.h" #include "data/data_file_origin.h" +#include "data/data_histories.h" #include "history/history.h" #include "history/history_message.h" // NewMessageFlags. #include "chat_helpers/message_field.h" // ConvertTextTagsToEntities. @@ -110,23 +111,30 @@ void SendExistingMedia( auto failHandler = std::make_shared>(); auto performRequest = [=] { - const auto usedFileReference = media->fileReference(); - history->sendRequestId = api->request(MTPmessages_SendMedia( - MTP_flags(sendFlags), - peer->input, - MTP_int(replyTo), - inputMedia(), - MTP_string(captionText), - MTP_long(randomId), - MTPReplyMarkup(), - sentEntities, - MTP_int(message.action.options.scheduled) - )).done([=](const MTPUpdates &result) { - api->applyUpdates(result, randomId); - }).fail([=](const RPCError &error) { - (*failHandler)(error, usedFileReference); - }).afterRequest(history->sendRequestId - ).send(); + auto &histories = history->owner().histories(); + const auto requestType = Data::Histories::RequestType::Send; + histories.sendRequest(history, requestType, [=](Fn finish) { + const auto usedFileReference = media->fileReference(); + history->sendRequestId = api->request(MTPmessages_SendMedia( + MTP_flags(sendFlags), + peer->input, + MTP_int(replyTo), + inputMedia(), + MTP_string(captionText), + MTP_long(randomId), + MTPReplyMarkup(), + sentEntities, + MTP_int(message.action.options.scheduled) + )).done([=](const MTPUpdates &result) { + api->applyUpdates(result, randomId); + finish(); + }).fail([=](const RPCError &error) { + (*failHandler)(error, usedFileReference); + finish(); + }).afterRequest(history->sendRequestId + ).send(); + return history->sendRequestId; + }); }; *failHandler = [=](const RPCError &error, QByteArray usedFileReference) { if (error.code() == 400 diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index ff5c309a3..c462dfeb4 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -2319,8 +2319,8 @@ void ApiWrap::deleteHistory( bool justClear, bool revoke) { auto deleteTillId = MsgId(0); - const auto history = _session->data().historyLoaded(peer); - if (history && justClear) { + const auto history = _session->data().history(peer); + if (justClear) { // In case of clear history we need to know the last server message. while (history->lastMessageKnown()) { const auto last = history->lastMessage(); @@ -2350,30 +2350,22 @@ void ApiWrap::deleteHistory( leaveChannel(channel); } else { if (const auto migrated = peer->migrateFrom()) { - clearHistory(migrated, revoke); + deleteHistory(migrated, justClear, revoke); } if (IsServerMsgId(deleteTillId)) { - request(MTPchannels_DeleteHistory( - channel->inputChannel, - MTP_int(deleteTillId) - )).send(); + history->owner().histories().deleteAllMessages( + history, + deleteTillId, + justClear, + revoke); } } } else { - using Flag = MTPmessages_DeleteHistory::Flag; - const auto flags = Flag(0) - | (justClear ? Flag::f_just_clear : Flag(0)) - | ((peer->isUser() && revoke) ? Flag::f_revoke : Flag(0)); - request(MTPmessages_DeleteHistory( - MTP_flags(flags), - peer->input, - MTP_int(0) - )).done([=](const MTPmessages_AffectedHistory &result) { - const auto offset = applyAffectedHistory(peer, result); - if (offset > 0) { - deleteHistory(peer, justClear, revoke); - } - }).send(); + history->owner().histories().deleteAllMessages( + history, + deleteTillId, + justClear, + revoke); } if (!justClear) { _session->data().deleteConversationLocally(peer); @@ -2411,30 +2403,6 @@ void ApiWrap::applyAffectedMessages( App::main()->ptsUpdateAndApply(data.vpts().v, data.vpts_count().v); } -void ApiWrap::deleteMessages( - not_null peer, - const QVector &ids, - bool revoke) { - const auto done = [=](const MTPmessages_AffectedMessages & result) { - applyAffectedMessages(peer, result); - if (const auto history = peer->owner().historyLoaded(peer)) { - history->requestChatListMessage(); - } - }; - if (const auto channel = peer->asChannel()) { - request(MTPchannels_DeleteMessages( - channel->inputChannel, - MTP_vector(ids) - )).done(done).send(); - } else { - using Flag = MTPmessages_DeleteMessages::Flag; - request(MTPmessages_DeleteMessages( - MTP_flags(revoke ? Flag::f_revoke : Flag(0)), - MTP_vector(ids) - )).done(done).send(); - } -} - void ApiWrap::saveDraftsToCloud() { for (auto i = _draftsSaveRequestIds.begin(), e = _draftsSaveRequestIds.end(); i != e; ++i) { if (i->second) continue; // sent already @@ -4326,6 +4294,8 @@ void ApiWrap::forwardMessages( FnMut &&successCallback) { Expects(!items.empty()); + auto &histories = session().data().histories(); + struct SharedCallback { int requestsLeft = 0; FnMut callback; @@ -4342,7 +4312,7 @@ void ApiWrap::forwardMessages( const auto history = action.history; const auto peer = history->peer; - session().data().histories().readInbox(history); + histories.readInbox(history); const auto channelPost = peer->isChannel() && !peer->isMegagroup(); const auto silentPost = action.options.silent @@ -4374,7 +4344,7 @@ void ApiWrap::forwardMessages( auto currentGroupId = items.front()->groupId(); auto ids = QVector(); auto randomIds = QVector(); - auto localIds = std::unique_ptr>(); + auto localIds = std::shared_ptr>(); const auto sendAccumulated = [&] { if (shared) { @@ -4384,30 +4354,36 @@ void ApiWrap::forwardMessages( | (currentGroupId == MessageGroupId() ? MTPmessages_ForwardMessages::Flag(0) : MTPmessages_ForwardMessages::Flag::f_grouped); - history->sendRequestId = request(MTPmessages_ForwardMessages( - MTP_flags(finalFlags), - forwardFrom->input, - MTP_vector(ids), - MTP_vector(randomIds), - peer->input, - MTP_int(action.options.scheduled) - )).done([=, callback = std::move(successCallback)]( - const MTPUpdates &updates) { - applyUpdates(updates); - if (shared && !--shared->requestsLeft) { - shared->callback(); - } - }).fail([=, ids = std::move(localIds)](const RPCError &error) { - if (ids) { - for (const auto &[randomId, itemId] : *ids) { - sendMessageFail(error, peer, randomId, itemId); + const auto requestType = Data::Histories::RequestType::Send; + histories.sendRequest(history, requestType, [=](Fn finish) { + history->sendRequestId = request(MTPmessages_ForwardMessages( + MTP_flags(finalFlags), + forwardFrom->input, + MTP_vector(ids), + MTP_vector(randomIds), + peer->input, + MTP_int(action.options.scheduled) + )).done([=]( + const MTPUpdates &updates) { + applyUpdates(updates); + if (shared && !--shared->requestsLeft) { + shared->callback(); } - } else { - sendMessageFail(error, peer); - } - }).afterRequest( - history->sendRequestId - ).send(); + finish(); + }).fail([=, ids = localIds](const RPCError &error) { + if (ids) { + for (const auto &[randomId, itemId] : *ids) { + sendMessageFail(error, peer, randomId, itemId); + } + } else { + sendMessageFail(error, peer); + } + finish(); + }).afterRequest( + history->sendRequestId + ).send(); + return history->sendRequestId; + }); ids.resize(0); randomIds.resize(0); @@ -4440,7 +4416,7 @@ void ApiWrap::forwardMessages( message); _session->data().registerMessageRandomId(randomId, newId); if (!localIds) { - localIds = std::make_unique>(); + localIds = std::make_shared>(); } localIds->emplace(randomId, newId); } @@ -4855,6 +4831,9 @@ void ApiWrap::sendMessage(MessageToSend &&message) { HistoryItem *lastMessage = nullptr; + auto &histories = history->owner().histories(); + const auto requestType = Data::Histories::RequestType::Send; + while (TextUtilities::CutPart(sending, left, MaxMessageSize)) { auto newId = FullMsgId( peerToChannel(peer->id), @@ -4945,27 +4924,32 @@ void ApiWrap::sendMessage(MessageToSend &&message) { MTPVector()), clientFlags, NewMessageType::Unread); - history->sendRequestId = request(MTPmessages_SendMessage( - MTP_flags(sendFlags), - peer->input, - MTP_int(action.replyTo), - msgText, - MTP_long(randomId), - MTPReplyMarkup(), - sentEntities, - MTP_int(action.options.scheduled) - )).done([=](const MTPUpdates &result) { - applyUpdates(result, randomId); - history->clearSentDraftText(QString()); - }).fail([=](const RPCError &error) { - if (error.type() == qstr("MESSAGE_EMPTY")) { - lastMessage->destroy(); - } else { - sendMessageFail(error, peer, randomId, newId); - } - history->clearSentDraftText(QString()); - }).afterRequest(history->sendRequestId - ).send(); + histories.sendRequest(history, requestType, [=](Fn finish) { + history->sendRequestId = request(MTPmessages_SendMessage( + MTP_flags(sendFlags), + peer->input, + MTP_int(action.replyTo), + msgText, + MTP_long(randomId), + MTPReplyMarkup(), + sentEntities, + MTP_int(action.options.scheduled) + )).done([=](const MTPUpdates &result) { + applyUpdates(result, randomId); + history->clearSentDraftText(QString()); + finish(); + }).fail([=](const RPCError &error) { + if (error.type() == qstr("MESSAGE_EMPTY")) { + lastMessage->destroy(); + } else { + sendMessageFail(error, peer, randomId, newId); + } + history->clearSentDraftText(QString()); + finish(); + }).afterRequest(history->sendRequestId + ).send(); + return history->sendRequestId; + }); } if (const auto main = App::main()) { @@ -5071,23 +5055,29 @@ void ApiWrap::sendInlineResult( history->clearCloudDraft(); history->setSentDraftText(QString()); - history->sendRequestId = request(MTPmessages_SendInlineBotResult( - MTP_flags(sendFlags), - peer->input, - MTP_int(action.replyTo), - MTP_long(randomId), - MTP_long(data->getQueryId()), - MTP_string(data->getId()), - MTP_int(action.options.scheduled) - )).done([=](const MTPUpdates &result) { - applyUpdates(result, randomId); - history->clearSentDraftText(QString()); - }).fail([=](const RPCError &error) { - sendMessageFail(error, peer, randomId, newId); - history->clearSentDraftText(QString()); - }).afterRequest(history->sendRequestId - ).send(); - + auto &histories = history->owner().histories(); + const auto requestType = Data::Histories::RequestType::Send; + histories.sendRequest(history, requestType, [=](Fn finish) { + history->sendRequestId = request(MTPmessages_SendInlineBotResult( + MTP_flags(sendFlags), + peer->input, + MTP_int(action.replyTo), + MTP_long(randomId), + MTP_long(data->getQueryId()), + MTP_string(data->getId()), + MTP_int(action.options.scheduled) + )).done([=](const MTPUpdates &result) { + applyUpdates(result, randomId); + history->clearSentDraftText(QString()); + finish(); + }).fail([=](const RPCError &error) { + sendMessageFail(error, peer, randomId, newId); + history->clearSentDraftText(QString()); + finish(); + }).afterRequest(history->sendRequestId + ).send(); + return history->sendRequestId; + }); if (const auto main = App::main()) { main->finishForwarding(action); } @@ -5206,25 +5196,32 @@ void ApiWrap::sendMediaWithRandomId( ? MTPmessages_SendMedia::Flag::f_schedule_date : MTPmessages_SendMedia::Flag(0)); - const auto peer = history->peer; - const auto itemId = item->fullId(); - history->sendRequestId = request(MTPmessages_SendMedia( - MTP_flags(flags), - peer->input, - MTP_int(replyTo), - media, - MTP_string(caption.text), - MTP_long(randomId), - MTPReplyMarkup(), - sentEntities, - MTP_int(options.scheduled) - )).done([=](const MTPUpdates &result) { - applyUpdates(result); - }).fail([=](const RPCError &error) { - sendMessageFail(error, peer, randomId, itemId); - }).afterRequest( - history->sendRequestId - ).send(); + auto &histories = history->owner().histories(); + const auto requestType = Data::Histories::RequestType::Send; + histories.sendRequest(history, requestType, [=](Fn finish) { + const auto peer = history->peer; + const auto itemId = item->fullId(); + history->sendRequestId = request(MTPmessages_SendMedia( + MTP_flags(flags), + peer->input, + MTP_int(replyTo), + media, + MTP_string(caption.text), + MTP_long(randomId), + MTPReplyMarkup(), + sentEntities, + MTP_int(options.scheduled) + )).done([=](const MTPUpdates &result) { + applyUpdates(result); + finish(); + }).fail([=](const RPCError &error) { + sendMessageFail(error, peer, randomId, itemId); + finish(); + }).afterRequest( + history->sendRequestId + ).send(); + return history->sendRequestId; + }); } void ApiWrap::sendAlbumWithUploaded( @@ -5302,27 +5299,34 @@ void ApiWrap::sendAlbumIfReady(not_null album) { | (album->options.scheduled ? MTPmessages_SendMultiMedia::Flag::f_schedule_date : MTPmessages_SendMultiMedia::Flag(0)); - const auto peer = history->peer; - history->sendRequestId = request(MTPmessages_SendMultiMedia( - MTP_flags(flags), - peer->input, - MTP_int(replyTo), - MTP_vector(medias), - MTP_int(album->options.scheduled) - )).done([=](const MTPUpdates &result) { - _sendingAlbums.remove(groupId); - applyUpdates(result); - }).fail([=](const RPCError &error) { - if (const auto album = _sendingAlbums.take(groupId)) { - for (const auto &item : (*album)->items) { - sendMessageFail(error, peer, item.randomId, item.msgId); + auto &histories = history->owner().histories(); + const auto requestType = Data::Histories::RequestType::Send; + histories.sendRequest(history, requestType, [=](Fn finish) { + const auto peer = history->peer; + history->sendRequestId = request(MTPmessages_SendMultiMedia( + MTP_flags(flags), + peer->input, + MTP_int(replyTo), + MTP_vector(medias), + MTP_int(album->options.scheduled) + )).done([=](const MTPUpdates &result) { + _sendingAlbums.remove(groupId); + applyUpdates(result); + finish(); + }).fail([=](const RPCError &error) { + if (const auto album = _sendingAlbums.take(groupId)) { + for (const auto &item : (*album)->items) { + sendMessageFail(error, peer, item.randomId, item.msgId); + } + } else { + sendMessageFail(error, peer); } - } else { - sendMessageFail(error, peer); - } - }).afterRequest( - history->sendRequestId - ).send(); + finish(); + }).afterRequest( + history->sendRequestId + ).send(); + return history->sendRequestId; + }); } FileLoadTo ApiWrap::fileLoadTaskOptions(const SendAction &action) const { @@ -5719,8 +5723,8 @@ Api::SensitiveContent &ApiWrap::sensitiveContent() { void ApiWrap::createPoll( const PollData &data, const SendAction &action, - FnMut done, - FnMut fail) { + Fn done, + Fn fail) { sendAction(action); const auto history = action.history; @@ -5753,27 +5757,34 @@ void ApiWrap::createPoll( correct.push_back(MTP_bytes(answer.option)); } } - const auto replyTo = action.replyTo; - history->sendRequestId = request(MTPmessages_SendMedia( - MTP_flags(sendFlags), - peer->input, - MTP_int(replyTo), - MTP_inputMediaPoll( - MTP_flags(inputFlags), - PollDataToMTP(&data), - MTP_vector(correct)), - MTP_string(), - MTP_long(rand_value()), - MTPReplyMarkup(), - MTPVector(), - MTP_int(action.options.scheduled) - )).done([=, done = std::move(done)](const MTPUpdates &result) mutable { - applyUpdates(result); - done(); - }).fail([=, fail = std::move(fail)](const RPCError &error) mutable { - fail(error); - }).afterRequest(history->sendRequestId - ).send(); + auto &histories = history->owner().histories(); + const auto requestType = Data::Histories::RequestType::Send; + histories.sendRequest(history, requestType, [=](Fn finish) { + const auto replyTo = action.replyTo; + history->sendRequestId = request(MTPmessages_SendMedia( + MTP_flags(sendFlags), + peer->input, + MTP_int(replyTo), + MTP_inputMediaPoll( + MTP_flags(inputFlags), + PollDataToMTP(&data), + MTP_vector(correct)), + MTP_string(), + MTP_long(rand_value()), + MTPReplyMarkup(), + MTPVector(), + MTP_int(action.options.scheduled) + )).done([=](const MTPUpdates &result) mutable { + applyUpdates(result); + done(); + finish(); + }).fail([=](const RPCError &error) mutable { + fail(error); + finish(); + }).afterRequest(history->sendRequestId + ).send(); + return history->sendRequestId; + }); } void ApiWrap::sendPollVotes( diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index a3691df2b..8f46aa7d7 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -141,6 +141,9 @@ public: void applyUpdates( const MTPUpdates &updates, uint64 sentMessageRandomId = 0); + int applyAffectedHistory( + not_null peer, + const MTPmessages_AffectedHistory &result); void registerModifyRequest(const QString &key, mtpRequestId requestId); void clearModifyRequest(const QString &key); @@ -298,10 +301,6 @@ public: void clearHistory(not_null peer, bool revoke); void deleteConversation(not_null peer, bool revoke); - void deleteMessages( - not_null peer, - const QVector &ids, - bool revoke); base::Observable &fullPeerUpdated() { return _fullPeerUpdated; @@ -469,8 +468,8 @@ public: void createPoll( const PollData &data, const SendAction &action, - FnMut done, - FnMut fail); + Fn done, + Fn fail); void sendPollVotes( FullMsgId itemId, const std::vector &options); @@ -616,9 +615,6 @@ private: not_null peer, bool justClear, bool revoke); - int applyAffectedHistory( - not_null peer, - const MTPmessages_AffectedHistory &result); void applyAffectedMessages(const MTPmessages_AffectedMessages &result); void deleteAllFromUserSend( diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 70cc1f954..c580d3716 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat.h" #include "data/data_user.h" #include "data/data_file_origin.h" +#include "data/data_histories.h" #include "base/unixtime.h" #include "main/main_session.h" #include "observer_peer.h" @@ -787,7 +788,7 @@ void DeleteMessagesBox::deleteAndClear() { auto remove = std::vector>(); remove.reserve(_ids.size()); - base::flat_map, QVector> idsByPeer; + base::flat_map, QVector> idsByPeer; base::flat_map, QVector> scheduledIdsByPeer; for (const auto itemId : _ids) { if (const auto item = _session->data().message(itemId)) { @@ -805,13 +806,13 @@ void DeleteMessagesBox::deleteAndClear() { } remove.push_back(item); if (IsServerMsgId(item->id)) { - idsByPeer[history->peer].push_back(MTP_int(itemId.msg)); + idsByPeer[history].push_back(MTP_int(itemId.msg)); } } } - for (const auto &[peer, ids] : idsByPeer) { - peer->session().api().deleteMessages(peer, ids, revoke); + for (const auto &[history, ids] : idsByPeer) { + history->owner().histories().deleteMessages(history, ids, revoke); } for (const auto &[peer, ids] : scheduledIdsByPeer) { peer->session().api().request(MTPmessages_DeleteScheduledMessages( diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index 606ecc4f4..5fab61356 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat.h" #include "data/data_user.h" #include "data/data_folder.h" +#include "data/data_histories.h" #include "apiwrap.h" #include "mainwidget.h" #include "lang/lang_keys.h" @@ -30,33 +31,36 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace { void ShareBotGame(not_null bot, not_null chat) { - const auto history = chat->owner().historyLoaded(chat); - const auto randomId = rand_value(); - const auto api = &chat->session().api(); - const auto requestId = api->request(MTPmessages_SendMedia( - MTP_flags(0), - chat->input, - MTP_int(0), - MTP_inputMediaGame( - MTP_inputGameShortName( - bot->inputUser, - MTP_string(bot->botInfo->shareGameShortName))), - MTP_string(), - MTP_long(randomId), - MTPReplyMarkup(), - MTPVector(), - MTP_int(0) // schedule_date - )).done([=](const MTPUpdates &result) { - api->applyUpdates(result, randomId); - }).fail([=](const RPCError &error) { - api->sendMessageFail(error, chat); - }).afterRequest( - history ? history->sendRequestId : 0 - ).send(); - - if (history) { - history->sendRequestId = requestId; - } + const auto history = chat->owner().history(chat); + auto &histories = history->owner().histories(); + const auto requestType = Data::Histories::RequestType::Send; + histories.sendRequest(history, requestType, [=](Fn finish) { + const auto randomId = rand_value(); + const auto api = &chat->session().api(); + history->sendRequestId = api->request(MTPmessages_SendMedia( + MTP_flags(0), + chat->input, + MTP_int(0), + MTP_inputMediaGame( + MTP_inputGameShortName( + bot->inputUser, + MTP_string(bot->botInfo->shareGameShortName))), + MTP_string(), + MTP_long(randomId), + MTPReplyMarkup(), + MTPVector(), + MTP_int(0) // schedule_date + )).done([=](const MTPUpdates &result) { + api->applyUpdates(result, randomId); + finish(); + }).fail([=](const RPCError &error) { + api->sendMessageFail(error, chat); + finish(); + }).afterRequest( + history->sendRequestId + ).send(); + return history->sendRequestId; + }); Ui::hideLayer(); Ui::showPeerHistory(chat, ShowAtUnreadMsgId); } diff --git a/Telegram/SourceFiles/data/data_histories.cpp b/Telegram/SourceFiles/data/data_histories.cpp index 571927435..7d87d1a8e 100644 --- a/Telegram/SourceFiles/data/data_histories.cpp +++ b/Telegram/SourceFiles/data/data_histories.cpp @@ -369,7 +369,7 @@ void Histories::sendReadRequests() { void Histories::sendReadRequest(not_null history, State &state) { const auto tillId = state.readTill; state.readWhen = kReadRequestSent; - sendRequest(history, RequestType::ReadInbox, [=](Fn done) { + sendRequest(history, RequestType::ReadInbox, [=](Fn finish) { const auto finished = [=] { const auto state = lookup(history); Assert(state != nullptr); @@ -386,7 +386,7 @@ void Histories::sendReadRequest(not_null history, State &state) { sendReadRequests(); } } - done(); + finish(); }; if (const auto channel = history->peer->asChannel()) { return session().api().request(MTPchannels_ReadHistory( @@ -439,10 +439,81 @@ bool Histories::postponeEntryRequest(const State &state) const { return (i != end(state.sent)); } +void Histories::deleteMessages( + not_null history, + const QVector &ids, + bool revoke) { + sendRequest(history, RequestType::Delete, [=](Fn finish) { + const auto done = [=](const MTPmessages_AffectedMessages &result) { + session().api().applyAffectedMessages(history->peer, result); + finish(); + history->requestChatListMessage(); + }; + const auto fail = [=](const RPCError &error) { + finish(); + }; + if (const auto channel = history->peer->asChannel()) { + return session().api().request(MTPchannels_DeleteMessages( + channel->inputChannel, + MTP_vector(ids) + )).done(done).fail(fail).send(); + } else { + using Flag = MTPmessages_DeleteMessages::Flag; + return session().api().request(MTPmessages_DeleteMessages( + MTP_flags(revoke ? Flag::f_revoke : Flag(0)), + MTP_vector(ids) + )).done(done).fail(fail).send(); + } + }); +} + +void Histories::deleteAllMessages( + not_null history, + MsgId deleteTillId, + bool justClear, + bool revoke) { + sendRequest(history, RequestType::Delete, [=](Fn finish) { + const auto peer = history->peer; + const auto fail = [=](const RPCError &error) { + finish(); + }; + if (const auto channel = peer->asChannel()) { + return session().api().request(MTPchannels_DeleteHistory( + channel->inputChannel, + MTP_int(deleteTillId) + )).done([=](const MTPBool &result) { + finish(); + }).fail(fail).send(); + } else { + using Flag = MTPmessages_DeleteHistory::Flag; + const auto flags = Flag(0) + | (justClear ? Flag::f_just_clear : Flag(0)) + | ((peer->isUser() && revoke) ? Flag::f_revoke : Flag(0)); + return session().api().request(MTPmessages_DeleteHistory( + MTP_flags(flags), + peer->input, + MTP_int(0) + )).done([=](const MTPmessages_AffectedHistory &result) { + const auto offset = session().api().applyAffectedHistory( + peer, + result); + if (offset > 0) { + deleteAllMessages( + history, + deleteTillId, + justClear, + revoke); + } + finish(); + }).fail(fail).send(); + } + }); +} + int Histories::sendRequest( not_null history, RequestType type, - Fn done)> generator) { + Fn finish)> generator) { Expects(type != RequestType::None); auto &state = _states[history]; diff --git a/Telegram/SourceFiles/data/data_histories.h b/Telegram/SourceFiles/data/data_histories.h index af62439b3..0cbae7539 100644 --- a/Telegram/SourceFiles/data/data_histories.h +++ b/Telegram/SourceFiles/data/data_histories.h @@ -57,18 +57,28 @@ public: void changeDialogUnreadMark(not_null history, bool unread); //void changeDialogUnreadMark(not_null feed, bool unread); // #feed + void deleteMessages( + not_null history, + const QVector &ids, + bool revoke); + void deleteAllMessages( + not_null history, + MsgId deleteTillId, + bool justClear, + bool revoke); + int sendRequest( not_null history, RequestType type, - Fn done)> generator); + Fn finish)> generator); void cancelRequest(not_null history, int id); private: struct PostponedHistoryRequest { - Fn done)> generator; + Fn finish)> generator; }; struct SentRequest { - Fn done)> generator; + Fn finish)> generator; mtpRequestId id = 0; RequestType type = RequestType::None; }; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 0c9ee4d34..7e2974d66 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -38,6 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_media_types.h" #include "data/data_channel.h" #include "data/data_user.h" +#include "data/data_histories.h" #include "facades.h" #include "app.h" #include "styles/style_dialogs.h" @@ -265,15 +266,6 @@ void FastShareMessage(not_null item) { return; } - auto doneCallback = [=](const MTPUpdates &updates, mtpRequestId requestId) { - history->session().api().applyUpdates(updates); - data->requests.remove(requestId); - if (data->requests.empty()) { - Ui::Toast::Show(tr::lng_share_done(tr::now)); - Ui::hideLayer(); - } - }; - const auto sendFlags = MTPmessages_ForwardMessages::Flag(0) | MTPmessages_ForwardMessages::Flag::f_with_my_score | (isGroup @@ -297,28 +289,40 @@ void FastShareMessage(not_null item) { } return result; }; + auto &api = owner->session().api(); + auto &histories = owner->histories(); + const auto requestType = Data::Histories::RequestType::Send; for (const auto peer : result) { - const auto history = peer->owner().history(peer); + const auto history = owner->history(peer); if (!comment.text.isEmpty()) { auto message = ApiWrap::MessageToSend(history); message.textWithTags = comment; message.action.options = options; message.action.clearDraft = false; - history->session().api().sendMessage(std::move(message)); + api.sendMessage(std::move(message)); } - history->sendRequestId = MTP::send( - MTPmessages_ForwardMessages( - MTP_flags(sendFlags), - data->peer->input, - MTP_vector(msgIds), - MTP_vector(generateRandom()), - peer->input, - MTP_int(options.scheduled)), - rpcDone(base::duplicate(doneCallback)), - nullptr, - 0, - 0, - history->sendRequestId); + histories.sendRequest(history, requestType, [=](Fn finish) { + auto &api = history->session().api(); + history->sendRequestId = api.request(MTPmessages_ForwardMessages( + MTP_flags(sendFlags), + data->peer->input, + MTP_vector(msgIds), + MTP_vector(generateRandom()), + peer->input, + MTP_int(options.scheduled) + )).done([=](const MTPUpdates &updates, mtpRequestId requestId) { + history->session().api().applyUpdates(updates); + data->requests.remove(requestId); + if (data->requests.empty()) { + Ui::Toast::Show(tr::lng_share_done(tr::now)); + Ui::hideLayer(); + } + finish(); + }).fail([=](const RPCError &error) { + finish(); + }).afterRequest(history->sendRequestId).send(); + return history->sendRequestId; + }); data->requests.insert(history->sendRequestId); } };