Fixes for dices and grouping modes in forwarding
This commit is contained in:
parent
7260b05900
commit
6d43f949fa
5 changed files with 205 additions and 71 deletions
|
|
@ -228,7 +228,7 @@ void SendExistingPhoto(
|
||||||
forwarding);
|
forwarding);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SendDice(Api::MessageToSend &message) {
|
bool SendDice(Api::MessageToSend &message, Fn<void()> doneCallback) {
|
||||||
const auto full = message.textWithTags.text.midRef(0).trimmed();
|
const auto full = message.textWithTags.text.midRef(0).trimmed();
|
||||||
auto length = 0;
|
auto length = 0;
|
||||||
if (!Ui::Emoji::Find(full.data(), full.data() + full.size(), &length)
|
if (!Ui::Emoji::Find(full.data(), full.data() + full.size(), &length)
|
||||||
|
|
@ -337,6 +337,9 @@ bool SendDice(Api::MessageToSend &message) {
|
||||||
MTP_int(message.action.options.scheduled)
|
MTP_int(message.action.options.scheduled)
|
||||||
)).done([=](const MTPUpdates &result) {
|
)).done([=](const MTPUpdates &result) {
|
||||||
api->applyUpdates(result, randomId);
|
api->applyUpdates(result, randomId);
|
||||||
|
if (doneCallback) {
|
||||||
|
doneCallback();
|
||||||
|
}
|
||||||
finish();
|
finish();
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](const RPCError &error) {
|
||||||
api->sendMessageFail(error, peer, randomId, newId);
|
api->sendMessageFail(error, peer, randomId, newId);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ void SendExistingPhoto(
|
||||||
Fn<void()> doneCallback = nullptr,
|
Fn<void()> doneCallback = nullptr,
|
||||||
bool forwarding = false);
|
bool forwarding = false);
|
||||||
|
|
||||||
bool SendDice(Api::MessageToSend &message);
|
bool SendDice(Api::MessageToSend &message, Fn<void()> doneCallback = nullptr);
|
||||||
|
|
||||||
void FillMessagePostFlags(
|
void FillMessagePostFlags(
|
||||||
const SendAction &action,
|
const SendAction &action,
|
||||||
|
|
|
||||||
|
|
@ -3922,7 +3922,11 @@ void ApiWrap::finishForwarding(const SendAction &action) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cForwardQuoted()) {
|
||||||
forwardMessages(std::move(toForward), action);
|
forwardMessages(std::move(toForward), action);
|
||||||
|
} else {
|
||||||
|
forwardMessagesUnquoted(std::move(toForward), action);
|
||||||
|
}
|
||||||
_session->data().cancelForwarding(history);
|
_session->data().cancelForwarding(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3954,7 +3958,7 @@ void ApiWrap::forwardMessages(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto count = int(items.size());
|
const auto count = int(items.size());
|
||||||
const auto genClientSideMessage = action.generateLocal && (count < 2) && cForwardQuoted();
|
const auto genClientSideMessage = action.generateLocal && (count < 2);
|
||||||
const auto history = action.history;
|
const auto history = action.history;
|
||||||
const auto peer = history->peer;
|
const auto peer = history->peer;
|
||||||
|
|
||||||
|
|
@ -3978,41 +3982,12 @@ void ApiWrap::forwardMessages(
|
||||||
}
|
}
|
||||||
|
|
||||||
auto forwardFrom = items.front()->history()->peer;
|
auto forwardFrom = items.front()->history()->peer;
|
||||||
auto currentGroupId = items.front()->groupId();
|
auto forwardGroupId = items.front()->groupId();
|
||||||
auto isLastGrouped = false;
|
|
||||||
auto ids = QVector<MTPint>();
|
auto ids = QVector<MTPint>();
|
||||||
auto randomIds = QVector<MTPlong>();
|
auto randomIds = QVector<MTPlong>();
|
||||||
auto localIds = std::shared_ptr<base::flat_map<uint64, FullMsgId>>();
|
auto localIds = std::shared_ptr<base::flat_map<uint64, FullMsgId>>();
|
||||||
auto fromIter = items.begin();
|
|
||||||
auto toIter = items.begin();
|
|
||||||
|
|
||||||
const auto needNextGroup = [&] (not_null<HistoryItem *> item) {
|
const auto sendAccumulated = [&] {
|
||||||
if (cForwardAlbumsAsIs()) {
|
|
||||||
const auto newFrom = item->history()->peer;
|
|
||||||
const auto newGroupId = item->groupId();
|
|
||||||
return forwardFrom != newFrom
|
|
||||||
|| currentGroupId != newGroupId;
|
|
||||||
} else if (cForwardGrouped()) {
|
|
||||||
if (item->media() && item->media()->canBeGrouped()) {
|
|
||||||
return !isLastGrouped;
|
|
||||||
} else {
|
|
||||||
return isLastGrouped;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto isGrouped = [&] {
|
|
||||||
return (cForwardAlbumsAsIs()
|
|
||||||
&& currentGroupId != MessageGroupId())
|
|
||||||
|| (!cForwardAlbumsAsIs()
|
|
||||||
&& cForwardGrouped()
|
|
||||||
&& items.front()->media()
|
|
||||||
&& items.front()->media()->canBeGrouped());
|
|
||||||
};
|
|
||||||
|
|
||||||
const auto forwardQuoted = [&] {
|
|
||||||
if (shared) {
|
if (shared) {
|
||||||
++shared->requestsLeft;
|
++shared->requestsLeft;
|
||||||
}
|
}
|
||||||
|
|
@ -4046,6 +4021,142 @@ void ApiWrap::forwardMessages(
|
||||||
).send();
|
).send();
|
||||||
return history->sendRequestId;
|
return history->sendRequestId;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ids.resize(0);
|
||||||
|
randomIds.resize(0);
|
||||||
|
localIds = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
ids.reserve(count);
|
||||||
|
randomIds.reserve(count);
|
||||||
|
for (const auto item : items) {
|
||||||
|
const auto randomId = rand_value<uint64>();
|
||||||
|
if (genClientSideMessage) {
|
||||||
|
if (const auto message = item->toHistoryMessage()) {
|
||||||
|
const auto newId = FullMsgId(
|
||||||
|
peerToChannel(peer->id),
|
||||||
|
_session->data().nextLocalMessageId());
|
||||||
|
const auto self = _session->user();
|
||||||
|
const auto messageFromId = anonymousPost
|
||||||
|
? PeerId(0)
|
||||||
|
: self->id;
|
||||||
|
const auto messagePostAuthor = peer->isBroadcast()
|
||||||
|
? self->name
|
||||||
|
: QString();
|
||||||
|
history->addNewLocalMessage(
|
||||||
|
newId.msg,
|
||||||
|
flags,
|
||||||
|
clientFlags,
|
||||||
|
HistoryItem::NewMessageDate(action.options.scheduled),
|
||||||
|
messageFromId,
|
||||||
|
messagePostAuthor,
|
||||||
|
message);
|
||||||
|
_session->data().registerMessageRandomId(randomId, newId);
|
||||||
|
if (!localIds) {
|
||||||
|
localIds = std::make_shared<base::flat_map<uint64, FullMsgId>>();
|
||||||
|
}
|
||||||
|
localIds->emplace(randomId, newId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto newFrom = item->history()->peer;
|
||||||
|
const auto newGroupId = item->groupId();
|
||||||
|
if (item != items.front() &&
|
||||||
|
(forwardFrom != newFrom
|
||||||
|
|| (!cForwardAlbumsAsIs() && !cForwardGrouped())
|
||||||
|
|| (cForwardAlbumsAsIs() && forwardGroupId != newGroupId))) {
|
||||||
|
sendAccumulated();
|
||||||
|
forwardFrom = newFrom;
|
||||||
|
forwardGroupId = newGroupId;
|
||||||
|
}
|
||||||
|
ids.push_back(MTP_int(item->id));
|
||||||
|
randomIds.push_back(MTP_long(randomId));
|
||||||
|
}
|
||||||
|
sendAccumulated();
|
||||||
|
_session->data().sendHistoryChangeNotifications();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::forwardMessagesUnquoted(
|
||||||
|
HistoryItemsList &&items,
|
||||||
|
const SendAction &action,
|
||||||
|
FnMut<void()> &&successCallback) {
|
||||||
|
Expects(!items.empty());
|
||||||
|
|
||||||
|
auto &histories = _session->data().histories();
|
||||||
|
|
||||||
|
struct SharedCallback {
|
||||||
|
int requestsLeft = 0;
|
||||||
|
FnMut<void()> callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LastGroupType {
|
||||||
|
None,
|
||||||
|
Documents,
|
||||||
|
Medias,
|
||||||
|
};
|
||||||
|
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 history = action.history;
|
||||||
|
const auto peer = history->peer;
|
||||||
|
|
||||||
|
histories.readInbox(history);
|
||||||
|
|
||||||
|
const auto anonymousPost = peer->amAnonymous();
|
||||||
|
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||||
|
|
||||||
|
auto flags = MTPDmessage::Flags(0);
|
||||||
|
auto clientFlags = MTPDmessage_ClientFlags();
|
||||||
|
auto sendFlags = MTPmessages_ForwardMessages::Flags(0);
|
||||||
|
FillMessagePostFlags(action, peer, flags);
|
||||||
|
if (silentPost) {
|
||||||
|
sendFlags |= MTPmessages_ForwardMessages::Flag::f_silent;
|
||||||
|
}
|
||||||
|
if (action.options.scheduled) {
|
||||||
|
flags |= MTPDmessage::Flag::f_from_scheduled;
|
||||||
|
sendFlags |= MTPmessages_ForwardMessages::Flag::f_schedule_date;
|
||||||
|
} else {
|
||||||
|
clientFlags |= MTPDmessage_ClientFlag::f_local_history_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto forwardFrom = items.front()->history()->peer;
|
||||||
|
auto currentGroupId = items.front()->groupId();
|
||||||
|
auto lastGroup = LastGroupType::None;
|
||||||
|
auto ids = QVector<MTPint>();
|
||||||
|
auto randomIds = QVector<MTPlong>();
|
||||||
|
auto localIds = std::shared_ptr<base::flat_map<uint64, FullMsgId>>();
|
||||||
|
auto fromIter = items.begin();
|
||||||
|
auto toIter = items.begin();
|
||||||
|
|
||||||
|
const auto needNextGroup = [&] (not_null<HistoryItem *> item) {
|
||||||
|
if (cForwardAlbumsAsIs()) {
|
||||||
|
const auto newFrom = item->history()->peer;
|
||||||
|
const auto newGroupId = item->groupId();
|
||||||
|
return forwardFrom != newFrom
|
||||||
|
|| currentGroupId != newGroupId;
|
||||||
|
} else if (cForwardGrouped()) {
|
||||||
|
if (item->media() && item->media()->canBeGrouped()) {
|
||||||
|
if (item->media()->photo()
|
||||||
|
|| (item->media()->document()
|
||||||
|
&& item->media()->document()->isVideoFile())) {
|
||||||
|
return lastGroup != LastGroupType::Medias;
|
||||||
|
} else {
|
||||||
|
return lastGroup != LastGroupType::Documents;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return lastGroup != LastGroupType::None;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto isGrouped = [&] {
|
||||||
|
return lastGroup != LastGroupType::None && fromIter != toIter;
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto forwardQuotedSingle = [&] (not_null<HistoryItem *> item) {
|
const auto forwardQuotedSingle = [&] (not_null<HistoryItem *> item) {
|
||||||
|
|
@ -4275,6 +4386,32 @@ void ApiWrap::forwardMessages(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const auto forwardDiceUnquoted = [&] (not_null<HistoryItem *> item) {
|
||||||
|
if (shared) {
|
||||||
|
++shared->requestsLeft;
|
||||||
|
}
|
||||||
|
const auto dice = dynamic_cast<Data::MediaDice*>(item->media());
|
||||||
|
if (!dice) {
|
||||||
|
Unexpected("Non-dice in ApiWrap::forwardMessages.");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto message = ApiWrap::MessageToSend(history);
|
||||||
|
message.textWithTags = TextWithTags{
|
||||||
|
dice->emoji(),
|
||||||
|
TextWithTags::Tags()
|
||||||
|
};
|
||||||
|
message.action.options = action.options;
|
||||||
|
message.action.clearDraft = false;
|
||||||
|
|
||||||
|
auto doneCallback = [=] () {
|
||||||
|
if (shared && !--shared->requestsLeft) {
|
||||||
|
shared->callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SendDice(message, std::move(doneCallback));
|
||||||
|
};
|
||||||
|
|
||||||
const auto forwardMessageUnquoted = [&] (not_null<HistoryItem *> item) {
|
const auto forwardMessageUnquoted = [&] (not_null<HistoryItem *> item) {
|
||||||
if (shared) {
|
if (shared) {
|
||||||
++shared->requestsLeft;
|
++shared->requestsLeft;
|
||||||
|
|
@ -4305,9 +4442,7 @@ void ApiWrap::forwardMessages(
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto sendAccumulated = [&] {
|
const auto sendAccumulated = [&] {
|
||||||
if (cForwardQuoted()) {
|
if (isGrouped()) {
|
||||||
forwardQuoted();
|
|
||||||
} else if (isGrouped()) {
|
|
||||||
forwardAlbumUnquoted();
|
forwardAlbumUnquoted();
|
||||||
} else {
|
} else {
|
||||||
for (auto i = fromIter, e = toIter; i != e; i++) {
|
for (auto i = fromIter, e = toIter; i != e; i++) {
|
||||||
|
|
@ -4315,7 +4450,9 @@ void ApiWrap::forwardMessages(
|
||||||
const auto media = item->media();
|
const auto media = item->media();
|
||||||
|
|
||||||
if (media && !media->webpage()) {
|
if (media && !media->webpage()) {
|
||||||
if ((media->poll() && !history->peer->isUser())
|
if (const auto dice = dynamic_cast<Data::MediaDice*>(media)) {
|
||||||
|
forwardDiceUnquoted(item);
|
||||||
|
} else if ((media->poll() && !history->peer->isUser())
|
||||||
|| media->geoPoint()
|
|| media->geoPoint()
|
||||||
|| media->sharedContact()
|
|| media->sharedContact()
|
||||||
|| media->photo()
|
|| media->photo()
|
||||||
|
|
@ -4340,33 +4477,6 @@ void ApiWrap::forwardMessages(
|
||||||
for (auto i = items.begin(), e = items.end(); i != e; /* ++i is in the end */) {
|
for (auto i = items.begin(), e = items.end(); i != e; /* ++i is in the end */) {
|
||||||
const auto item = *i;
|
const auto item = *i;
|
||||||
const auto randomId = rand_value<uint64>();
|
const auto randomId = rand_value<uint64>();
|
||||||
if (genClientSideMessage) {
|
|
||||||
if (const auto message = item->toHistoryMessage()) {
|
|
||||||
const auto newId = FullMsgId(
|
|
||||||
peerToChannel(peer->id),
|
|
||||||
_session->data().nextLocalMessageId());
|
|
||||||
const auto self = _session->user();
|
|
||||||
const auto messageFromId = anonymousPost
|
|
||||||
? PeerId(0)
|
|
||||||
: self->id;
|
|
||||||
const auto messagePostAuthor = peer->isBroadcast()
|
|
||||||
? self->name
|
|
||||||
: QString();
|
|
||||||
history->addNewLocalMessage(
|
|
||||||
newId.msg,
|
|
||||||
flags,
|
|
||||||
clientFlags,
|
|
||||||
HistoryItem::NewMessageDate(action.options.scheduled),
|
|
||||||
messageFromId,
|
|
||||||
messagePostAuthor,
|
|
||||||
message);
|
|
||||||
_session->data().registerMessageRandomId(randomId, newId);
|
|
||||||
if (!localIds) {
|
|
||||||
localIds = std::make_shared<base::flat_map<uint64, FullMsgId>>();
|
|
||||||
}
|
|
||||||
localIds->emplace(randomId, newId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (needNextGroup(item)) {
|
if (needNextGroup(item)) {
|
||||||
sendAccumulated();
|
sendAccumulated();
|
||||||
forwardFrom = item->history()->peer;
|
forwardFrom = item->history()->peer;
|
||||||
|
|
@ -4376,7 +4486,15 @@ void ApiWrap::forwardMessages(
|
||||||
ids.push_back(MTP_int(item->id));
|
ids.push_back(MTP_int(item->id));
|
||||||
randomIds.push_back(MTP_long(randomId));
|
randomIds.push_back(MTP_long(randomId));
|
||||||
if (item->media() && item->media()->canBeGrouped()) {
|
if (item->media() && item->media()->canBeGrouped()) {
|
||||||
isLastGrouped = true;
|
if (item->media()->photo()
|
||||||
|
|| (item->media()->document()
|
||||||
|
&& item->media()->document()->isVideoFile())) {
|
||||||
|
lastGroup = LastGroupType::Medias;
|
||||||
|
} else {
|
||||||
|
lastGroup = LastGroupType::Documents;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lastGroup = LastGroupType::None;
|
||||||
}
|
}
|
||||||
toIter = ++i;
|
toIter = ++i;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,10 @@ public:
|
||||||
HistoryItemsList &&items,
|
HistoryItemsList &&items,
|
||||||
const SendAction &action,
|
const SendAction &action,
|
||||||
FnMut<void()> &&successCallback = nullptr);
|
FnMut<void()> &&successCallback = nullptr);
|
||||||
|
void forwardMessagesUnquoted(
|
||||||
|
HistoryItemsList &&items,
|
||||||
|
const SendAction &action,
|
||||||
|
FnMut<void()> &&successCallback = nullptr);
|
||||||
void shareContact(
|
void shareContact(
|
||||||
const QString &phone,
|
const QString &phone,
|
||||||
const QString &firstName,
|
const QString &firstName,
|
||||||
|
|
|
||||||
|
|
@ -1217,9 +1217,15 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
action.options = options;
|
action.options = options;
|
||||||
action.clearDraft = false;
|
action.clearDraft = false;
|
||||||
|
|
||||||
|
if (cForwardQuoted()) {
|
||||||
api.forwardMessages(history->owner().idsToItems(data->msgIds), action, [=] {
|
api.forwardMessages(history->owner().idsToItems(data->msgIds), action, [=] {
|
||||||
checkAndClose();
|
checkAndClose();
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
api.forwardMessagesUnquoted(history->owner().idsToItems(data->msgIds), action, [=] {
|
||||||
|
checkAndClose();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (data->submitCallback && !cForwardRetainSelection()) {
|
if (data->submitCallback && !cForwardRetainSelection()) {
|
||||||
data->submitCallback();
|
data->submitCallback();
|
||||||
|
|
@ -1232,6 +1238,9 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
||||||
? Fn<void()>(std::move(copyCallback))
|
? Fn<void()>(std::move(copyCallback))
|
||||||
: Fn<void()>();
|
: Fn<void()>();
|
||||||
auto goToChatCallback = [navigation, data](PeerData *peer) {
|
auto goToChatCallback = [navigation, data](PeerData *peer) {
|
||||||
|
if (data->submitCallback && !cForwardRetainSelection()) {
|
||||||
|
data->submitCallback();
|
||||||
|
}
|
||||||
navigation->parentController()->content()->setForwardDraft(peer->id, std::move(data->msgIds));
|
navigation->parentController()->content()->setForwardDraft(peer->id, std::move(data->msgIds));
|
||||||
};
|
};
|
||||||
*weak = Ui::show(Box<ShareBox>(
|
*weak = Ui::show(Box<ShareBox>(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue