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);
|
||||
}
|
||||
|
||||
bool SendDice(Api::MessageToSend &message) {
|
||||
bool SendDice(Api::MessageToSend &message, Fn<void()> doneCallback) {
|
||||
const auto full = message.textWithTags.text.midRef(0).trimmed();
|
||||
auto length = 0;
|
||||
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)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->applyUpdates(result, randomId);
|
||||
if (doneCallback) {
|
||||
doneCallback();
|
||||
}
|
||||
finish();
|
||||
}).fail([=](const RPCError &error) {
|
||||
api->sendMessageFail(error, peer, randomId, newId);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ void SendExistingPhoto(
|
|||
Fn<void()> doneCallback = nullptr,
|
||||
bool forwarding = false);
|
||||
|
||||
bool SendDice(Api::MessageToSend &message);
|
||||
bool SendDice(Api::MessageToSend &message, Fn<void()> doneCallback = nullptr);
|
||||
|
||||
void FillMessagePostFlags(
|
||||
const SendAction &action,
|
||||
|
|
|
|||
|
|
@ -3922,7 +3922,11 @@ void ApiWrap::finishForwarding(const SendAction &action) {
|
|||
return;
|
||||
}
|
||||
|
||||
forwardMessages(std::move(toForward), action);
|
||||
if (cForwardQuoted()) {
|
||||
forwardMessages(std::move(toForward), action);
|
||||
} else {
|
||||
forwardMessagesUnquoted(std::move(toForward), action);
|
||||
}
|
||||
_session->data().cancelForwarding(history);
|
||||
}
|
||||
|
||||
|
|
@ -3954,7 +3958,7 @@ void ApiWrap::forwardMessages(
|
|||
}
|
||||
|
||||
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 peer = history->peer;
|
||||
|
||||
|
|
@ -3978,41 +3982,12 @@ void ApiWrap::forwardMessages(
|
|||
}
|
||||
|
||||
auto forwardFrom = items.front()->history()->peer;
|
||||
auto currentGroupId = items.front()->groupId();
|
||||
auto isLastGrouped = false;
|
||||
auto forwardGroupId = items.front()->groupId();
|
||||
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()) {
|
||||
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 = [&] {
|
||||
const auto sendAccumulated = [&] {
|
||||
if (shared) {
|
||||
++shared->requestsLeft;
|
||||
}
|
||||
|
|
@ -4046,6 +4021,142 @@ void ApiWrap::forwardMessages(
|
|||
).send();
|
||||
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) {
|
||||
|
|
@ -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) {
|
||||
if (shared) {
|
||||
++shared->requestsLeft;
|
||||
|
|
@ -4305,9 +4442,7 @@ void ApiWrap::forwardMessages(
|
|||
};
|
||||
|
||||
const auto sendAccumulated = [&] {
|
||||
if (cForwardQuoted()) {
|
||||
forwardQuoted();
|
||||
} else if (isGrouped()) {
|
||||
if (isGrouped()) {
|
||||
forwardAlbumUnquoted();
|
||||
} else {
|
||||
for (auto i = fromIter, e = toIter; i != e; i++) {
|
||||
|
|
@ -4315,7 +4450,9 @@ void ApiWrap::forwardMessages(
|
|||
const auto media = item->media();
|
||||
|
||||
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->sharedContact()
|
||||
|| media->photo()
|
||||
|
|
@ -4340,33 +4477,6 @@ void ApiWrap::forwardMessages(
|
|||
for (auto i = items.begin(), e = items.end(); i != e; /* ++i is in the end */) {
|
||||
const auto item = *i;
|
||||
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)) {
|
||||
sendAccumulated();
|
||||
forwardFrom = item->history()->peer;
|
||||
|
|
@ -4376,7 +4486,15 @@ void ApiWrap::forwardMessages(
|
|||
ids.push_back(MTP_int(item->id));
|
||||
randomIds.push_back(MTP_long(randomId));
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,6 +378,10 @@ public:
|
|||
HistoryItemsList &&items,
|
||||
const SendAction &action,
|
||||
FnMut<void()> &&successCallback = nullptr);
|
||||
void forwardMessagesUnquoted(
|
||||
HistoryItemsList &&items,
|
||||
const SendAction &action,
|
||||
FnMut<void()> &&successCallback = nullptr);
|
||||
void shareContact(
|
||||
const QString &phone,
|
||||
const QString &firstName,
|
||||
|
|
|
|||
|
|
@ -1216,10 +1216,16 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
|||
auto action = Api::SendAction(history);
|
||||
action.options = options;
|
||||
action.clearDraft = false;
|
||||
|
||||
api.forwardMessages(history->owner().idsToItems(data->msgIds), action, [=] {
|
||||
checkAndClose();
|
||||
});
|
||||
|
||||
if (cForwardQuoted()) {
|
||||
api.forwardMessages(history->owner().idsToItems(data->msgIds), action, [=] {
|
||||
checkAndClose();
|
||||
});
|
||||
} else {
|
||||
api.forwardMessagesUnquoted(history->owner().idsToItems(data->msgIds), action, [=] {
|
||||
checkAndClose();
|
||||
});
|
||||
}
|
||||
}
|
||||
if (data->submitCallback && !cForwardRetainSelection()) {
|
||||
data->submitCallback();
|
||||
|
|
@ -1232,6 +1238,9 @@ QPointer<Ui::RpWidget> ShowForwardMessagesBox(
|
|||
? Fn<void()>(std::move(copyCallback))
|
||||
: Fn<void()>();
|
||||
auto goToChatCallback = [navigation, data](PeerData *peer) {
|
||||
if (data->submitCallback && !cForwardRetainSelection()) {
|
||||
data->submitCallback();
|
||||
}
|
||||
navigation->parentController()->content()->setForwardDraft(peer->id, std::move(data->msgIds));
|
||||
};
|
||||
*weak = Ui::show(Box<ShareBox>(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue