Reuse sending APIs and try to fix media references
This commit is contained in:
parent
23c8792935
commit
eeaa4923a4
5 changed files with 404 additions and 292 deletions
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
|
#include "data/data_location.h"
|
||||||
#include "data/data_channel.h" // ChannelData::addsSignature.
|
#include "data/data_channel.h" // ChannelData::addsSignature.
|
||||||
#include "data/data_user.h" // UserData::name
|
#include "data/data_user.h" // UserData::name
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
|
@ -62,7 +63,9 @@ void SendExistingMedia(
|
||||||
Api::MessageToSend &&message,
|
Api::MessageToSend &&message,
|
||||||
not_null<MediaData*> media,
|
not_null<MediaData*> media,
|
||||||
Fn<MTPInputMedia()> inputMedia,
|
Fn<MTPInputMedia()> inputMedia,
|
||||||
Data::FileOrigin origin) {
|
Data::FileOrigin origin,
|
||||||
|
Fn<void()> doneCallback = nullptr,
|
||||||
|
bool forwarding = false) {
|
||||||
const auto history = message.action.history;
|
const auto history = message.action.history;
|
||||||
const auto peer = history->peer;
|
const auto peer = history->peer;
|
||||||
const auto session = &history->session();
|
const auto session = &history->session();
|
||||||
|
|
@ -135,7 +138,6 @@ void SendExistingMedia(
|
||||||
auto &histories = history->owner().histories();
|
auto &histories = history->owner().histories();
|
||||||
const auto requestType = Data::Histories::RequestType::Send;
|
const auto requestType = Data::Histories::RequestType::Send;
|
||||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
||||||
const auto usedFileReference = media->fileReference();
|
|
||||||
history->sendRequestId = api->request(MTPmessages_SendMedia(
|
history->sendRequestId = api->request(MTPmessages_SendMedia(
|
||||||
MTP_flags(sendFlags),
|
MTP_flags(sendFlags),
|
||||||
peer->input,
|
peer->input,
|
||||||
|
|
@ -146,12 +148,16 @@ void SendExistingMedia(
|
||||||
MTPReplyMarkup(),
|
MTPReplyMarkup(),
|
||||||
sentEntities,
|
sentEntities,
|
||||||
MTP_int(message.action.options.scheduled)
|
MTP_int(message.action.options.scheduled)
|
||||||
)).done([=](const MTPUpdates &result) {
|
)).done([=](const MTPUpdates &result, mtpRequestId requestId) {
|
||||||
api->applyUpdates(result, randomId);
|
api->applyUpdates(result, randomId);
|
||||||
|
if (doneCallback) {
|
||||||
|
doneCallback();
|
||||||
|
}
|
||||||
finish();
|
finish();
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](const RPCError &error) {
|
||||||
if (error.code() == 400
|
if (error.code() == 400
|
||||||
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
|
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
|
||||||
|
const auto usedFileReference = media->fileReference();
|
||||||
api->refreshFileReference(origin, [=](const auto &result) {
|
api->refreshFileReference(origin, [=](const auto &result) {
|
||||||
if (media->fileReference() != usedFileReference) {
|
if (media->fileReference() != usedFileReference) {
|
||||||
repeatRequest(repeatRequest);
|
repeatRequest(repeatRequest);
|
||||||
|
|
@ -170,14 +176,18 @@ void SendExistingMedia(
|
||||||
};
|
};
|
||||||
performRequest(performRequest);
|
performRequest(performRequest);
|
||||||
|
|
||||||
api->finishForwarding(message.action);
|
if (!forwarding) {
|
||||||
|
api->finishForwarding(message.action);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void SendExistingDocument(
|
void SendExistingDocument(
|
||||||
Api::MessageToSend &&message,
|
Api::MessageToSend &&message,
|
||||||
not_null<DocumentData*> document) {
|
not_null<DocumentData*> document,
|
||||||
|
Fn<void()> doneCallback,
|
||||||
|
bool forwarding) {
|
||||||
const auto inputMedia = [=] {
|
const auto inputMedia = [=] {
|
||||||
return MTP_inputMediaDocument(
|
return MTP_inputMediaDocument(
|
||||||
MTP_flags(0),
|
MTP_flags(0),
|
||||||
|
|
@ -188,7 +198,9 @@ void SendExistingDocument(
|
||||||
std::move(message),
|
std::move(message),
|
||||||
document,
|
document,
|
||||||
inputMedia,
|
inputMedia,
|
||||||
document->stickerOrGifOrigin());
|
document->stickerOrGifOrigin(),
|
||||||
|
(doneCallback ? std::move(doneCallback) : nullptr),
|
||||||
|
forwarding);
|
||||||
|
|
||||||
if (document->sticker()) {
|
if (document->sticker()) {
|
||||||
document->owner().stickers().incrementSticker(document);
|
document->owner().stickers().incrementSticker(document);
|
||||||
|
|
@ -197,7 +209,9 @@ void SendExistingDocument(
|
||||||
|
|
||||||
void SendExistingPhoto(
|
void SendExistingPhoto(
|
||||||
Api::MessageToSend &&message,
|
Api::MessageToSend &&message,
|
||||||
not_null<PhotoData*> photo) {
|
not_null<PhotoData*> photo,
|
||||||
|
Fn<void()> doneCallback,
|
||||||
|
bool forwarding) {
|
||||||
const auto inputMedia = [=] {
|
const auto inputMedia = [=] {
|
||||||
return MTP_inputMediaPhoto(
|
return MTP_inputMediaPhoto(
|
||||||
MTP_flags(0),
|
MTP_flags(0),
|
||||||
|
|
@ -208,7 +222,9 @@ void SendExistingPhoto(
|
||||||
std::move(message),
|
std::move(message),
|
||||||
photo,
|
photo,
|
||||||
inputMedia,
|
inputMedia,
|
||||||
Data::FileOrigin());
|
Data::FileOrigin(),
|
||||||
|
(doneCallback ? std::move(doneCallback) : nullptr),
|
||||||
|
forwarding);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendDice(Api::MessageToSend &message) {
|
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
|
} // namespace Api
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ class History;
|
||||||
class PhotoData;
|
class PhotoData;
|
||||||
class DocumentData;
|
class DocumentData;
|
||||||
struct FileLoadResult;
|
struct FileLoadResult;
|
||||||
|
class RPCError;
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
class LocationPoint;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
namespace Api {
|
namespace Api {
|
||||||
|
|
||||||
|
|
@ -19,11 +24,15 @@ struct SendAction;
|
||||||
|
|
||||||
void SendExistingDocument(
|
void SendExistingDocument(
|
||||||
Api::MessageToSend &&message,
|
Api::MessageToSend &&message,
|
||||||
not_null<DocumentData*> document);
|
not_null<DocumentData*> document,
|
||||||
|
Fn<void()> doneCallback = nullptr,
|
||||||
|
bool forwarding = false);
|
||||||
|
|
||||||
void SendExistingPhoto(
|
void SendExistingPhoto(
|
||||||
Api::MessageToSend &&message,
|
Api::MessageToSend &&message,
|
||||||
not_null<PhotoData*> photo);
|
not_null<PhotoData*> photo,
|
||||||
|
Fn<void()> doneCallback = nullptr,
|
||||||
|
bool forwarding = false);
|
||||||
|
|
||||||
bool SendDice(Api::MessageToSend &message);
|
bool SendDice(Api::MessageToSend &message);
|
||||||
|
|
||||||
|
|
@ -37,4 +46,10 @@ void SendConfirmedFile(
|
||||||
const std::shared_ptr<FileLoadResult> &file,
|
const std::shared_ptr<FileLoadResult> &file,
|
||||||
const std::optional<FullMsgId> &oldId);
|
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
|
} // namespace Api
|
||||||
|
|
|
||||||
|
|
@ -4086,7 +4086,9 @@ void ApiWrap::forwardMessages(
|
||||||
++shared->requestsLeft;
|
++shared->requestsLeft;
|
||||||
}
|
}
|
||||||
auto medias = QVector<MTPInputSingleMedia>();
|
auto medias = QVector<MTPInputSingleMedia>();
|
||||||
|
auto mediaRefs = QVector<QByteArray>();
|
||||||
medias.reserve(ids.size());
|
medias.reserve(ids.size());
|
||||||
|
mediaRefs.reserve(ids.size());
|
||||||
|
|
||||||
for (auto i = fromIter, e = toIter; i != e; i++) {
|
for (auto i = fromIter, e = toIter; i != e; i++) {
|
||||||
const auto item = *i;
|
const auto item = *i;
|
||||||
|
|
@ -4125,33 +4127,74 @@ void ApiWrap::forwardMessages(
|
||||||
: MTPmessages_SendMultiMedia::Flag(0));
|
: MTPmessages_SendMultiMedia::Flag(0));
|
||||||
|
|
||||||
const auto requestType = Data::Histories::RequestType::Send;
|
const auto requestType = Data::Histories::RequestType::Send;
|
||||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
auto performRequest = [=, &mediaRefs, &histories](const auto &repeatRequest) -> void {
|
||||||
history->sendRequestId = request(MTPmessages_SendMultiMedia(
|
mediaRefs.clear();
|
||||||
MTP_flags(finalFlags),
|
for (auto i = fromIter, e = toIter; i != e; i++) {
|
||||||
peer->input,
|
const auto item = *i;
|
||||||
MTPint(),
|
const auto media = item->media();
|
||||||
MTP_vector<MTPInputSingleMedia>(medias),
|
mediaRefs.push_back(media->photo()
|
||||||
MTP_int(action.options.scheduled)
|
? media->photo()->fileReference()
|
||||||
)).done([=](const MTPUpdates &result) {
|
: media->document()->fileReference());
|
||||||
applyUpdates(result);
|
}
|
||||||
if (shared && !--shared->requestsLeft) {
|
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
||||||
shared->callback();
|
history->sendRequestId = request(MTPmessages_SendMultiMedia(
|
||||||
}
|
MTP_flags(finalFlags),
|
||||||
finish();
|
peer->input,
|
||||||
}).fail([=, ids = localIds](const RPCError &error) {
|
MTPint(),
|
||||||
if (ids) {
|
MTP_vector<MTPInputSingleMedia>(medias),
|
||||||
for (const auto &[randomId, itemId] : *ids) {
|
MTP_int(action.options.scheduled)
|
||||||
sendMessageFail(error, peer, randomId, itemId);
|
)).done([=](const MTPUpdates &result) {
|
||||||
|
applyUpdates(result);
|
||||||
|
if (shared && !--shared->requestsLeft) {
|
||||||
|
shared->callback();
|
||||||
}
|
}
|
||||||
} else {
|
finish();
|
||||||
sendMessageFail(error, peer);
|
}).fail([=, ids = localIds](const RPCError &error) {
|
||||||
}
|
if (error.code() == 400
|
||||||
finish();
|
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
|
||||||
}).afterRequest(
|
auto refreshRequests = mediaRefs.size();
|
||||||
history->sendRequestId
|
auto index = 0;
|
||||||
).send();
|
for (auto i = fromIter, e = toIter; i != e; i++) {
|
||||||
return history->sendRequestId;
|
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) {
|
const auto forwardMediaUnquoted = [&] (not_null<HistoryItem *> item) {
|
||||||
|
|
@ -4160,86 +4203,62 @@ void ApiWrap::forwardMessages(
|
||||||
}
|
}
|
||||||
const auto media = item->media();
|
const auto media = item->media();
|
||||||
|
|
||||||
auto newSendFlags = MTPmessages_SendMedia::Flags(0)
|
auto message = ApiWrap::MessageToSend(history);
|
||||||
| (action.options.silent
|
const auto caption = (cForwardCaptioned()
|
||||||
? MTPmessages_SendMedia::Flag::f_silent
|
&& !media->geoPoint()
|
||||||
: MTPmessages_SendMedia::Flag(0))
|
&& !media->sharedContact())
|
||||||
| (action.options.scheduled
|
? item->originalText()
|
||||||
? MTPmessages_SendMedia::Flag::f_schedule_date
|
: TextWithEntities();
|
||||||
: MTPmessages_SendMedia::Flag(0));
|
|
||||||
|
|
||||||
auto caption = (cForwardCaptioned()
|
message.textWithTags = TextWithTags{
|
||||||
&& !media->geoPoint()
|
caption.text,
|
||||||
&& !media->sharedContact())
|
TextUtilities::ConvertEntitiesToTextTags(caption.entities)
|
||||||
? item->originalText()
|
};
|
||||||
: TextWithEntities();
|
message.action.options = action.options;
|
||||||
|
message.action.clearDraft = false;
|
||||||
|
|
||||||
auto sentEntities = Api::EntitiesToMTP(
|
auto doneCallback = [=] () {
|
||||||
_session,
|
if (shared && !--shared->requestsLeft) {
|
||||||
caption.entities,
|
shared->callback();
|
||||||
Api::ConvertOption::SkipLocal);
|
}
|
||||||
if (!sentEntities.v.isEmpty()) {
|
};
|
||||||
newSendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
|
||||||
|
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) {
|
const auto forwardMessageUnquoted = [&] (not_null<HistoryItem *> item) {
|
||||||
|
|
@ -4248,65 +4267,27 @@ void ApiWrap::forwardMessages(
|
||||||
}
|
}
|
||||||
const auto media = item->media();
|
const auto media = item->media();
|
||||||
|
|
||||||
auto newSendFlags = MTPmessages_SendMessage::Flag(0)
|
const auto webPageId = (!media || !media->webpage())
|
||||||
| (!media || !media->webpage()
|
? CancelledWebPageId
|
||||||
? MTPmessages_SendMessage::Flag::f_no_webpage
|
: media->webpage()->id;
|
||||||
: 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));
|
|
||||||
|
|
||||||
auto sentEntities = Api::EntitiesToMTP(
|
auto message = ApiWrap::MessageToSend(history);
|
||||||
_session,
|
message.textWithTags = TextWithTags{
|
||||||
item->originalText().entities,
|
item->originalText().text,
|
||||||
Api::ConvertOption::SkipLocal);
|
TextUtilities::ConvertEntitiesToTextTags(item->originalText().entities)
|
||||||
if (!sentEntities.v.isEmpty()) {
|
};
|
||||||
newSendFlags |= MTPmessages_SendMessage::Flag::f_entities;
|
message.action.options = action.options;
|
||||||
}
|
message.action.clearDraft = false;
|
||||||
|
message.webPageId = webPageId;
|
||||||
|
|
||||||
const auto requestType = Data::Histories::RequestType::Send;
|
session().api().sendMessage(
|
||||||
const auto currentRandomId = randomIds.takeFirst();
|
std::move(message),
|
||||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
[=] (const MTPUpdates &result, mtpRequestId requestId) {
|
||||||
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);
|
|
||||||
if (shared && !--shared->requestsLeft) {
|
if (shared && !--shared->requestsLeft) {
|
||||||
shared->callback();
|
shared->callback();
|
||||||
}
|
}
|
||||||
finish();
|
},
|
||||||
}).fail([=, ids = localIds](const RPCError &error) {
|
true); // forwarding
|
||||||
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 sendAccumulated = [&] {
|
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 history = message.action.history;
|
||||||
const auto peer = history->peer;
|
const auto peer = history->peer;
|
||||||
auto &textWithTags = message.textWithTags;
|
auto &textWithTags = message.textWithTags;
|
||||||
|
|
@ -4779,9 +4763,12 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
MTPReplyMarkup(),
|
MTPReplyMarkup(),
|
||||||
sentEntities,
|
sentEntities,
|
||||||
MTP_int(action.options.scheduled)
|
MTP_int(action.options.scheduled)
|
||||||
)).done([=](const MTPUpdates &result) {
|
)).done([=](const MTPUpdates &result, mtpRequestId requestId) {
|
||||||
applyUpdates(result, randomId);
|
applyUpdates(result, randomId);
|
||||||
history->clearSentDraftText(QString());
|
history->clearSentDraftText(QString());
|
||||||
|
if (doneCallback) {
|
||||||
|
doneCallback(result, requestId);
|
||||||
|
}
|
||||||
finish();
|
finish();
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](const RPCError &error) {
|
||||||
if (error.type() == qstr("MESSAGE_EMPTY")) {
|
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) {
|
void ApiWrap::sendBotStart(not_null<UserData*> bot, PeerData *chat) {
|
||||||
|
|
@ -5621,7 +5610,9 @@ void ApiWrap::createPoll(
|
||||||
done();
|
done();
|
||||||
finish();
|
finish();
|
||||||
}).fail([=](const RPCError &error) mutable {
|
}).fail([=](const RPCError &error) mutable {
|
||||||
fail(error);
|
if (fail) {
|
||||||
|
fail(error);
|
||||||
|
}
|
||||||
finish();
|
finish();
|
||||||
}).afterRequest(history->sendRequestId
|
}).afterRequest(history->sendRequestId
|
||||||
).send();
|
).send();
|
||||||
|
|
|
||||||
|
|
@ -421,7 +421,10 @@ public:
|
||||||
|
|
||||||
void cancelLocalItem(not_null<HistoryItem*> item);
|
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 sendBotStart(not_null<UserData*> bot, PeerData *chat = nullptr);
|
||||||
void sendInlineResult(
|
void sendInlineResult(
|
||||||
not_null<UserData*> bot,
|
not_null<UserData*> bot,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
|
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
#include "api/api_sending.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "boxes/mute_settings_box.h"
|
#include "boxes/mute_settings_box.h"
|
||||||
#include "boxes/add_contact_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_drafts.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_game.h"
|
#include "data/data_game.h"
|
||||||
|
#include "data/data_web_page.h"
|
||||||
#include "data/data_scheduled_messages.h"
|
#include "data/data_scheduled_messages.h"
|
||||||
#include "data/data_histories.h"
|
#include "data/data_histories.h"
|
||||||
#include "data/data_chat_filters.h"
|
#include "data/data_chat_filters.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "dialogs/dialogs_key.h"
|
#include "dialogs/dialogs_key.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "export/export_manager.h"
|
#include "export/export_manager.h"
|
||||||
|
|
@ -1116,7 +1119,7 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
}
|
}
|
||||||
not_null<PeerData*> peer;
|
not_null<PeerData*> peer;
|
||||||
MessageIdsList msgIds;
|
MessageIdsList msgIds;
|
||||||
base::flat_set<mtpRequestId> requests;
|
int requestsLeft = 0;
|
||||||
FnMut<void()> submitCallback;
|
FnMut<void()> submitCallback;
|
||||||
};
|
};
|
||||||
struct MsgIdsGroup {
|
struct MsgIdsGroup {
|
||||||
|
|
@ -1188,7 +1191,7 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
std::vector<not_null<PeerData*>> &&result,
|
std::vector<not_null<PeerData*>> &&result,
|
||||||
TextWithTags &&comment,
|
TextWithTags &&comment,
|
||||||
Api::SendOptions options) {
|
Api::SendOptions options) {
|
||||||
if (!data->requests.empty()) {
|
if (data->requestsLeft > 0) {
|
||||||
return; // Share clicked already.
|
return; // Share clicked already.
|
||||||
}
|
}
|
||||||
auto items = history->owner().idsToItems(data->msgIds);
|
auto items = history->owner().idsToItems(data->msgIds);
|
||||||
|
|
@ -1278,9 +1281,9 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
const auto checkAndClose = [=] (mtpRequestId requestId) {
|
const auto checkAndClose = [=] {
|
||||||
data->requests.remove(requestId);
|
data->requestsLeft--;
|
||||||
if (data->requests.empty()) {
|
if (!data->requestsLeft) {
|
||||||
Ui::Toast::Show(tr::lng_share_done(tr::now));
|
Ui::Toast::Show(tr::lng_share_done(tr::now));
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
}
|
}
|
||||||
|
|
@ -1304,19 +1307,21 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
MTP_int(options.scheduled)
|
MTP_int(options.scheduled)
|
||||||
)).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
|
)).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
|
||||||
history->session().api().applyUpdates(updates);
|
history->session().api().applyUpdates(updates);
|
||||||
checkAndClose(requestId);
|
checkAndClose();
|
||||||
finish();
|
finish();
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](const RPCError &error) {
|
||||||
finish();
|
finish();
|
||||||
}).afterRequest(history->sendRequestId).send();
|
}).afterRequest(history->sendRequestId).send();
|
||||||
return history->sendRequestId;
|
return history->sendRequestId;
|
||||||
});
|
});
|
||||||
data->requests.insert(history->sendRequestId);
|
data->requestsLeft++;
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto forwardAlbumUnquoted = [&] (MsgIdsGroup &&group, not_null<History*> history) {
|
const auto forwardAlbumUnquoted = [&] (MsgIdsGroup &&group, not_null<History*> history) {
|
||||||
auto medias = QVector<MTPInputSingleMedia>();
|
auto medias = QVector<MTPInputSingleMedia>();
|
||||||
|
auto mediaRefs = QVector<QByteArray>();
|
||||||
medias.reserve(group.items.size());
|
medias.reserve(group.items.size());
|
||||||
|
mediaRefs.reserve(group.items.size());
|
||||||
|
|
||||||
auto randomIds = generateRandom(group.items.size());
|
auto randomIds = generateRandom(group.items.size());
|
||||||
|
|
||||||
|
|
@ -1345,6 +1350,9 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
randomId,
|
randomId,
|
||||||
MTP_string(caption.text),
|
MTP_string(caption.text),
|
||||||
sentEntities));
|
sentEntities));
|
||||||
|
mediaRefs.push_back(media->photo()
|
||||||
|
? media->photo()->fileReference()
|
||||||
|
: media->document()->fileReference());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto flags = MTPmessages_SendMultiMedia::Flags(0)
|
const auto flags = MTPmessages_SendMultiMedia::Flags(0)
|
||||||
|
|
@ -1355,135 +1363,154 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
? MTPmessages_SendMultiMedia::Flag::f_schedule_date
|
? MTPmessages_SendMultiMedia::Flag::f_schedule_date
|
||||||
: MTPmessages_SendMultiMedia::Flag(0));
|
: MTPmessages_SendMultiMedia::Flag(0));
|
||||||
|
|
||||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
auto performRequest = [=, &mediaRefs, &histories](const auto &repeatRequest) -> void {
|
||||||
auto &api = history->session().api();
|
mediaRefs.clear();
|
||||||
history->sendRequestId = api.request(MTPmessages_SendMultiMedia(
|
for (const auto item : group.items) {
|
||||||
MTP_flags(flags),
|
const auto media = item->media();
|
||||||
history->peer->input,
|
mediaRefs.push_back(media->photo()
|
||||||
MTPint(),
|
? media->photo()->fileReference()
|
||||||
MTP_vector<MTPInputSingleMedia>(medias),
|
: media->document()->fileReference());
|
||||||
MTP_int(options.scheduled)
|
}
|
||||||
)).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
|
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
||||||
history->session().api().applyUpdates(updates);
|
auto &api = history->session().api();
|
||||||
checkAndClose(requestId);
|
history->sendRequestId = api.request(MTPmessages_SendMultiMedia(
|
||||||
finish();
|
MTP_flags(flags),
|
||||||
}).fail([=](const RPCError &error) {
|
history->peer->input,
|
||||||
finish();
|
MTPint(),
|
||||||
}).afterRequest(history->sendRequestId).send();
|
MTP_vector<MTPInputSingleMedia>(medias),
|
||||||
return history->sendRequestId;
|
MTP_int(options.scheduled)
|
||||||
});
|
)).done([=](const MTPUpdates &updates, mtpRequestId requestId) {
|
||||||
data->requests.insert(history->sendRequestId);
|
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 forwardMediaUnquoted = [&] (not_null<HistoryItem *> item, not_null<History*> history) {
|
||||||
const auto media = item->media();
|
const auto media = item->media();
|
||||||
|
|
||||||
auto newSendFlags = MTPmessages_SendMedia::Flags(0)
|
auto message = ApiWrap::MessageToSend(history);
|
||||||
| (options.silent
|
|
||||||
? MTPmessages_SendMedia::Flag::f_silent
|
|
||||||
: MTPmessages_SendMedia::Flag(0))
|
|
||||||
| (options.scheduled
|
|
||||||
? MTPmessages_SendMedia::Flag::f_schedule_date
|
|
||||||
: MTPmessages_SendMedia::Flag(0));
|
|
||||||
|
|
||||||
const auto caption = (cForwardCaptioned()
|
const auto caption = (cForwardCaptioned()
|
||||||
&& !media->geoPoint()
|
&& !media->geoPoint()
|
||||||
&& !media->sharedContact())
|
&& !media->sharedContact())
|
||||||
? item->originalText()
|
? item->originalText()
|
||||||
: TextWithEntities();
|
: TextWithEntities();
|
||||||
|
|
||||||
const auto sentEntities = Api::EntitiesToMTP(
|
message.textWithTags = TextWithTags{
|
||||||
session,
|
caption.text,
|
||||||
caption.entities,
|
TextUtilities::ConvertEntitiesToTextTags(caption.entities)
|
||||||
Api::ConvertOption::SkipLocal);
|
};
|
||||||
if (!sentEntities.v.isEmpty()) {
|
message.action.options = options;
|
||||||
newSendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
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()
|
data->requestsLeft++;
|
||||||
? 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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto forwardMessageUnquoted = [&] (not_null<HistoryItem *> item, not_null<History*> history) {
|
const auto forwardMessageUnquoted = [&] (not_null<HistoryItem *> item, not_null<History*> history) {
|
||||||
const auto media = item->media();
|
const auto media = item->media();
|
||||||
|
|
||||||
auto newSendFlags = MTPmessages_SendMessage::Flag(0)
|
const auto webPageId = (!media || !media->webpage())
|
||||||
| (!media || !media->webpage()
|
? CancelledWebPageId
|
||||||
? MTPmessages_SendMessage::Flag::f_no_webpage
|
: media->webpage()->id;
|
||||||
: 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 sentEntities = Api::EntitiesToMTP(
|
auto message = ApiWrap::MessageToSend(history);
|
||||||
session,
|
message.textWithTags = TextWithTags{
|
||||||
item->originalText().entities,
|
item->originalText().text,
|
||||||
Api::ConvertOption::SkipLocal);
|
TextUtilities::ConvertEntitiesToTextTags(item->originalText().entities)
|
||||||
if (!sentEntities.v.isEmpty()) {
|
};
|
||||||
newSendFlags |= MTPmessages_SendMessage::Flag::f_entities;
|
message.action.options = options;
|
||||||
}
|
message.action.clearDraft = false;
|
||||||
|
message.webPageId = webPageId;
|
||||||
|
|
||||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
history->session().api().sendMessage(
|
||||||
auto &api = history->session().api();
|
std::move(message),
|
||||||
history->sendRequestId = api.request(MTPmessages_SendMessage(
|
[=] (const MTPUpdates &result, mtpRequestId requestId) {
|
||||||
MTP_flags(newSendFlags),
|
checkAndClose();
|
||||||
history->peer->input,
|
},
|
||||||
MTPint(),
|
true); // forwarding
|
||||||
MTP_string(item->originalText().text),
|
|
||||||
rand_value<MTPlong>(),
|
data->requestsLeft++;
|
||||||
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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto peer : result) {
|
for (const auto peer : result) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue