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_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"
|
||||||
#include "data/data_file_origin.h"
|
//#include "data/data_file_origin.h" // included in header
|
||||||
#include "data/data_histories.h"
|
#include "data/data_histories.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/stickers/data_stickers.h"
|
#include "data/stickers/data_stickers.h"
|
||||||
|
|
@ -184,6 +184,166 @@ void SendExistingMedia(
|
||||||
|
|
||||||
} // namespace
|
} // 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(
|
void SendExistingDocument(
|
||||||
Api::MessageToSend &&message,
|
Api::MessageToSend &&message,
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
|
|
||||||
class History;
|
class History;
|
||||||
class PhotoData;
|
class PhotoData;
|
||||||
class DocumentData;
|
class DocumentData;
|
||||||
|
|
@ -25,6 +27,20 @@ namespace Api {
|
||||||
struct MessageToSend;
|
struct MessageToSend;
|
||||||
struct SendAction;
|
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(
|
void SendExistingDocument(
|
||||||
Api::MessageToSend &&message,
|
Api::MessageToSend &&message,
|
||||||
not_null<DocumentData*> document,
|
not_null<DocumentData*> document,
|
||||||
|
|
|
||||||
|
|
@ -3881,168 +3881,42 @@ void ApiWrap::forwardMessagesUnquoted(
|
||||||
++shared->requestsLeft;
|
++shared->requestsLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto medias = std::make_shared<QVector<Data::Media*>>();
|
std::vector<Api::ExistingAlbumItem> items;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
const auto media = item->media();
|
const auto media = item->media();
|
||||||
medias->push_back(media);
|
auto albumItem = Api::ExistingAlbumItem();
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (const auto photo = media->photo()) {
|
if (const auto photo = media->photo()) {
|
||||||
history->addNewLocalMessage(
|
albumItem.photo = photo;
|
||||||
newId.msg,
|
albumItem.inputMedia = MTP_inputMediaPhoto(
|
||||||
msgFlags,
|
MTP_flags(0), photo->mtpInput(), MTPint());
|
||||||
clientFlags,
|
|
||||||
0, // viaBotId
|
|
||||||
0, // replyTo
|
|
||||||
HistoryItem::NewMessageDate(action.options.scheduled),
|
|
||||||
messageFromId,
|
|
||||||
messagePostAuthor,
|
|
||||||
photo,
|
|
||||||
caption,
|
|
||||||
MTPReplyMarkup(),
|
|
||||||
newGroupId);
|
|
||||||
} else if (const auto document = media->document()) {
|
} else if (const auto document = media->document()) {
|
||||||
history->addNewLocalMessage(
|
albumItem.document = document;
|
||||||
newId.msg,
|
albumItem.inputMedia = MTP_inputMediaDocument(
|
||||||
msgFlags,
|
MTP_flags(0), document->mtpInput(), MTPint(), MTPstring());
|
||||||
clientFlags,
|
albumItem.origin = document->stickerOrGifOrigin();
|
||||||
0, // viaBotId
|
|
||||||
0, // replyTo
|
|
||||||
HistoryItem::NewMessageDate(action.options.scheduled),
|
|
||||||
messageFromId,
|
|
||||||
messagePostAuthor,
|
|
||||||
document,
|
|
||||||
caption,
|
|
||||||
MTPReplyMarkup(),
|
|
||||||
newGroupId);
|
|
||||||
}
|
}
|
||||||
|
albumItem.text = cForwardCaptioned()
|
||||||
|
? item->originalText()
|
||||||
|
: TextWithEntities();
|
||||||
|
|
||||||
|
items.push_back(albumItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto finalFlags = MTPmessages_SendMultiMedia::Flags(0)
|
auto doneCallback = [=] () {
|
||||||
| (action.options.silent
|
if (shared && !--shared->requestsLeft) {
|
||||||
? MTPmessages_SendMultiMedia::Flag::f_silent
|
shared->callback();
|
||||||
: 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());
|
|
||||||
}
|
}
|
||||||
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) {
|
const auto forwardMediaUnquoted = [&] (not_null<HistoryItem *> item) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue