Send and delete messages through Histories.

This commit is contained in:
John Preston 2020-02-21 14:29:48 +04:00
parent 147e8cc467
commit 818f5cd004
8 changed files with 363 additions and 258 deletions

View file

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h" // UserData::name #include "data/data_user.h" // UserData::name
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "data/data_histories.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_message.h" // NewMessageFlags. #include "history/history_message.h" // NewMessageFlags.
#include "chat_helpers/message_field.h" // ConvertTextTagsToEntities. #include "chat_helpers/message_field.h" // ConvertTextTagsToEntities.
@ -110,6 +111,9 @@ void SendExistingMedia(
auto failHandler = std::make_shared<Fn<void(const RPCError&, QByteArray)>>(); auto failHandler = std::make_shared<Fn<void(const RPCError&, QByteArray)>>();
auto performRequest = [=] { auto performRequest = [=] {
auto &histories = history->owner().histories();
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
const auto usedFileReference = media->fileReference(); const auto usedFileReference = media->fileReference();
history->sendRequestId = api->request(MTPmessages_SendMedia( history->sendRequestId = api->request(MTPmessages_SendMedia(
MTP_flags(sendFlags), MTP_flags(sendFlags),
@ -123,10 +127,14 @@ void SendExistingMedia(
MTP_int(message.action.options.scheduled) MTP_int(message.action.options.scheduled)
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
api->applyUpdates(result, randomId); api->applyUpdates(result, randomId);
finish();
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
(*failHandler)(error, usedFileReference); (*failHandler)(error, usedFileReference);
finish();
}).afterRequest(history->sendRequestId }).afterRequest(history->sendRequestId
).send(); ).send();
return history->sendRequestId;
});
}; };
*failHandler = [=](const RPCError &error, QByteArray usedFileReference) { *failHandler = [=](const RPCError &error, QByteArray usedFileReference) {
if (error.code() == 400 if (error.code() == 400

View file

@ -2319,8 +2319,8 @@ void ApiWrap::deleteHistory(
bool justClear, bool justClear,
bool revoke) { bool revoke) {
auto deleteTillId = MsgId(0); auto deleteTillId = MsgId(0);
const auto history = _session->data().historyLoaded(peer); const auto history = _session->data().history(peer);
if (history && justClear) { if (justClear) {
// In case of clear history we need to know the last server message. // In case of clear history we need to know the last server message.
while (history->lastMessageKnown()) { while (history->lastMessageKnown()) {
const auto last = history->lastMessage(); const auto last = history->lastMessage();
@ -2350,30 +2350,22 @@ void ApiWrap::deleteHistory(
leaveChannel(channel); leaveChannel(channel);
} else { } else {
if (const auto migrated = peer->migrateFrom()) { if (const auto migrated = peer->migrateFrom()) {
clearHistory(migrated, revoke); deleteHistory(migrated, justClear, revoke);
} }
if (IsServerMsgId(deleteTillId)) { if (IsServerMsgId(deleteTillId)) {
request(MTPchannels_DeleteHistory( history->owner().histories().deleteAllMessages(
channel->inputChannel, history,
MTP_int(deleteTillId) deleteTillId,
)).send(); justClear,
revoke);
} }
} }
} else { } else {
using Flag = MTPmessages_DeleteHistory::Flag; history->owner().histories().deleteAllMessages(
const auto flags = Flag(0) history,
| (justClear ? Flag::f_just_clear : Flag(0)) deleteTillId,
| ((peer->isUser() && revoke) ? Flag::f_revoke : Flag(0)); justClear,
request(MTPmessages_DeleteHistory( revoke);
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();
} }
if (!justClear) { if (!justClear) {
_session->data().deleteConversationLocally(peer); _session->data().deleteConversationLocally(peer);
@ -2411,30 +2403,6 @@ void ApiWrap::applyAffectedMessages(
App::main()->ptsUpdateAndApply(data.vpts().v, data.vpts_count().v); App::main()->ptsUpdateAndApply(data.vpts().v, data.vpts_count().v);
} }
void ApiWrap::deleteMessages(
not_null<PeerData*> peer,
const QVector<MTPint> &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<MTPint>(ids)
)).done(done).send();
} else {
using Flag = MTPmessages_DeleteMessages::Flag;
request(MTPmessages_DeleteMessages(
MTP_flags(revoke ? Flag::f_revoke : Flag(0)),
MTP_vector<MTPint>(ids)
)).done(done).send();
}
}
void ApiWrap::saveDraftsToCloud() { void ApiWrap::saveDraftsToCloud() {
for (auto i = _draftsSaveRequestIds.begin(), e = _draftsSaveRequestIds.end(); i != e; ++i) { for (auto i = _draftsSaveRequestIds.begin(), e = _draftsSaveRequestIds.end(); i != e; ++i) {
if (i->second) continue; // sent already if (i->second) continue; // sent already
@ -4326,6 +4294,8 @@ void ApiWrap::forwardMessages(
FnMut<void()> &&successCallback) { FnMut<void()> &&successCallback) {
Expects(!items.empty()); Expects(!items.empty());
auto &histories = session().data().histories();
struct SharedCallback { struct SharedCallback {
int requestsLeft = 0; int requestsLeft = 0;
FnMut<void()> callback; FnMut<void()> callback;
@ -4342,7 +4312,7 @@ void ApiWrap::forwardMessages(
const auto history = action.history; const auto history = action.history;
const auto peer = history->peer; const auto peer = history->peer;
session().data().histories().readInbox(history); histories.readInbox(history);
const auto channelPost = peer->isChannel() && !peer->isMegagroup(); const auto channelPost = peer->isChannel() && !peer->isMegagroup();
const auto silentPost = action.options.silent const auto silentPost = action.options.silent
@ -4374,7 +4344,7 @@ void ApiWrap::forwardMessages(
auto currentGroupId = items.front()->groupId(); auto currentGroupId = items.front()->groupId();
auto ids = QVector<MTPint>(); auto ids = QVector<MTPint>();
auto randomIds = QVector<MTPlong>(); auto randomIds = QVector<MTPlong>();
auto localIds = std::unique_ptr<base::flat_map<uint64, FullMsgId>>(); auto localIds = std::shared_ptr<base::flat_map<uint64, FullMsgId>>();
const auto sendAccumulated = [&] { const auto sendAccumulated = [&] {
if (shared) { if (shared) {
@ -4384,6 +4354,8 @@ void ApiWrap::forwardMessages(
| (currentGroupId == MessageGroupId() | (currentGroupId == MessageGroupId()
? MTPmessages_ForwardMessages::Flag(0) ? MTPmessages_ForwardMessages::Flag(0)
: MTPmessages_ForwardMessages::Flag::f_grouped); : MTPmessages_ForwardMessages::Flag::f_grouped);
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_ForwardMessages( history->sendRequestId = request(MTPmessages_ForwardMessages(
MTP_flags(finalFlags), MTP_flags(finalFlags),
forwardFrom->input, forwardFrom->input,
@ -4391,13 +4363,14 @@ void ApiWrap::forwardMessages(
MTP_vector<MTPlong>(randomIds), MTP_vector<MTPlong>(randomIds),
peer->input, peer->input,
MTP_int(action.options.scheduled) MTP_int(action.options.scheduled)
)).done([=, callback = std::move(successCallback)]( )).done([=](
const MTPUpdates &updates) { const MTPUpdates &updates) {
applyUpdates(updates); applyUpdates(updates);
if (shared && !--shared->requestsLeft) { if (shared && !--shared->requestsLeft) {
shared->callback(); shared->callback();
} }
}).fail([=, ids = std::move(localIds)](const RPCError &error) { finish();
}).fail([=, ids = localIds](const RPCError &error) {
if (ids) { if (ids) {
for (const auto &[randomId, itemId] : *ids) { for (const auto &[randomId, itemId] : *ids) {
sendMessageFail(error, peer, randomId, itemId); sendMessageFail(error, peer, randomId, itemId);
@ -4405,9 +4378,12 @@ void ApiWrap::forwardMessages(
} else { } else {
sendMessageFail(error, peer); sendMessageFail(error, peer);
} }
finish();
}).afterRequest( }).afterRequest(
history->sendRequestId history->sendRequestId
).send(); ).send();
return history->sendRequestId;
});
ids.resize(0); ids.resize(0);
randomIds.resize(0); randomIds.resize(0);
@ -4440,7 +4416,7 @@ void ApiWrap::forwardMessages(
message); message);
_session->data().registerMessageRandomId(randomId, newId); _session->data().registerMessageRandomId(randomId, newId);
if (!localIds) { if (!localIds) {
localIds = std::make_unique<base::flat_map<uint64, FullMsgId>>(); localIds = std::make_shared<base::flat_map<uint64, FullMsgId>>();
} }
localIds->emplace(randomId, newId); localIds->emplace(randomId, newId);
} }
@ -4855,6 +4831,9 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
HistoryItem *lastMessage = nullptr; HistoryItem *lastMessage = nullptr;
auto &histories = history->owner().histories();
const auto requestType = Data::Histories::RequestType::Send;
while (TextUtilities::CutPart(sending, left, MaxMessageSize)) { while (TextUtilities::CutPart(sending, left, MaxMessageSize)) {
auto newId = FullMsgId( auto newId = FullMsgId(
peerToChannel(peer->id), peerToChannel(peer->id),
@ -4945,6 +4924,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
MTPVector<MTPRestrictionReason>()), MTPVector<MTPRestrictionReason>()),
clientFlags, clientFlags,
NewMessageType::Unread); NewMessageType::Unread);
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_SendMessage( history->sendRequestId = request(MTPmessages_SendMessage(
MTP_flags(sendFlags), MTP_flags(sendFlags),
peer->input, peer->input,
@ -4957,6 +4937,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
applyUpdates(result, randomId); applyUpdates(result, randomId);
history->clearSentDraftText(QString()); history->clearSentDraftText(QString());
finish();
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
if (error.type() == qstr("MESSAGE_EMPTY")) { if (error.type() == qstr("MESSAGE_EMPTY")) {
lastMessage->destroy(); lastMessage->destroy();
@ -4964,8 +4945,11 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
sendMessageFail(error, peer, randomId, newId); sendMessageFail(error, peer, randomId, newId);
} }
history->clearSentDraftText(QString()); history->clearSentDraftText(QString());
finish();
}).afterRequest(history->sendRequestId }).afterRequest(history->sendRequestId
).send(); ).send();
return history->sendRequestId;
});
} }
if (const auto main = App::main()) { if (const auto main = App::main()) {
@ -5071,6 +5055,9 @@ void ApiWrap::sendInlineResult(
history->clearCloudDraft(); history->clearCloudDraft();
history->setSentDraftText(QString()); history->setSentDraftText(QString());
auto &histories = history->owner().histories();
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_SendInlineBotResult( history->sendRequestId = request(MTPmessages_SendInlineBotResult(
MTP_flags(sendFlags), MTP_flags(sendFlags),
peer->input, peer->input,
@ -5082,12 +5069,15 @@ void ApiWrap::sendInlineResult(
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
applyUpdates(result, randomId); applyUpdates(result, randomId);
history->clearSentDraftText(QString()); history->clearSentDraftText(QString());
finish();
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
sendMessageFail(error, peer, randomId, newId); sendMessageFail(error, peer, randomId, newId);
history->clearSentDraftText(QString()); history->clearSentDraftText(QString());
finish();
}).afterRequest(history->sendRequestId }).afterRequest(history->sendRequestId
).send(); ).send();
return history->sendRequestId;
});
if (const auto main = App::main()) { if (const auto main = App::main()) {
main->finishForwarding(action); main->finishForwarding(action);
} }
@ -5206,6 +5196,9 @@ void ApiWrap::sendMediaWithRandomId(
? MTPmessages_SendMedia::Flag::f_schedule_date ? MTPmessages_SendMedia::Flag::f_schedule_date
: MTPmessages_SendMedia::Flag(0)); : MTPmessages_SendMedia::Flag(0));
auto &histories = history->owner().histories();
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
const auto peer = history->peer; const auto peer = history->peer;
const auto itemId = item->fullId(); const auto itemId = item->fullId();
history->sendRequestId = request(MTPmessages_SendMedia( history->sendRequestId = request(MTPmessages_SendMedia(
@ -5220,11 +5213,15 @@ void ApiWrap::sendMediaWithRandomId(
MTP_int(options.scheduled) MTP_int(options.scheduled)
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
applyUpdates(result); applyUpdates(result);
finish();
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
sendMessageFail(error, peer, randomId, itemId); sendMessageFail(error, peer, randomId, itemId);
finish();
}).afterRequest( }).afterRequest(
history->sendRequestId history->sendRequestId
).send(); ).send();
return history->sendRequestId;
});
} }
void ApiWrap::sendAlbumWithUploaded( void ApiWrap::sendAlbumWithUploaded(
@ -5302,6 +5299,9 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
| (album->options.scheduled | (album->options.scheduled
? MTPmessages_SendMultiMedia::Flag::f_schedule_date ? MTPmessages_SendMultiMedia::Flag::f_schedule_date
: MTPmessages_SendMultiMedia::Flag(0)); : MTPmessages_SendMultiMedia::Flag(0));
auto &histories = history->owner().histories();
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
const auto peer = history->peer; const auto peer = history->peer;
history->sendRequestId = request(MTPmessages_SendMultiMedia( history->sendRequestId = request(MTPmessages_SendMultiMedia(
MTP_flags(flags), MTP_flags(flags),
@ -5312,6 +5312,7 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
_sendingAlbums.remove(groupId); _sendingAlbums.remove(groupId);
applyUpdates(result); applyUpdates(result);
finish();
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
if (const auto album = _sendingAlbums.take(groupId)) { if (const auto album = _sendingAlbums.take(groupId)) {
for (const auto &item : (*album)->items) { for (const auto &item : (*album)->items) {
@ -5320,9 +5321,12 @@ void ApiWrap::sendAlbumIfReady(not_null<SendingAlbum*> album) {
} else { } else {
sendMessageFail(error, peer); sendMessageFail(error, peer);
} }
finish();
}).afterRequest( }).afterRequest(
history->sendRequestId history->sendRequestId
).send(); ).send();
return history->sendRequestId;
});
} }
FileLoadTo ApiWrap::fileLoadTaskOptions(const SendAction &action) const { FileLoadTo ApiWrap::fileLoadTaskOptions(const SendAction &action) const {
@ -5719,8 +5723,8 @@ Api::SensitiveContent &ApiWrap::sensitiveContent() {
void ApiWrap::createPoll( void ApiWrap::createPoll(
const PollData &data, const PollData &data,
const SendAction &action, const SendAction &action,
FnMut<void()> done, Fn<void()> done,
FnMut<void(const RPCError &error)> fail) { Fn<void(const RPCError &error)> fail) {
sendAction(action); sendAction(action);
const auto history = action.history; const auto history = action.history;
@ -5753,6 +5757,9 @@ void ApiWrap::createPoll(
correct.push_back(MTP_bytes(answer.option)); correct.push_back(MTP_bytes(answer.option));
} }
} }
auto &histories = history->owner().histories();
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
const auto replyTo = action.replyTo; const auto replyTo = action.replyTo;
history->sendRequestId = request(MTPmessages_SendMedia( history->sendRequestId = request(MTPmessages_SendMedia(
MTP_flags(sendFlags), MTP_flags(sendFlags),
@ -5767,13 +5774,17 @@ void ApiWrap::createPoll(
MTPReplyMarkup(), MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(), MTPVector<MTPMessageEntity>(),
MTP_int(action.options.scheduled) MTP_int(action.options.scheduled)
)).done([=, done = std::move(done)](const MTPUpdates &result) mutable { )).done([=](const MTPUpdates &result) mutable {
applyUpdates(result); applyUpdates(result);
done(); done();
}).fail([=, fail = std::move(fail)](const RPCError &error) mutable { finish();
}).fail([=](const RPCError &error) mutable {
fail(error); fail(error);
finish();
}).afterRequest(history->sendRequestId }).afterRequest(history->sendRequestId
).send(); ).send();
return history->sendRequestId;
});
} }
void ApiWrap::sendPollVotes( void ApiWrap::sendPollVotes(

View file

@ -141,6 +141,9 @@ public:
void applyUpdates( void applyUpdates(
const MTPUpdates &updates, const MTPUpdates &updates,
uint64 sentMessageRandomId = 0); uint64 sentMessageRandomId = 0);
int applyAffectedHistory(
not_null<PeerData*> peer,
const MTPmessages_AffectedHistory &result);
void registerModifyRequest(const QString &key, mtpRequestId requestId); void registerModifyRequest(const QString &key, mtpRequestId requestId);
void clearModifyRequest(const QString &key); void clearModifyRequest(const QString &key);
@ -298,10 +301,6 @@ public:
void clearHistory(not_null<PeerData*> peer, bool revoke); void clearHistory(not_null<PeerData*> peer, bool revoke);
void deleteConversation(not_null<PeerData*> peer, bool revoke); void deleteConversation(not_null<PeerData*> peer, bool revoke);
void deleteMessages(
not_null<PeerData*> peer,
const QVector<MTPint> &ids,
bool revoke);
base::Observable<PeerData*> &fullPeerUpdated() { base::Observable<PeerData*> &fullPeerUpdated() {
return _fullPeerUpdated; return _fullPeerUpdated;
@ -469,8 +468,8 @@ public:
void createPoll( void createPoll(
const PollData &data, const PollData &data,
const SendAction &action, const SendAction &action,
FnMut<void()> done, Fn<void()> done,
FnMut<void(const RPCError &error)> fail); Fn<void(const RPCError &error)> fail);
void sendPollVotes( void sendPollVotes(
FullMsgId itemId, FullMsgId itemId,
const std::vector<QByteArray> &options); const std::vector<QByteArray> &options);
@ -616,9 +615,6 @@ private:
not_null<PeerData*> peer, not_null<PeerData*> peer,
bool justClear, bool justClear,
bool revoke); bool revoke);
int applyAffectedHistory(
not_null<PeerData*> peer,
const MTPmessages_AffectedHistory &result);
void applyAffectedMessages(const MTPmessages_AffectedMessages &result); void applyAffectedMessages(const MTPmessages_AffectedMessages &result);
void deleteAllFromUserSend( void deleteAllFromUserSend(

View file

@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat.h" #include "data/data_chat.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "data/data_histories.h"
#include "base/unixtime.h" #include "base/unixtime.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "observer_peer.h" #include "observer_peer.h"
@ -787,7 +788,7 @@ void DeleteMessagesBox::deleteAndClear() {
auto remove = std::vector<not_null<HistoryItem*>>(); auto remove = std::vector<not_null<HistoryItem*>>();
remove.reserve(_ids.size()); remove.reserve(_ids.size());
base::flat_map<not_null<PeerData*>, QVector<MTPint>> idsByPeer; base::flat_map<not_null<History*>, QVector<MTPint>> idsByPeer;
base::flat_map<not_null<PeerData*>, QVector<MTPint>> scheduledIdsByPeer; base::flat_map<not_null<PeerData*>, QVector<MTPint>> scheduledIdsByPeer;
for (const auto itemId : _ids) { for (const auto itemId : _ids) {
if (const auto item = _session->data().message(itemId)) { if (const auto item = _session->data().message(itemId)) {
@ -805,13 +806,13 @@ void DeleteMessagesBox::deleteAndClear() {
} }
remove.push_back(item); remove.push_back(item);
if (IsServerMsgId(item->id)) { 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) { for (const auto &[history, ids] : idsByPeer) {
peer->session().api().deleteMessages(peer, ids, revoke); history->owner().histories().deleteMessages(history, ids, revoke);
} }
for (const auto &[peer, ids] : scheduledIdsByPeer) { for (const auto &[peer, ids] : scheduledIdsByPeer) {
peer->session().api().request(MTPmessages_DeleteScheduledMessages( peer->session().api().request(MTPmessages_DeleteScheduledMessages(

View file

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat.h" #include "data/data_chat.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_folder.h" #include "data/data_folder.h"
#include "data/data_histories.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
@ -30,10 +31,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace { namespace {
void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) { void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
const auto history = chat->owner().historyLoaded(chat); const auto history = chat->owner().history(chat);
auto &histories = history->owner().histories();
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
const auto randomId = rand_value<uint64>(); const auto randomId = rand_value<uint64>();
const auto api = &chat->session().api(); const auto api = &chat->session().api();
const auto requestId = api->request(MTPmessages_SendMedia( history->sendRequestId = api->request(MTPmessages_SendMedia(
MTP_flags(0), MTP_flags(0),
chat->input, chat->input,
MTP_int(0), MTP_int(0),
@ -48,15 +52,15 @@ void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
MTP_int(0) // schedule_date MTP_int(0) // schedule_date
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
api->applyUpdates(result, randomId); api->applyUpdates(result, randomId);
finish();
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
api->sendMessageFail(error, chat); api->sendMessageFail(error, chat);
finish();
}).afterRequest( }).afterRequest(
history ? history->sendRequestId : 0 history->sendRequestId
).send(); ).send();
return history->sendRequestId;
if (history) { });
history->sendRequestId = requestId;
}
Ui::hideLayer(); Ui::hideLayer();
Ui::showPeerHistory(chat, ShowAtUnreadMsgId); Ui::showPeerHistory(chat, ShowAtUnreadMsgId);
} }

View file

@ -369,7 +369,7 @@ void Histories::sendReadRequests() {
void Histories::sendReadRequest(not_null<History*> history, State &state) { void Histories::sendReadRequest(not_null<History*> history, State &state) {
const auto tillId = state.readTill; const auto tillId = state.readTill;
state.readWhen = kReadRequestSent; state.readWhen = kReadRequestSent;
sendRequest(history, RequestType::ReadInbox, [=](Fn<void()> done) { sendRequest(history, RequestType::ReadInbox, [=](Fn<void()> finish) {
const auto finished = [=] { const auto finished = [=] {
const auto state = lookup(history); const auto state = lookup(history);
Assert(state != nullptr); Assert(state != nullptr);
@ -386,7 +386,7 @@ void Histories::sendReadRequest(not_null<History*> history, State &state) {
sendReadRequests(); sendReadRequests();
} }
} }
done(); finish();
}; };
if (const auto channel = history->peer->asChannel()) { if (const auto channel = history->peer->asChannel()) {
return session().api().request(MTPchannels_ReadHistory( return session().api().request(MTPchannels_ReadHistory(
@ -439,10 +439,81 @@ bool Histories::postponeEntryRequest(const State &state) const {
return (i != end(state.sent)); return (i != end(state.sent));
} }
void Histories::deleteMessages(
not_null<History*> history,
const QVector<MTPint> &ids,
bool revoke) {
sendRequest(history, RequestType::Delete, [=](Fn<void()> 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<MTPint>(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<MTPint>(ids)
)).done(done).fail(fail).send();
}
});
}
void Histories::deleteAllMessages(
not_null<History*> history,
MsgId deleteTillId,
bool justClear,
bool revoke) {
sendRequest(history, RequestType::Delete, [=](Fn<void()> 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( int Histories::sendRequest(
not_null<History*> history, not_null<History*> history,
RequestType type, RequestType type,
Fn<mtpRequestId(Fn<void()> done)> generator) { Fn<mtpRequestId(Fn<void()> finish)> generator) {
Expects(type != RequestType::None); Expects(type != RequestType::None);
auto &state = _states[history]; auto &state = _states[history];

View file

@ -57,18 +57,28 @@ public:
void changeDialogUnreadMark(not_null<History*> history, bool unread); void changeDialogUnreadMark(not_null<History*> history, bool unread);
//void changeDialogUnreadMark(not_null<Data::Feed*> feed, bool unread); // #feed //void changeDialogUnreadMark(not_null<Data::Feed*> feed, bool unread); // #feed
void deleteMessages(
not_null<History*> history,
const QVector<MTPint> &ids,
bool revoke);
void deleteAllMessages(
not_null<History*> history,
MsgId deleteTillId,
bool justClear,
bool revoke);
int sendRequest( int sendRequest(
not_null<History*> history, not_null<History*> history,
RequestType type, RequestType type,
Fn<mtpRequestId(Fn<void()> done)> generator); Fn<mtpRequestId(Fn<void()> finish)> generator);
void cancelRequest(not_null<History*> history, int id); void cancelRequest(not_null<History*> history, int id);
private: private:
struct PostponedHistoryRequest { struct PostponedHistoryRequest {
Fn<mtpRequestId(Fn<void()> done)> generator; Fn<mtpRequestId(Fn<void()> finish)> generator;
}; };
struct SentRequest { struct SentRequest {
Fn<mtpRequestId(Fn<void()> done)> generator; Fn<mtpRequestId(Fn<void()> finish)> generator;
mtpRequestId id = 0; mtpRequestId id = 0;
RequestType type = RequestType::None; RequestType type = RequestType::None;
}; };

View file

@ -38,6 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_media_types.h" #include "data/data_media_types.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_histories.h"
#include "facades.h" #include "facades.h"
#include "app.h" #include "app.h"
#include "styles/style_dialogs.h" #include "styles/style_dialogs.h"
@ -265,15 +266,6 @@ void FastShareMessage(not_null<HistoryItem*> item) {
return; 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) const auto sendFlags = MTPmessages_ForwardMessages::Flag(0)
| MTPmessages_ForwardMessages::Flag::f_with_my_score | MTPmessages_ForwardMessages::Flag::f_with_my_score
| (isGroup | (isGroup
@ -297,28 +289,40 @@ void FastShareMessage(not_null<HistoryItem*> item) {
} }
return result; return result;
}; };
auto &api = owner->session().api();
auto &histories = owner->histories();
const auto requestType = Data::Histories::RequestType::Send;
for (const auto peer : result) { for (const auto peer : result) {
const auto history = peer->owner().history(peer); const auto history = owner->history(peer);
if (!comment.text.isEmpty()) { if (!comment.text.isEmpty()) {
auto message = ApiWrap::MessageToSend(history); auto message = ApiWrap::MessageToSend(history);
message.textWithTags = comment; message.textWithTags = comment;
message.action.options = options; message.action.options = options;
message.action.clearDraft = false; message.action.clearDraft = false;
history->session().api().sendMessage(std::move(message)); api.sendMessage(std::move(message));
} }
history->sendRequestId = MTP::send( histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
MTPmessages_ForwardMessages( auto &api = history->session().api();
history->sendRequestId = api.request(MTPmessages_ForwardMessages(
MTP_flags(sendFlags), MTP_flags(sendFlags),
data->peer->input, data->peer->input,
MTP_vector<MTPint>(msgIds), MTP_vector<MTPint>(msgIds),
MTP_vector<MTPlong>(generateRandom()), MTP_vector<MTPlong>(generateRandom()),
peer->input, peer->input,
MTP_int(options.scheduled)), MTP_int(options.scheduled)
rpcDone(base::duplicate(doneCallback)), )).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
nullptr, history->session().api().applyUpdates(updates);
0, data->requests.remove(requestId);
0, if (data->requests.empty()) {
history->sendRequestId); 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); data->requests.insert(history->sendRequestId);
} }
}; };