Reuse sending APIs and try to fix media references

This commit is contained in:
Eric Kotato 2020-09-11 09:23:30 +03:00
parent 23c8792935
commit eeaa4923a4
5 changed files with 404 additions and 292 deletions

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unixtime.h"
#include "data/data_document.h"
#include "data/data_photo.h"
#include "data/data_location.h"
#include "data/data_channel.h" // ChannelData::addsSignature.
#include "data/data_user.h" // UserData::name
#include "data/data_session.h"
@ -62,7 +63,9 @@ void SendExistingMedia(
Api::MessageToSend &&message,
not_null<MediaData*> media,
Fn<MTPInputMedia()> inputMedia,
Data::FileOrigin origin) {
Data::FileOrigin origin,
Fn<void()> doneCallback = nullptr,
bool forwarding = false) {
const auto history = message.action.history;
const auto peer = history->peer;
const auto session = &history->session();
@ -135,7 +138,6 @@ void SendExistingMedia(
auto &histories = history->owner().histories();
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
const auto usedFileReference = media->fileReference();
history->sendRequestId = api->request(MTPmessages_SendMedia(
MTP_flags(sendFlags),
peer->input,
@ -146,12 +148,16 @@ void SendExistingMedia(
MTPReplyMarkup(),
sentEntities,
MTP_int(message.action.options.scheduled)
)).done([=](const MTPUpdates &result) {
)).done([=](const MTPUpdates &result, mtpRequestId requestId) {
api->applyUpdates(result, randomId);
if (doneCallback) {
doneCallback();
}
finish();
}).fail([=](const RPCError &error) {
if (error.code() == 400
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
const auto usedFileReference = media->fileReference();
api->refreshFileReference(origin, [=](const auto &result) {
if (media->fileReference() != usedFileReference) {
repeatRequest(repeatRequest);
@ -170,14 +176,18 @@ void SendExistingMedia(
};
performRequest(performRequest);
api->finishForwarding(message.action);
if (!forwarding) {
api->finishForwarding(message.action);
}
}
} // namespace
void SendExistingDocument(
Api::MessageToSend &&message,
not_null<DocumentData*> document) {
not_null<DocumentData*> document,
Fn<void()> doneCallback,
bool forwarding) {
const auto inputMedia = [=] {
return MTP_inputMediaDocument(
MTP_flags(0),
@ -188,7 +198,9 @@ void SendExistingDocument(
std::move(message),
document,
inputMedia,
document->stickerOrGifOrigin());
document->stickerOrGifOrigin(),
(doneCallback ? std::move(doneCallback) : nullptr),
forwarding);
if (document->sticker()) {
document->owner().stickers().incrementSticker(document);
@ -197,7 +209,9 @@ void SendExistingDocument(
void SendExistingPhoto(
Api::MessageToSend &&message,
not_null<PhotoData*> photo) {
not_null<PhotoData*> photo,
Fn<void()> doneCallback,
bool forwarding) {
const auto inputMedia = [=] {
return MTP_inputMediaPhoto(
MTP_flags(0),
@ -208,7 +222,9 @@ void SendExistingPhoto(
std::move(message),
photo,
inputMedia,
Data::FileOrigin());
Data::FileOrigin(),
(doneCallback ? std::move(doneCallback) : nullptr),
forwarding);
}
bool SendDice(Api::MessageToSend &message) {
@ -550,4 +566,64 @@ void SendConfirmedFile(
}
}
void SendLocationPoint(
const Data::LocationPoint &data,
const SendAction &action,
Fn<void()> done,
Fn<void(const RPCError &error)> fail) {
const auto history = action.history;
const auto session = &history->session();
const auto api = &session->api();
const auto peer = history->peer;
api->sendAction(action);
auto sendFlags = MTPmessages_SendMedia::Flags(0);
if (action.replyTo) {
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
}
if (action.clearDraft) {
sendFlags |= MTPmessages_SendMedia::Flag::f_clear_draft;
history->clearLocalDraft();
history->clearCloudDraft();
}
const auto silentPost = action.options.silent
|| (peer->isBroadcast() && session->data().notifySilentPosts(peer));
if (silentPost) {
sendFlags |= MTPmessages_SendMedia::Flag::f_silent;
}
if (action.options.scheduled) {
sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date;
}
auto &histories = history->owner().histories();
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
const auto replyTo = action.replyTo;
history->sendRequestId = api->request(MTPmessages_SendMedia(
MTP_flags(sendFlags),
peer->input,
MTP_int(replyTo),
MTP_inputMediaGeoPoint(
MTP_inputGeoPoint(
MTP_double(data.lat()),
MTP_double(data.lon()))),
MTP_string(),
MTP_long(rand_value<uint64>()),
MTPReplyMarkup(),
MTPVector<MTPMessageEntity>(),
MTP_int(action.options.scheduled)
)).done([=](const MTPUpdates &result) mutable {
api->applyUpdates(result);
done();
finish();
}).fail([=](const RPCError &error) mutable {
if (fail) {
fail(error);
}
finish();
}).afterRequest(history->sendRequestId
).send();
return history->sendRequestId;
});
}
} // namespace Api

View file

@ -11,6 +11,11 @@ class History;
class PhotoData;
class DocumentData;
struct FileLoadResult;
class RPCError;
namespace Data {
class LocationPoint;
} // namespace Data
namespace Api {
@ -19,11 +24,15 @@ struct SendAction;
void SendExistingDocument(
Api::MessageToSend &&message,
not_null<DocumentData*> document);
not_null<DocumentData*> document,
Fn<void()> doneCallback = nullptr,
bool forwarding = false);
void SendExistingPhoto(
Api::MessageToSend &&message,
not_null<PhotoData*> photo);
not_null<PhotoData*> photo,
Fn<void()> doneCallback = nullptr,
bool forwarding = false);
bool SendDice(Api::MessageToSend &message);
@ -37,4 +46,10 @@ void SendConfirmedFile(
const std::shared_ptr<FileLoadResult> &file,
const std::optional<FullMsgId> &oldId);
void SendLocationPoint(
const Data::LocationPoint &data,
const SendAction &action,
Fn<void()> done,
Fn<void(const RPCError &error)> fail);
} // namespace Api

View file

@ -4086,7 +4086,9 @@ void ApiWrap::forwardMessages(
++shared->requestsLeft;
}
auto medias = QVector<MTPInputSingleMedia>();
auto mediaRefs = QVector<QByteArray>();
medias.reserve(ids.size());
mediaRefs.reserve(ids.size());
for (auto i = fromIter, e = toIter; i != e; i++) {
const auto item = *i;
@ -4125,33 +4127,74 @@ void ApiWrap::forwardMessages(
: MTPmessages_SendMultiMedia::Flag(0));
const auto requestType = Data::Histories::RequestType::Send;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_SendMultiMedia(
MTP_flags(finalFlags),
peer->input,
MTPint(),
MTP_vector<MTPInputSingleMedia>(medias),
MTP_int(action.options.scheduled)
)).done([=](const MTPUpdates &result) {
applyUpdates(result);
if (shared && !--shared->requestsLeft) {
shared->callback();
}
finish();
}).fail([=, ids = localIds](const RPCError &error) {
if (ids) {
for (const auto &[randomId, itemId] : *ids) {
sendMessageFail(error, peer, randomId, itemId);
auto performRequest = [=, &mediaRefs, &histories](const auto &repeatRequest) -> void {
mediaRefs.clear();
for (auto i = fromIter, e = toIter; i != e; i++) {
const auto item = *i;
const auto media = item->media();
mediaRefs.push_back(media->photo()
? media->photo()->fileReference()
: media->document()->fileReference());
}
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_SendMultiMedia(
MTP_flags(finalFlags),
peer->input,
MTPint(),
MTP_vector<MTPInputSingleMedia>(medias),
MTP_int(action.options.scheduled)
)).done([=](const MTPUpdates &result) {
applyUpdates(result);
if (shared && !--shared->requestsLeft) {
shared->callback();
}
} else {
sendMessageFail(error, peer);
}
finish();
}).afterRequest(
history->sendRequestId
).send();
return history->sendRequestId;
});
finish();
}).fail([=, ids = localIds](const RPCError &error) {
if (error.code() == 400
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
auto refreshRequests = mediaRefs.size();
auto index = 0;
for (auto i = fromIter, e = toIter; i != e; i++) {
const auto item = *i;
const auto media = item->media();
const auto origin = media->document()
? media->document()->stickerOrGifOrigin()
: Data::FileOrigin();
const auto usedFileReference = mediaRefs.value(index);
refreshFileReference(origin, [=, &refreshRequests](const auto &result) {
if (refreshRequests > 0) {
refreshRequests--;
return;
}
const auto currentMediaReference = media->photo()
? media->photo()->fileReference()
: media->document()->fileReference();
if (currentMediaReference != usedFileReference) {
repeatRequest(repeatRequest);
} else {
sendMessageFail(error, peer);
}
});
index++;
}
} else 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;
});
};
performRequest(performRequest);
};
const auto forwardMediaUnquoted = [&] (not_null<HistoryItem *> item) {
@ -4160,86 +4203,62 @@ void ApiWrap::forwardMessages(
}
const auto media = item->media();
auto newSendFlags = MTPmessages_SendMedia::Flags(0)
| (action.options.silent
? MTPmessages_SendMedia::Flag::f_silent
: MTPmessages_SendMedia::Flag(0))
| (action.options.scheduled
? MTPmessages_SendMedia::Flag::f_schedule_date
: MTPmessages_SendMedia::Flag(0));
auto message = ApiWrap::MessageToSend(history);
const auto caption = (cForwardCaptioned()
&& !media->geoPoint()
&& !media->sharedContact())
? item->originalText()
: TextWithEntities();
auto caption = (cForwardCaptioned()
&& !media->geoPoint()
&& !media->sharedContact())
? item->originalText()
: TextWithEntities();
message.textWithTags = TextWithTags{
caption.text,
TextUtilities::ConvertEntitiesToTextTags(caption.entities)
};
message.action.options = action.options;
message.action.clearDraft = false;
auto sentEntities = Api::EntitiesToMTP(
_session,
caption.entities,
Api::ConvertOption::SkipLocal);
if (!sentEntities.v.isEmpty()) {
newSendFlags |= MTPmessages_SendMedia::Flag::f_entities;
auto doneCallback = [=] () {
if (shared && !--shared->requestsLeft) {
shared->callback();
}
};
if (media->poll()) {
const auto poll = *(media->poll());
createPoll(
poll,
message.action,
std::move(doneCallback),
nullptr);
} else if (media->geoPoint()) {
const auto location = *(media->geoPoint());
Api::SendLocationPoint(
location,
message.action,
std::move(doneCallback),
nullptr);
} else if (media->sharedContact()) {
const auto contact = media->sharedContact();
shareContact(
contact->phoneNumber,
contact->firstName,
contact->lastName,
message.action);
} else if (media->photo()) {
Api::SendExistingPhoto(
std::move(message),
media->photo(),
std::move(doneCallback),
true); // forwarding
} else if (media->document()) {
Api::SendExistingDocument(
std::move(message),
media->document(),
std::move(doneCallback),
true); // forwarding
} else {
Unexpected("Media type in ApiWrap::forwardMessages.");
}
auto inputMedia = media->poll()
? PollDataToInputMedia(media->poll())
: media->geoPoint()
? MTP_inputMediaGeoPoint(
MTP_inputGeoPoint(
MTP_double(media->geoPoint()->lat()),
MTP_double(media->geoPoint()->lon())))
: media->sharedContact()
? MTP_inputMediaContact(
MTP_string(media->sharedContact()->phoneNumber),
MTP_string(media->sharedContact()->firstName),
MTP_string(media->sharedContact()->lastName),
MTPstring())
: media->photo()
? MTP_inputMediaPhoto(MTP_flags(0), media->photo()->mtpInput(), MTPint())
: MTP_inputMediaDocument(MTP_flags(0), media->document()->mtpInput(), MTPint());
const auto requestType = Data::Histories::RequestType::Send;
const auto currentRandomId = randomIds.takeFirst();
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_SendMedia(
MTP_flags(newSendFlags),
peer->input,
MTPint(),
inputMedia,
MTP_string(caption.text),
currentRandomId,
MTPReplyMarkup(),
sentEntities,
MTP_int(action.options.scheduled)
)).done([=](const MTPUpdates &result) {
applyUpdates(result);
if (shared && !--shared->requestsLeft) {
shared->callback();
}
finish();
}).fail([=, ids = localIds](const RPCError &error) {
if (ids) {
auto found = false;
for (const auto &[randomId, itemId] : *ids) {
if (currentRandomId == MTP_long(randomId)) {
sendMessageFail(error, peer, randomId, itemId);
found = true;
break;
}
}
if (!found) {
sendMessageFail(error, peer);
}
} else {
sendMessageFail(error, peer);
}
finish();
}).afterRequest(
history->sendRequestId
).send();
return history->sendRequestId;
});
};
const auto forwardMessageUnquoted = [&] (not_null<HistoryItem *> item) {
@ -4248,65 +4267,27 @@ void ApiWrap::forwardMessages(
}
const auto media = item->media();
auto newSendFlags = MTPmessages_SendMessage::Flag(0)
| (!media || !media->webpage()
? MTPmessages_SendMessage::Flag::f_no_webpage
: MTPmessages_SendMessage::Flag(0))
| (action.options.silent
? MTPmessages_SendMessage::Flag::f_silent
: MTPmessages_SendMessage::Flag(0))
| (action.options.scheduled
? MTPmessages_SendMessage::Flag::f_schedule_date
: MTPmessages_SendMessage::Flag(0));
const auto webPageId = (!media || !media->webpage())
? CancelledWebPageId
: media->webpage()->id;
auto sentEntities = Api::EntitiesToMTP(
_session,
item->originalText().entities,
Api::ConvertOption::SkipLocal);
if (!sentEntities.v.isEmpty()) {
newSendFlags |= MTPmessages_SendMessage::Flag::f_entities;
}
auto message = ApiWrap::MessageToSend(history);
message.textWithTags = TextWithTags{
item->originalText().text,
TextUtilities::ConvertEntitiesToTextTags(item->originalText().entities)
};
message.action.options = action.options;
message.action.clearDraft = false;
message.webPageId = webPageId;
const auto requestType = Data::Histories::RequestType::Send;
const auto currentRandomId = randomIds.takeFirst();
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_SendMessage(
MTP_flags(newSendFlags),
peer->input,
MTPint(),
MTP_string(item->originalText().text),
currentRandomId,
MTPReplyMarkup(),
sentEntities,
MTP_int(action.options.scheduled)
)).done([=](const MTPUpdates &result) {
applyUpdates(result);
session().api().sendMessage(
std::move(message),
[=] (const MTPUpdates &result, mtpRequestId requestId) {
if (shared && !--shared->requestsLeft) {
shared->callback();
}
finish();
}).fail([=, ids = localIds](const RPCError &error) {
if (ids) {
auto found = false;
for (const auto &[randomId, itemId] : *ids) {
if (currentRandomId == MTP_long(randomId)) {
sendMessageFail(error, peer, randomId, itemId);
found = true;
break;
}
}
if (!found) {
sendMessageFail(error, peer);
}
} else {
sendMessageFail(error, peer);
}
finish();
}).afterRequest(
history->sendRequestId
).send();
return history->sendRequestId;
});
},
true); // forwarding
};
const auto sendAccumulated = [&] {
@ -4650,7 +4631,10 @@ void ApiWrap::cancelLocalItem(not_null<HistoryItem*> item) {
}
}
void ApiWrap::sendMessage(MessageToSend &&message) {
void ApiWrap::sendMessage(
MessageToSend &&message,
Fn<void(const MTPUpdates &, mtpRequestId)> doneCallback,
bool forwarding) {
const auto history = message.action.history;
const auto peer = history->peer;
auto &textWithTags = message.textWithTags;
@ -4779,9 +4763,12 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
MTPReplyMarkup(),
sentEntities,
MTP_int(action.options.scheduled)
)).done([=](const MTPUpdates &result) {
)).done([=](const MTPUpdates &result, mtpRequestId requestId) {
applyUpdates(result, randomId);
history->clearSentDraftText(QString());
if (doneCallback) {
doneCallback(result, requestId);
}
finish();
}).fail([=](const RPCError &error) {
if (error.type() == qstr("MESSAGE_EMPTY")) {
@ -4797,7 +4784,9 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
});
}
finishForwarding(action);
if (!forwarding) {
finishForwarding(action);
}
}
void ApiWrap::sendBotStart(not_null<UserData*> bot, PeerData *chat) {
@ -5621,7 +5610,9 @@ void ApiWrap::createPoll(
done();
finish();
}).fail([=](const RPCError &error) mutable {
fail(error);
if (fail) {
fail(error);
}
finish();
}).afterRequest(history->sendRequestId
).send();

View file

@ -421,7 +421,10 @@ public:
void cancelLocalItem(not_null<HistoryItem*> item);
void sendMessage(MessageToSend &&message);
void sendMessage(
MessageToSend &&message,
Fn<void(const MTPUpdates &, mtpRequestId)> doneCallback = nullptr,
bool forwarding = false);
void sendBotStart(not_null<UserData*> bot, PeerData *chat = nullptr);
void sendInlineResult(
not_null<UserData*> bot,

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_peer_menu.h"
#include "lang/lang_keys.h"
#include "api/api_sending.h"
#include "boxes/confirm_box.h"
#include "boxes/mute_settings_box.h"
#include "boxes/add_contact_box.h"
@ -54,9 +55,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_drafts.h"
#include "data/data_user.h"
#include "data/data_game.h"
#include "data/data_web_page.h"
#include "data/data_scheduled_messages.h"
#include "data/data_histories.h"
#include "data/data_chat_filters.h"
#include "data/data_file_origin.h"
#include "dialogs/dialogs_key.h"
#include "core/application.h"
#include "export/export_manager.h"
@ -1116,7 +1119,7 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
}
not_null<PeerData*> peer;
MessageIdsList msgIds;
base::flat_set<mtpRequestId> requests;
int requestsLeft = 0;
FnMut<void()> submitCallback;
};
struct MsgIdsGroup {
@ -1188,7 +1191,7 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
std::vector<not_null<PeerData*>> &&result,
TextWithTags &&comment,
Api::SendOptions options) {
if (!data->requests.empty()) {
if (data->requestsLeft > 0) {
return; // Share clicked already.
}
auto items = history->owner().idsToItems(data->msgIds);
@ -1278,9 +1281,9 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
}
return result;
};
const auto checkAndClose = [=] (mtpRequestId requestId) {
data->requests.remove(requestId);
if (data->requests.empty()) {
const auto checkAndClose = [=] {
data->requestsLeft--;
if (!data->requestsLeft) {
Ui::Toast::Show(tr::lng_share_done(tr::now));
Ui::hideLayer();
}
@ -1304,19 +1307,21 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
MTP_int(options.scheduled)
)).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
history->session().api().applyUpdates(updates);
checkAndClose(requestId);
checkAndClose();
finish();
}).fail([=](const RPCError &error) {
finish();
}).afterRequest(history->sendRequestId).send();
return history->sendRequestId;
});
data->requests.insert(history->sendRequestId);
data->requestsLeft++;
};
const auto forwardAlbumUnquoted = [&] (MsgIdsGroup &&group, not_null<History*> history) {
auto medias = QVector<MTPInputSingleMedia>();
auto mediaRefs = QVector<QByteArray>();
medias.reserve(group.items.size());
mediaRefs.reserve(group.items.size());
auto randomIds = generateRandom(group.items.size());
@ -1345,6 +1350,9 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
randomId,
MTP_string(caption.text),
sentEntities));
mediaRefs.push_back(media->photo()
? media->photo()->fileReference()
: media->document()->fileReference());
}
const auto flags = MTPmessages_SendMultiMedia::Flags(0)
@ -1355,135 +1363,154 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
? MTPmessages_SendMultiMedia::Flag::f_schedule_date
: MTPmessages_SendMultiMedia::Flag(0));
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
auto &api = history->session().api();
history->sendRequestId = api.request(MTPmessages_SendMultiMedia(
MTP_flags(flags),
history->peer->input,
MTPint(),
MTP_vector<MTPInputSingleMedia>(medias),
MTP_int(options.scheduled)
)).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
history->session().api().applyUpdates(updates);
checkAndClose(requestId);
finish();
}).fail([=](const RPCError &error) {
finish();
}).afterRequest(history->sendRequestId).send();
return history->sendRequestId;
});
data->requests.insert(history->sendRequestId);
auto performRequest = [=, &mediaRefs, &histories](const auto &repeatRequest) -> void {
mediaRefs.clear();
for (const auto item : group.items) {
const auto media = item->media();
mediaRefs.push_back(media->photo()
? media->photo()->fileReference()
: media->document()->fileReference());
}
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
auto &api = history->session().api();
history->sendRequestId = api.request(MTPmessages_SendMultiMedia(
MTP_flags(flags),
history->peer->input,
MTPint(),
MTP_vector<MTPInputSingleMedia>(medias),
MTP_int(options.scheduled)
)).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
history->session().api().applyUpdates(updates);
checkAndClose();
finish();
}).fail([=](const RPCError &error) {
if (error.code() == 400
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
auto refreshRequests = mediaRefs.size();
auto index = 0;
for (const auto item : group.items) {
const auto media = item->media();
const auto origin = media->document()
? media->document()->stickerOrGifOrigin()
: Data::FileOrigin();
const auto usedFileReference = mediaRefs.value(index);
history->session().api().refreshFileReference(origin, [=, &refreshRequests](const auto &result) {
if (refreshRequests > 0) {
refreshRequests--;
return;
}
const auto currentMediaReference = media->photo()
? media->photo()->fileReference()
: media->document()->fileReference();
if (currentMediaReference != usedFileReference) {
repeatRequest(repeatRequest);
} else {
history->session().api().sendMessageFail(error, history->peer);
}
});
index++;
}
} else {
finish();
}
}).afterRequest(history->sendRequestId).send();
return history->sendRequestId;
});
};
performRequest(performRequest);
data->requestsLeft++;
};
const auto forwardMediaUnquoted = [&] (not_null<HistoryItem *> item, not_null<History*> history) {
const auto media = item->media();
auto newSendFlags = MTPmessages_SendMedia::Flags(0)
| (options.silent
? MTPmessages_SendMedia::Flag::f_silent
: MTPmessages_SendMedia::Flag(0))
| (options.scheduled
? MTPmessages_SendMedia::Flag::f_schedule_date
: MTPmessages_SendMedia::Flag(0));
auto message = ApiWrap::MessageToSend(history);
const auto caption = (cForwardCaptioned()
&& !media->geoPoint()
&& !media->sharedContact())
? item->originalText()
: TextWithEntities();
&& !media->geoPoint()
&& !media->sharedContact())
? item->originalText()
: TextWithEntities();
const auto sentEntities = Api::EntitiesToMTP(
session,
caption.entities,
Api::ConvertOption::SkipLocal);
if (!sentEntities.v.isEmpty()) {
newSendFlags |= MTPmessages_SendMedia::Flag::f_entities;
message.textWithTags = TextWithTags{
caption.text,
TextUtilities::ConvertEntitiesToTextTags(caption.entities)
};
message.action.options = options;
message.action.clearDraft = false;
auto doneCallback = [=] () {
checkAndClose();
};
auto &api = history->session().api();
if (media->poll()) {
const auto poll = *(media->poll());
api.createPoll(
poll,
message.action,
std::move(doneCallback),
nullptr);
} else if (media->geoPoint()) {
const auto location = *(media->geoPoint());
Api::SendLocationPoint(
location,
message.action,
std::move(doneCallback),
nullptr);
} else if (media->sharedContact()) {
const auto contact = media->sharedContact();
api.shareContact(
contact->phoneNumber,
contact->firstName,
contact->lastName,
message.action);
} else if (media->photo()) {
Api::SendExistingPhoto(
std::move(message),
media->photo(),
std::move(doneCallback),
true); // forwarding
} else if (media->document()) {
Api::SendExistingDocument(
std::move(message),
media->document(),
std::move(doneCallback),
true); // forwarding
} else {
Unexpected("Media type in Window::ShowForwardMessagesBox.");
}
const auto inputMedia = media->poll()
? PollDataToInputMedia(media->poll())
: media->geoPoint()
? MTP_inputMediaGeoPoint(
MTP_inputGeoPoint(
MTP_double(media->geoPoint()->lat()),
MTP_double(media->geoPoint()->lon())))
: media->sharedContact()
? MTP_inputMediaContact(
MTP_string(media->sharedContact()->phoneNumber),
MTP_string(media->sharedContact()->firstName),
MTP_string(media->sharedContact()->lastName),
MTPstring())
: media->photo()
? MTP_inputMediaPhoto(MTP_flags(0), media->photo()->mtpInput(), MTPint())
: MTP_inputMediaDocument(MTP_flags(0), media->document()->mtpInput(), MTPint());
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
auto &api = history->session().api();
history->sendRequestId = api.request(MTPmessages_SendMedia(
MTP_flags(newSendFlags),
history->peer->input,
MTPint(),
inputMedia,
MTP_string(caption.text),
rand_value<MTPlong>(),
MTPReplyMarkup(),
sentEntities,
MTP_int(options.scheduled)
)).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
history->session().api().applyUpdates(updates);
checkAndClose(requestId);
finish();
}).fail([=](const RPCError &error) {
finish();
}).afterRequest(history->sendRequestId).send();
return history->sendRequestId;
});
data->requests.insert(history->sendRequestId);
data->requestsLeft++;
};
const auto forwardMessageUnquoted = [&] (not_null<HistoryItem *> item, not_null<History*> history) {
const auto media = item->media();
auto newSendFlags = MTPmessages_SendMessage::Flag(0)
| (!media || !media->webpage()
? MTPmessages_SendMessage::Flag::f_no_webpage
: MTPmessages_SendMessage::Flag(0))
| (options.silent
? MTPmessages_SendMessage::Flag::f_silent
: MTPmessages_SendMessage::Flag(0))
| (options.scheduled
? MTPmessages_SendMessage::Flag::f_schedule_date
: MTPmessages_SendMessage::Flag(0));
const auto webPageId = (!media || !media->webpage())
? CancelledWebPageId
: media->webpage()->id;
const auto sentEntities = Api::EntitiesToMTP(
session,
item->originalText().entities,
Api::ConvertOption::SkipLocal);
if (!sentEntities.v.isEmpty()) {
newSendFlags |= MTPmessages_SendMessage::Flag::f_entities;
}
auto message = ApiWrap::MessageToSend(history);
message.textWithTags = TextWithTags{
item->originalText().text,
TextUtilities::ConvertEntitiesToTextTags(item->originalText().entities)
};
message.action.options = options;
message.action.clearDraft = false;
message.webPageId = webPageId;
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
auto &api = history->session().api();
history->sendRequestId = api.request(MTPmessages_SendMessage(
MTP_flags(newSendFlags),
history->peer->input,
MTPint(),
MTP_string(item->originalText().text),
rand_value<MTPlong>(),
MTPReplyMarkup(),
sentEntities,
MTP_int(options.scheduled)
)).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
history->session().api().applyUpdates(updates);
checkAndClose(requestId);
finish();
}).fail([=](const RPCError &error) {
finish();
}).afterRequest(history->sendRequestId).send();
return history->sendRequestId;
});
data->requests.insert(history->sendRequestId);
history->session().api().sendMessage(
std::move(message),
[=] (const MTPUpdates &result, mtpRequestId requestId) {
checkAndClose();
},
true); // forwarding
data->requestsLeft++;
};
for (const auto peer : result) {