Forward messages to Saved Messages instantly.

This commit is contained in:
John Preston 2017-12-06 17:56:40 +04:00
parent 6764a3cc86
commit 1473c14668
5 changed files with 141 additions and 54 deletions

View File

@ -2387,4 +2387,110 @@ void ApiWrap::userPhotosDone(
));
}
void ApiWrap::forwardMessages(
HistoryItemsList &&items,
const SendOptions &options,
base::lambda_once<void()> &&successCallback) {
Expects(!items.empty());
struct SharedCallback {
int requestsLeft = 0;
base::lambda_once<void()> callback;
};
const auto shared = successCallback
? std::make_shared<SharedCallback>()
: std::shared_ptr<SharedCallback>();
if (successCallback) {
shared->callback = std::move(successCallback);
}
const auto count = int(items.size());
const auto genClientSideMessage = options.generateLocal && (count < 2);
const auto history = options.history;
App::main()->readServerHistory(history);
const auto channelPost = history->peer->isChannel()
&& !history->peer->isMegagroup();
const auto silentPost = channelPost && options.silent;
auto flags = MTPDmessage::Flags(0);
auto sendFlags = MTPmessages_ForwardMessages::Flags(0);
if (channelPost) {
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (!channelPost) {
flags |= MTPDmessage::Flag::f_from_id;
} else if (history->peer->asChannel()->addsSignature()) {
flags |= MTPDmessage::Flag::f_post_author;
}
if (silentPost) {
sendFlags |= MTPmessages_ForwardMessages::Flag::f_silent;
}
auto forwardFrom = items.front()->history()->peer;
auto ids = QVector<MTPint>();
auto randomIds = QVector<MTPlong>();
const auto sendAccumulated = [&] {
if (shared) {
++shared->requestsLeft;
}
history->sendRequestId = request(MTPmessages_ForwardMessages(
MTP_flags(sendFlags),
forwardFrom->input,
MTP_vector<MTPint>(ids),
MTP_vector<MTPlong>(randomIds),
history->peer->input
)).done([=, callback = std::move(successCallback)](
const MTPUpdates &updates) {
applyUpdates(updates);
if (shared && !--shared->requestsLeft) {
shared->callback();
}
}).after(
history->sendRequestId
).send();
ids.resize(0);
randomIds.resize(0);
};
ids.reserve(count);
randomIds.reserve(count);
for (const auto item : items) {
auto randomId = rand_value<uint64>();
if (genClientSideMessage) {
if (auto message = item->toHistoryMessage()) {
const auto newId = FullMsgId(
peerToChannel(history->peer->id),
clientMsgId());
const auto self = Auth().user();
const auto messageFromId = channelPost
? UserId(0)
: peerToUser(self->id);
const auto messagePostAuthor = channelPost
? (self->firstName + ' ' + self->lastName)
: QString();
history->addNewForwarded(
newId.msg,
flags,
date(MTP_int(unixtime())),
messageFromId,
messagePostAuthor,
message);
App::historyRegRandom(randomId, newId);
}
}
if (forwardFrom != item->history()->peer) {
sendAccumulated();
forwardFrom = item->history()->peer;
}
ids.push_back(MTP_int(item->id));
randomIds.push_back(MTP_long(randomId));
}
sendAccumulated();
}
ApiWrap::~ApiWrap() = default;

View File

@ -159,6 +159,22 @@ public:
const QVector<MTPChannelParticipant> &list)> callbackList,
base::lambda<void()> callbackNotModified = nullptr);
struct SendOptions {
SendOptions(not_null<History*> history) : history(history) {
}
not_null<History*> history;
MsgId replyTo = 0;
bool silent = false;
WebPageId webPageId = 0;
bool clearDraft = true;
bool generateLocal = true;
};
void forwardMessages(
HistoryItemsList &&items,
const SendOptions &options,
base::lambda_once<void()> &&successCallback = nullptr);
~ApiWrap();
private:

View File

@ -6168,7 +6168,12 @@ void HistoryWidget::handlePeerUpdate() {
void HistoryWidget::onForwardSelected() {
if (!_list) return;
Window::ShowForwardMessagesBox(getSelectedItems());
auto weak = make_weak(this);
Window::ShowForwardMessagesBox(getSelectedItems(), [=] {
if (weak) {
weak->onClearSelected();
}
});
}
void HistoryWidget::confirmDeleteContextItem() {

View File

@ -662,7 +662,6 @@ bool MainWidget::setForwardDraft(PeerId peerId, MessageIdsList &&items) {
if (_history->peer() == peer) {
_history->cancelReply();
}
_history->onClearSelected();
Ui::showPeerHistory(peer, ShowAtUnreadMsgId);
return true;
}
@ -724,61 +723,15 @@ void MainWidget::cancelForwarding(History *history) {
void MainWidget::finishForwarding(History *history, bool silent) {
if (!history) return;
const auto toForward = history->validateForwardDraft();
if (const auto count = int(toForward.size())) {
auto genClientSideMessage = (count < 2);
PeerData *forwardFrom = 0;
App::main()->readServerHistory(history);
auto flags = MTPDmessage::Flags(0);
auto sendFlags = MTPmessages_ForwardMessages::Flags(0);
bool channelPost = history->peer->isChannel() && !history->peer->isMegagroup();
bool silentPost = channelPost && silent;
if (channelPost) {
flags |= MTPDmessage::Flag::f_views;
flags |= MTPDmessage::Flag::f_post;
}
if (!channelPost) {
flags |= MTPDmessage::Flag::f_from_id;
} else if (history->peer->asChannel()->addsSignature()) {
flags |= MTPDmessage::Flag::f_post_author;
}
if (silentPost) {
sendFlags |= MTPmessages_ForwardMessages::Flag::f_silent;
}
QVector<MTPint> ids;
QVector<MTPlong> randomIds;
ids.reserve(count);
randomIds.reserve(count);
for (const auto item : toForward) {
auto randomId = rand_value<uint64>();
if (genClientSideMessage) {
if (auto message = item->toHistoryMessage()) {
auto newId = FullMsgId(peerToChannel(history->peer->id), clientMsgId());
auto messageFromId = channelPost ? 0 : Auth().userId();
auto messagePostAuthor = channelPost ? (Auth().user()->firstName + ' ' + Auth().user()->lastName) : QString();
history->addNewForwarded(newId.msg, flags, date(MTP_int(unixtime())), messageFromId, messagePostAuthor, message);
App::historyRegRandom(randomId, newId);
}
}
if (forwardFrom != item->history()->peer) {
if (forwardFrom) {
history->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_flags(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), history->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, history->sendRequestId);
ids.resize(0);
randomIds.resize(0);
}
forwardFrom = item->history()->peer;
}
ids.push_back(MTP_int(item->id));
randomIds.push_back(MTP_long(randomId));
}
history->sendRequestId = MTP::send(MTPmessages_ForwardMessages(MTP_flags(sendFlags), forwardFrom->input, MTP_vector<MTPint>(ids), MTP_vector<MTPlong>(randomIds), history->peer->input), rpcDone(&MainWidget::sentUpdatesReceived), RPCFailHandlerPtr(), 0, 0, history->sendRequestId);
auto toForward = history->validateForwardDraft();
if (!toForward.empty()) {
auto options = ApiWrap::SendOptions(history);
options.silent = silent;
Auth().api().forwardMessages(std::move(toForward), options);
if (_history->peer() == history->peer) {
_history->peerMessagesUpdated();
}
cancelForwarding(history);
}

View File

@ -503,7 +503,14 @@ void ShowForwardMessagesBox(
weak
](not_null<PeerData*> peer) mutable {
if (peer->isSelf()) {
Ui::Toast::Show(lang(lng_share_done));
auto items = Auth().data().idsToItems(ids);
if (!items.empty()) {
auto options = ApiWrap::SendOptions(App::history(peer));
options.generateLocal = false;
Auth().api().forwardMessages(std::move(items), options, [] {
Ui::Toast::Show(lang(lng_share_done));
});
}
} else {
App::main()->setForwardDraft(peer->id, std::move(ids));
}