Moving to new Api::SendExistingAlbum function
This should reduce complexity of main unquoted forward function and potentially resolve Windows CI faliure.
This commit is contained in:
parent
5654ab6fdf
commit
0aea7e8d75
3 changed files with 202 additions and 152 deletions
|
|
@ -16,7 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_channel.h" // ChannelData::addsSignature.
|
||||
#include "data/data_user.h" // UserData::name
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
//#include "data/data_file_origin.h" // included in header
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/stickers/data_stickers.h"
|
||||
|
|
@ -184,6 +184,166 @@ void SendExistingMedia(
|
|||
|
||||
} // namespace
|
||||
|
||||
void SendExistingAlbum(
|
||||
Api::MessageToSend &&message,
|
||||
std::vector<ExistingAlbumItem> &&items,
|
||||
Fn<void()> doneCallback,
|
||||
bool forwarding) {
|
||||
const auto history = message.action.history;
|
||||
const auto peer = history->peer;
|
||||
const auto session = &history->session();
|
||||
const auto api = &session->api();
|
||||
|
||||
message.action.clearDraft = false;
|
||||
message.action.generateLocal = true;
|
||||
api->sendAction(message.action);
|
||||
|
||||
auto flags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media;
|
||||
auto clientFlags = NewMessageClientFlags();
|
||||
auto sendFlags = MTPmessages_SendMultiMedia::Flags(0);
|
||||
if (message.action.replyTo) {
|
||||
flags |= MTPDmessage::Flag::f_reply_to;
|
||||
sendFlags |= MTPmessages_SendMultiMedia::Flag::f_reply_to_msg_id;
|
||||
}
|
||||
const auto anonymousPost = peer->amAnonymous();
|
||||
const auto silentPost = ShouldSendSilent(peer, message.action.options);
|
||||
InnerFillMessagePostFlags(message.action.options, peer, flags);
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMultiMedia::Flag::f_silent;
|
||||
}
|
||||
auto messageFromId = anonymousPost ? 0 : session->userPeerId();
|
||||
auto messagePostAuthor = peer->isBroadcast() ? session->user()->name : QString();
|
||||
|
||||
const auto replyTo = message.action.replyTo;
|
||||
|
||||
if (message.action.options.scheduled) {
|
||||
flags |= MTPDmessage::Flag::f_from_scheduled;
|
||||
sendFlags |= MTPmessages_SendMultiMedia::Flag::f_schedule_date;
|
||||
} else {
|
||||
clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry;
|
||||
}
|
||||
|
||||
const auto newGroupId = openssl::RandomValue<uint64>();
|
||||
auto mediaInputs = QVector<MTPInputSingleMedia>();
|
||||
mediaInputs.reserve(items.size());
|
||||
|
||||
for (auto i = items.begin(), e = items.end(); i != e; ++i) {
|
||||
auto caption = i->text;
|
||||
TextUtilities::Trim(caption);
|
||||
auto sentEntities = EntitiesToMTP(
|
||||
session,
|
||||
caption.entities,
|
||||
ConvertOption::SkipLocal);
|
||||
|
||||
const auto singleFlags = !sentEntities.v.isEmpty()
|
||||
? MTPDinputSingleMedia::Flag::f_entities
|
||||
: MTPDinputSingleMedia::Flag(0);
|
||||
|
||||
const auto newId = FullMsgId(
|
||||
peerToChannel(peer->id),
|
||||
session->data().nextLocalMessageId());
|
||||
const auto randomId = openssl::RandomValue<uint64>();
|
||||
|
||||
session->data().registerMessageRandomId(randomId, newId);
|
||||
|
||||
if (i->photo) {
|
||||
history->addNewLocalMessage(
|
||||
newId.msg,
|
||||
flags,
|
||||
clientFlags,
|
||||
0,
|
||||
replyTo,
|
||||
HistoryItem::NewMessageDate(message.action.options.scheduled),
|
||||
messageFromId,
|
||||
messagePostAuthor,
|
||||
i->photo,
|
||||
caption,
|
||||
MTPReplyMarkup(),
|
||||
newGroupId);
|
||||
} else if (i->document) {
|
||||
history->addNewLocalMessage(
|
||||
newId.msg,
|
||||
flags,
|
||||
clientFlags,
|
||||
0,
|
||||
replyTo,
|
||||
HistoryItem::NewMessageDate(message.action.options.scheduled),
|
||||
messageFromId,
|
||||
messagePostAuthor,
|
||||
i->document,
|
||||
caption,
|
||||
MTPReplyMarkup(),
|
||||
newGroupId);
|
||||
}
|
||||
|
||||
mediaInputs.push_back(MTP_inputSingleMedia(
|
||||
MTP_flags(singleFlags),
|
||||
i->inputMedia,
|
||||
MTP_long(randomId),
|
||||
MTP_string(caption.text),
|
||||
sentEntities));
|
||||
}
|
||||
|
||||
auto performRequest = [=](const auto &repeatRequest) -> void {
|
||||
auto &histories = history->owner().histories();
|
||||
const auto requestType = Data::Histories::RequestType::Send;
|
||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
||||
history->sendRequestId = api->request(MTPmessages_SendMultiMedia(
|
||||
MTP_flags(sendFlags),
|
||||
peer->input,
|
||||
MTPint(),
|
||||
MTP_vector<MTPInputSingleMedia>(mediaInputs),
|
||||
MTP_int(message.action.options.scheduled)
|
||||
)).done([=](const MTPUpdates &result, mtpRequestId requestId) {
|
||||
api->applyUpdates(result);
|
||||
if (doneCallback) {
|
||||
doneCallback();
|
||||
}
|
||||
finish();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.code() == 400
|
||||
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
|
||||
auto requestsLeft = items.size();
|
||||
auto refreshed = false;
|
||||
for (auto i = items.begin(), e = items.end(); i != e; ++i) {
|
||||
const auto iter = i;
|
||||
const auto usedFileReference = iter->photo
|
||||
? iter->photo->fileReference()
|
||||
: iter->document->fileReference();
|
||||
api->refreshFileReference(i->origin, [=, &requestsLeft, &refreshed](const auto &result) {
|
||||
const auto newFileReference = iter->photo
|
||||
? iter->photo->fileReference()
|
||||
: iter->document->fileReference();
|
||||
|
||||
if (newFileReference != usedFileReference) {
|
||||
refreshed = true;
|
||||
}
|
||||
|
||||
if (--requestsLeft == 0) {
|
||||
if (refreshed) {
|
||||
repeatRequest(repeatRequest);
|
||||
} else {
|
||||
api->sendMessageFail(error, peer);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
api->sendMessageFail(error, peer);
|
||||
}
|
||||
finish();
|
||||
}).afterRequest(history->sendRequestId
|
||||
).send();
|
||||
return history->sendRequestId;
|
||||
});
|
||||
};
|
||||
performRequest(performRequest);
|
||||
|
||||
if (!forwarding) {
|
||||
api->finishForwarding(message.action);
|
||||
}
|
||||
}
|
||||
|
||||
void SendExistingDocument(
|
||||
Api::MessageToSend &&message,
|
||||
not_null<DocumentData*> document,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "data/data_file_origin.h"
|
||||
|
||||
class History;
|
||||
class PhotoData;
|
||||
class DocumentData;
|
||||
|
|
@ -25,6 +27,20 @@ namespace Api {
|
|||
struct MessageToSend;
|
||||
struct SendAction;
|
||||
|
||||
struct ExistingAlbumItem {
|
||||
PhotoData* photo;
|
||||
DocumentData* document;
|
||||
MTPInputMedia inputMedia;
|
||||
Data::FileOrigin origin;
|
||||
TextWithEntities text;
|
||||
};
|
||||
|
||||
void SendExistingAlbum(
|
||||
Api::MessageToSend &&message,
|
||||
std::vector<ExistingAlbumItem> &&items,
|
||||
Fn<void()> doneCallback = nullptr,
|
||||
bool forwarding = false);
|
||||
|
||||
void SendExistingDocument(
|
||||
Api::MessageToSend &&message,
|
||||
not_null<DocumentData*> document,
|
||||
|
|
|
|||
|
|
@ -3881,168 +3881,42 @@ void ApiWrap::forwardMessagesUnquoted(
|
|||
++shared->requestsLeft;
|
||||
}
|
||||
|
||||
const auto medias = std::make_shared<QVector<Data::Media*>>();
|
||||
const auto mediaInputs = std::make_shared<QVector<MTPInputSingleMedia>>();
|
||||
const auto mediaRefs = std::make_shared<QVector<QByteArray>>();
|
||||
mediaInputs->reserve(ids.size());
|
||||
mediaRefs->reserve(ids.size());
|
||||
|
||||
const auto views = 1;
|
||||
const auto forwards = 0;
|
||||
const auto newGroupId = openssl::RandomValue<uint64>();
|
||||
|
||||
auto msgFlags = NewMessageFlags(peer) | MTPDmessage::Flag::f_media;
|
||||
auto clientFlags = NewMessageClientFlags();
|
||||
|
||||
FillMessagePostFlags(action, peer, msgFlags);
|
||||
|
||||
if (action.options.scheduled) {
|
||||
msgFlags |= MTPDmessage::Flag::f_from_scheduled;
|
||||
} else {
|
||||
clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry;
|
||||
}
|
||||
std::vector<Api::ExistingAlbumItem> items;
|
||||
|
||||
for (auto i = fromIter, e = toIter; i != e; i++) {
|
||||
const auto item = *i;
|
||||
const auto media = item->media();
|
||||
medias->push_back(media);
|
||||
|
||||
const auto inputMedia = media->photo()
|
||||
? MTP_inputMediaPhoto(MTP_flags(0), media->photo()->mtpInput(), MTPint())
|
||||
: MTP_inputMediaDocument(MTP_flags(0), media->document()->mtpInput(), MTPint(), MTPstring());
|
||||
auto caption = cForwardCaptioned()
|
||||
? item->originalText()
|
||||
: TextWithEntities();
|
||||
auto sentEntities = Api::EntitiesToMTP(
|
||||
_session,
|
||||
caption.entities,
|
||||
Api::ConvertOption::SkipLocal);
|
||||
|
||||
const auto flags = !sentEntities.v.isEmpty()
|
||||
? MTPDinputSingleMedia::Flag::f_entities
|
||||
: MTPDinputSingleMedia::Flag(0);
|
||||
|
||||
const auto newId = FullMsgId(
|
||||
peerToChannel(peer->id),
|
||||
_session->data().nextLocalMessageId());
|
||||
auto randomId = randomIds.takeFirst();
|
||||
|
||||
mediaInputs->push_back(MTP_inputSingleMedia(
|
||||
MTP_flags(flags),
|
||||
inputMedia,
|
||||
MTP_long(randomId),
|
||||
MTP_string(caption.text),
|
||||
sentEntities));
|
||||
|
||||
_session->data().registerMessageRandomId(randomId, newId);
|
||||
|
||||
auto albumItem = Api::ExistingAlbumItem();
|
||||
if (const auto photo = media->photo()) {
|
||||
history->addNewLocalMessage(
|
||||
newId.msg,
|
||||
msgFlags,
|
||||
clientFlags,
|
||||
0, // viaBotId
|
||||
0, // replyTo
|
||||
HistoryItem::NewMessageDate(action.options.scheduled),
|
||||
messageFromId,
|
||||
messagePostAuthor,
|
||||
photo,
|
||||
caption,
|
||||
MTPReplyMarkup(),
|
||||
newGroupId);
|
||||
albumItem.photo = photo;
|
||||
albumItem.inputMedia = MTP_inputMediaPhoto(
|
||||
MTP_flags(0), photo->mtpInput(), MTPint());
|
||||
} else if (const auto document = media->document()) {
|
||||
history->addNewLocalMessage(
|
||||
newId.msg,
|
||||
msgFlags,
|
||||
clientFlags,
|
||||
0, // viaBotId
|
||||
0, // replyTo
|
||||
HistoryItem::NewMessageDate(action.options.scheduled),
|
||||
messageFromId,
|
||||
messagePostAuthor,
|
||||
document,
|
||||
caption,
|
||||
MTPReplyMarkup(),
|
||||
newGroupId);
|
||||
albumItem.document = document;
|
||||
albumItem.inputMedia = MTP_inputMediaDocument(
|
||||
MTP_flags(0), document->mtpInput(), MTPint(), MTPstring());
|
||||
albumItem.origin = document->stickerOrGifOrigin();
|
||||
}
|
||||
albumItem.text = cForwardCaptioned()
|
||||
? item->originalText()
|
||||
: TextWithEntities();
|
||||
|
||||
items.push_back(albumItem);
|
||||
}
|
||||
|
||||
const auto finalFlags = MTPmessages_SendMultiMedia::Flags(0)
|
||||
| (action.options.silent
|
||||
? MTPmessages_SendMultiMedia::Flag::f_silent
|
||||
: MTPmessages_SendMultiMedia::Flag(0))
|
||||
| (action.options.scheduled
|
||||
? MTPmessages_SendMultiMedia::Flag::f_schedule_date
|
||||
: MTPmessages_SendMultiMedia::Flag(0));
|
||||
|
||||
const auto requestType = Data::Histories::RequestType::Send;
|
||||
auto performRequest = [=, &histories](const auto &repeatRequest) -> void {
|
||||
mediaRefs->clear();
|
||||
for (auto i = medias->begin(), e = medias->end(); i != e; i++) {
|
||||
const auto media = *i;
|
||||
mediaRefs->push_back(media->photo()
|
||||
? media->photo()->fileReference()
|
||||
: media->document()->fileReference());
|
||||
auto doneCallback = [=] () {
|
||||
if (shared && !--shared->requestsLeft) {
|
||||
shared->callback();
|
||||
}
|
||||
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
|
||||
history->sendRequestId = request(MTPmessages_SendMultiMedia(
|
||||
MTP_flags(finalFlags),
|
||||
peer->input,
|
||||
MTPint(),
|
||||
MTP_vector<MTPInputSingleMedia>(*mediaInputs),
|
||||
MTP_int(action.options.scheduled)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
if (shared && !--shared->requestsLeft) {
|
||||
shared->callback();
|
||||
}
|
||||
finish();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
if (error.code() == 400
|
||||
&& error.type().startsWith(qstr("FILE_REFERENCE_"))) {
|
||||
auto refreshRequests = mediaRefs->size();
|
||||
auto index = 0;
|
||||
auto wasUpdated = false;
|
||||
for (auto i = medias->begin(), e = medias->end(); i != e; i++) {
|
||||
const auto media = *i;
|
||||
const auto origin = media->document()
|
||||
? media->document()->stickerOrGifOrigin()
|
||||
: Data::FileOrigin();
|
||||
const auto usedFileReference = mediaRefs->value(index);
|
||||
|
||||
refreshFileReference(origin, [=, &refreshRequests, &wasUpdated](const auto &result) {
|
||||
const auto currentMediaReference = media->photo()
|
||||
? media->photo()->fileReference()
|
||||
: media->document()->fileReference();
|
||||
|
||||
if (currentMediaReference != usedFileReference) {
|
||||
wasUpdated = true;
|
||||
}
|
||||
|
||||
if (refreshRequests > 0) {
|
||||
refreshRequests--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (wasUpdated) {
|
||||
repeatRequest(repeatRequest);
|
||||
} else {
|
||||
sendMessageFail(error, peer);
|
||||
}
|
||||
});
|
||||
index++;
|
||||
}
|
||||
} else {
|
||||
sendMessageFail(error, peer);
|
||||
}
|
||||
finish();
|
||||
}).afterRequest(
|
||||
history->sendRequestId
|
||||
).send();
|
||||
return history->sendRequestId;
|
||||
});
|
||||
};
|
||||
performRequest(performRequest);
|
||||
|
||||
auto message = ApiWrap::MessageToSend(history);
|
||||
|
||||
Api::SendExistingAlbum(
|
||||
std::move(message),
|
||||
std::move(items),
|
||||
std::move(doneCallback),
|
||||
true); // forwarding
|
||||
};
|
||||
|
||||
const auto forwardMediaUnquoted = [&] (not_null<HistoryItem *> item) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue