mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Don't accept drafts older than last saved.
I hope it finally fixes #4922, partially fixes #10001. The rest of #10001 like RAM usage / crashes are unrelated to drafts.
This commit is contained in:
parent
74c21039b3
commit
5794679277
4 changed files with 86 additions and 52 deletions
|
@ -114,6 +114,10 @@ using PhotoFileLocationId = Data::PhotoFileLocationId;
|
||||||
using DocumentFileLocationId = Data::DocumentFileLocationId;
|
using DocumentFileLocationId = Data::DocumentFileLocationId;
|
||||||
using UpdatedFileReferences = Data::UpdatedFileReferences;
|
using UpdatedFileReferences = Data::UpdatedFileReferences;
|
||||||
|
|
||||||
|
[[nodiscard]] TimeId UnixtimeFromMsgId(mtpMsgId msgId) {
|
||||||
|
return TimeId(msgId << 32);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MTPInputPrivacyKey ApiWrap::Privacy::Input(Key key) {
|
MTPInputPrivacyKey ApiWrap::Privacy::Input(Key key) {
|
||||||
|
@ -2445,38 +2449,41 @@ void ApiWrap::saveDraftsToCloud() {
|
||||||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags),
|
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags),
|
||||||
Api::ConvertOption::SkipLocal);
|
Api::ConvertOption::SkipLocal);
|
||||||
|
|
||||||
const auto draftText = textWithTags.text;
|
history->startSavingCloudDraft();
|
||||||
history->setSentDraftText(draftText);
|
|
||||||
cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(
|
cloudDraft->saveRequestId = request(MTPmessages_SaveDraft(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
MTP_int(cloudDraft->msgId),
|
MTP_int(cloudDraft->msgId),
|
||||||
history->peer->input,
|
history->peer->input,
|
||||||
MTP_string(textWithTags.text),
|
MTP_string(textWithTags.text),
|
||||||
entities
|
entities
|
||||||
)).done([=](const MTPBool &result, mtpRequestId requestId) {
|
)).done([=](const MTPBool &result, const MTP::Response &response) {
|
||||||
history->clearSentDraftText(draftText);
|
history->finishSavingCloudDraft(
|
||||||
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
|
|
||||||
if (const auto cloudDraft = history->cloudDraft()) {
|
if (const auto cloudDraft = history->cloudDraft()) {
|
||||||
if (cloudDraft->saveRequestId == requestId) {
|
if (cloudDraft->saveRequestId == response.requestId) {
|
||||||
cloudDraft->saveRequestId = 0;
|
cloudDraft->saveRequestId = 0;
|
||||||
history->draftSavedToCloud();
|
history->draftSavedToCloud();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto i = _draftsSaveRequestIds.find(history);
|
auto i = _draftsSaveRequestIds.find(history);
|
||||||
if (i != _draftsSaveRequestIds.cend() && i->second == requestId) {
|
if (i != _draftsSaveRequestIds.cend()
|
||||||
|
&& i->second == response.requestId) {
|
||||||
_draftsSaveRequestIds.erase(history);
|
_draftsSaveRequestIds.erase(history);
|
||||||
checkQuitPreventFinished();
|
checkQuitPreventFinished();
|
||||||
}
|
}
|
||||||
}).fail([=](const RPCError &error, mtpRequestId requestId) {
|
}).fail([=](const RPCError &error, const MTP::Response &response) {
|
||||||
history->clearSentDraftText(draftText);
|
history->finishSavingCloudDraft(
|
||||||
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
|
|
||||||
if (const auto cloudDraft = history->cloudDraft()) {
|
if (const auto cloudDraft = history->cloudDraft()) {
|
||||||
if (cloudDraft->saveRequestId == requestId) {
|
if (cloudDraft->saveRequestId == response.requestId) {
|
||||||
history->clearCloudDraft();
|
history->clearCloudDraft();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto i = _draftsSaveRequestIds.find(history);
|
auto i = _draftsSaveRequestIds.find(history);
|
||||||
if (i != _draftsSaveRequestIds.cend() && i->second == requestId) {
|
if (i != _draftsSaveRequestIds.cend()
|
||||||
|
&& i->second == response.requestId) {
|
||||||
_draftsSaveRequestIds.erase(history);
|
_draftsSaveRequestIds.erase(history);
|
||||||
checkQuitPreventFinished();
|
checkQuitPreventFinished();
|
||||||
}
|
}
|
||||||
|
@ -4027,10 +4034,11 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
if (!sentEntities.v.isEmpty()) {
|
if (!sentEntities.v.isEmpty()) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_entities;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_entities;
|
||||||
}
|
}
|
||||||
if (action.clearDraft) {
|
const auto clearCloudDraft = action.clearDraft;
|
||||||
|
if (clearCloudDraft) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_clear_draft;
|
||||||
history->clearCloudDraft();
|
history->clearCloudDraft();
|
||||||
history->setSentDraftText(QString());
|
history->startSavingCloudDraft();
|
||||||
}
|
}
|
||||||
auto messageFromId = anonymousPost ? 0 : _session->userPeerId();
|
auto messageFromId = anonymousPost ? 0 : _session->userPeerId();
|
||||||
auto messagePostAuthor = peer->isBroadcast()
|
auto messagePostAuthor = peer->isBroadcast()
|
||||||
|
@ -4080,17 +4088,27 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
MTPReplyMarkup(),
|
MTPReplyMarkup(),
|
||||||
sentEntities,
|
sentEntities,
|
||||||
MTP_int(action.options.scheduled)
|
MTP_int(action.options.scheduled)
|
||||||
)).done([=](const MTPUpdates &result) {
|
)).done([=](
|
||||||
|
const MTPUpdates &result,
|
||||||
|
const MTP::Response &response) {
|
||||||
applyUpdates(result, randomId);
|
applyUpdates(result, randomId);
|
||||||
history->clearSentDraftText(QString());
|
if (clearCloudDraft) {
|
||||||
|
history->finishSavingCloudDraft(
|
||||||
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
|
}
|
||||||
finish();
|
finish();
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](
|
||||||
|
const RPCError &error,
|
||||||
|
const MTP::Response &response) {
|
||||||
if (error.type() == qstr("MESSAGE_EMPTY")) {
|
if (error.type() == qstr("MESSAGE_EMPTY")) {
|
||||||
lastMessage->destroy();
|
lastMessage->destroy();
|
||||||
} else {
|
} else {
|
||||||
sendMessageFail(error, peer, randomId, newId);
|
sendMessageFail(error, peer, randomId, newId);
|
||||||
}
|
}
|
||||||
history->clearSentDraftText(QString());
|
if (clearCloudDraft) {
|
||||||
|
history->finishSavingCloudDraft(
|
||||||
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
|
}
|
||||||
finish();
|
finish();
|
||||||
}).afterRequest(history->sendRequestId
|
}).afterRequest(history->sendRequestId
|
||||||
).send();
|
).send();
|
||||||
|
@ -4188,7 +4206,7 @@ void ApiWrap::sendInlineResult(
|
||||||
messagePostAuthor);
|
messagePostAuthor);
|
||||||
|
|
||||||
history->clearCloudDraft();
|
history->clearCloudDraft();
|
||||||
history->setSentDraftText(QString());
|
history->startSavingCloudDraft();
|
||||||
|
|
||||||
auto &histories = history->owner().histories();
|
auto &histories = history->owner().histories();
|
||||||
const auto requestType = Data::Histories::RequestType::Send;
|
const auto requestType = Data::Histories::RequestType::Send;
|
||||||
|
@ -4201,13 +4219,19 @@ void ApiWrap::sendInlineResult(
|
||||||
MTP_long(data->getQueryId()),
|
MTP_long(data->getQueryId()),
|
||||||
MTP_string(data->getId()),
|
MTP_string(data->getId()),
|
||||||
MTP_int(action.options.scheduled)
|
MTP_int(action.options.scheduled)
|
||||||
)).done([=](const MTPUpdates &result) {
|
)).done([=](
|
||||||
|
const MTPUpdates &result,
|
||||||
|
const MTP::Response &response) {
|
||||||
applyUpdates(result, randomId);
|
applyUpdates(result, randomId);
|
||||||
history->clearSentDraftText(QString());
|
history->finishSavingCloudDraft(
|
||||||
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
finish();
|
finish();
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](
|
||||||
|
const RPCError &error,
|
||||||
|
const MTP::Response &response) {
|
||||||
sendMessageFail(error, peer, randomId, newId);
|
sendMessageFail(error, peer, randomId, newId);
|
||||||
history->clearSentDraftText(QString());
|
history->finishSavingCloudDraft(
|
||||||
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
finish();
|
finish();
|
||||||
}).afterRequest(history->sendRequestId
|
}).afterRequest(history->sendRequestId
|
||||||
).send();
|
).send();
|
||||||
|
@ -4894,10 +4918,12 @@ void ApiWrap::createPoll(
|
||||||
if (action.replyTo) {
|
if (action.replyTo) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_reply_to_msg_id;
|
||||||
}
|
}
|
||||||
if (action.clearDraft) {
|
const auto clearCloudDraft = action.clearDraft;
|
||||||
|
if (clearCloudDraft) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_clear_draft;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_clear_draft;
|
||||||
history->clearLocalDraft();
|
history->clearLocalDraft();
|
||||||
history->clearCloudDraft();
|
history->clearCloudDraft();
|
||||||
|
history->startSavingCloudDraft();
|
||||||
}
|
}
|
||||||
const auto silentPost = ShouldSendSilent(peer, action.options);
|
const auto silentPost = ShouldSendSilent(peer, action.options);
|
||||||
if (silentPost) {
|
if (silentPost) {
|
||||||
|
@ -4920,8 +4946,14 @@ void ApiWrap::createPoll(
|
||||||
MTPReplyMarkup(),
|
MTPReplyMarkup(),
|
||||||
MTPVector<MTPMessageEntity>(),
|
MTPVector<MTPMessageEntity>(),
|
||||||
MTP_int(action.options.scheduled)
|
MTP_int(action.options.scheduled)
|
||||||
)).done([=](const MTPUpdates &result) mutable {
|
)).done([=](
|
||||||
|
const MTPUpdates &result,
|
||||||
|
const MTP::Response &response) mutable {
|
||||||
applyUpdates(result);
|
applyUpdates(result);
|
||||||
|
if (clearCloudDraft) {
|
||||||
|
history->finishSavingCloudDraft(
|
||||||
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
|
}
|
||||||
_session->changes().historyUpdated(
|
_session->changes().historyUpdated(
|
||||||
history,
|
history,
|
||||||
(action.options.scheduled
|
(action.options.scheduled
|
||||||
|
@ -4929,7 +4961,13 @@ void ApiWrap::createPoll(
|
||||||
: Data::HistoryUpdate::Flag::MessageSent));
|
: Data::HistoryUpdate::Flag::MessageSent));
|
||||||
done();
|
done();
|
||||||
finish();
|
finish();
|
||||||
}).fail([=](const RPCError &error) mutable {
|
}).fail([=](
|
||||||
|
const RPCError &error,
|
||||||
|
const MTP::Response &response) mutable {
|
||||||
|
if (clearCloudDraft) {
|
||||||
|
history->finishSavingCloudDraft(
|
||||||
|
UnixtimeFromMsgId(response.outerMsgId));
|
||||||
|
}
|
||||||
fail(error);
|
fail(error);
|
||||||
finish();
|
finish();
|
||||||
}).afterRequest(history->sendRequestId
|
}).afterRequest(history->sendRequestId
|
||||||
|
|
|
@ -48,7 +48,11 @@ void ApplyPeerCloudDraft(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
const MTPDdraftMessage &draft) {
|
const MTPDdraftMessage &draft) {
|
||||||
const auto history = session->data().history(peerId);
|
const auto history = session->data().history(peerId);
|
||||||
const auto textWithTags = TextWithTags {
|
const auto date = draft.vdate().v;
|
||||||
|
if (history->skipCloudDraftUpdate(date)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto textWithTags = TextWithTags{
|
||||||
qs(draft.vmessage()),
|
qs(draft.vmessage()),
|
||||||
TextUtilities::ConvertEntitiesToTextTags(
|
TextUtilities::ConvertEntitiesToTextTags(
|
||||||
Api::EntitiesFromMTP(
|
Api::EntitiesFromMTP(
|
||||||
|
@ -56,9 +60,6 @@ void ApplyPeerCloudDraft(
|
||||||
draft.ventities().value_or_empty()))
|
draft.ventities().value_or_empty()))
|
||||||
};
|
};
|
||||||
const auto replyTo = draft.vreply_to_msg_id().value_or_empty();
|
const auto replyTo = draft.vreply_to_msg_id().value_or_empty();
|
||||||
if (history->skipCloudDraft(textWithTags.text, replyTo, draft.vdate().v)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto cloudDraft = std::make_unique<Draft>(
|
auto cloudDraft = std::make_unique<Draft>(
|
||||||
textWithTags,
|
textWithTags,
|
||||||
replyTo,
|
replyTo,
|
||||||
|
@ -66,7 +67,7 @@ void ApplyPeerCloudDraft(
|
||||||
(draft.is_no_webpage()
|
(draft.is_no_webpage()
|
||||||
? Data::PreviewState::Cancelled
|
? Data::PreviewState::Cancelled
|
||||||
: Data::PreviewState::Allowed));
|
: Data::PreviewState::Allowed));
|
||||||
cloudDraft->date = draft.vdate().v;
|
cloudDraft->date = date;
|
||||||
|
|
||||||
history->setCloudDraft(std::move(cloudDraft));
|
history->setCloudDraft(std::move(cloudDraft));
|
||||||
history->applyCloudDraft();
|
history->applyCloudDraft();
|
||||||
|
@ -77,7 +78,7 @@ void ClearPeerCloudDraft(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
TimeId date) {
|
TimeId date) {
|
||||||
const auto history = session->data().history(peerId);
|
const auto history = session->data().history(peerId);
|
||||||
if (history->skipCloudDraft(QString(), MsgId(0), date)) {
|
if (history->skipCloudDraftUpdate(date)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kNewBlockEachMessage = 50;
|
constexpr auto kNewBlockEachMessage = 50;
|
||||||
constexpr auto kSkipCloudDraftsFor = TimeId(3);
|
constexpr auto kSkipCloudDraftsFor = TimeId(2);
|
||||||
|
constexpr auto kSendingDraftTime = TimeId(-1);
|
||||||
|
|
||||||
using UpdateFlag = Data::HistoryUpdate::Flag;
|
using UpdateFlag = Data::HistoryUpdate::Flag;
|
||||||
|
|
||||||
|
@ -299,27 +300,21 @@ Data::Draft *History::createCloudDraft(const Data::Draft *fromDraft) {
|
||||||
return cloudDraft();
|
return cloudDraft();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool History::skipCloudDraft(const QString &text, MsgId replyTo, TimeId date) const {
|
bool History::skipCloudDraftUpdate(TimeId date) const {
|
||||||
if (Data::draftStringIsEmpty(text)
|
return (_savingCloudDraftRequests > 0)
|
||||||
&& !replyTo
|
|| (date < _acceptCloudDraftsAfter);
|
||||||
&& date > 0
|
|
||||||
&& date <= _lastSentDraftTime + kSkipCloudDraftsFor) {
|
|
||||||
return true;
|
|
||||||
} else if (_lastSentDraftText && *_lastSentDraftText == text) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::setSentDraftText(const QString &text) {
|
void History::startSavingCloudDraft() {
|
||||||
_lastSentDraftText = text;
|
++_savingCloudDraftRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::clearSentDraftText(const QString &text) {
|
void History::finishSavingCloudDraft(TimeId savedAt) {
|
||||||
if (_lastSentDraftText && *_lastSentDraftText == text) {
|
if (_savingCloudDraftRequests > 0) {
|
||||||
_lastSentDraftText = std::nullopt;
|
--_savingCloudDraftRequests;
|
||||||
}
|
}
|
||||||
accumulate_max(_lastSentDraftTime, base::unixtime::now());
|
const auto acceptAfter = savedAt + kSkipCloudDraftsFor;
|
||||||
|
_acceptCloudDraftsAfter = std::max(_acceptCloudDraftsAfter, acceptAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void History::applyCloudDraft() {
|
void History::applyCloudDraft() {
|
||||||
|
|
|
@ -339,9 +339,9 @@ public:
|
||||||
}
|
}
|
||||||
void clearDrafts();
|
void clearDrafts();
|
||||||
Data::Draft *createCloudDraft(const Data::Draft *fromDraft);
|
Data::Draft *createCloudDraft(const Data::Draft *fromDraft);
|
||||||
bool skipCloudDraft(const QString &text, MsgId replyTo, TimeId date) const;
|
bool skipCloudDraftUpdate(TimeId date) const;
|
||||||
void setSentDraftText(const QString &text);
|
void startSavingCloudDraft();
|
||||||
void clearSentDraftText(const QString &text);
|
void finishSavingCloudDraft(TimeId savedAt);
|
||||||
void takeLocalDraft(not_null<History*> from);
|
void takeLocalDraft(not_null<History*> from);
|
||||||
void applyCloudDraft();
|
void applyCloudDraft();
|
||||||
void draftSavedToCloud();
|
void draftSavedToCloud();
|
||||||
|
@ -584,8 +584,8 @@ private:
|
||||||
std::unique_ptr<BuildingBlock> _buildingFrontBlock;
|
std::unique_ptr<BuildingBlock> _buildingFrontBlock;
|
||||||
|
|
||||||
Data::HistoryDrafts _drafts;
|
Data::HistoryDrafts _drafts;
|
||||||
std::optional<QString> _lastSentDraftText;
|
TimeId _acceptCloudDraftsAfter = 0;
|
||||||
TimeId _lastSentDraftTime = 0;
|
int _savingCloudDraftRequests = 0;
|
||||||
MessageIdsList _forwardDraft;
|
MessageIdsList _forwardDraft;
|
||||||
|
|
||||||
QString _topPromotedMessage;
|
QString _topPromotedMessage;
|
||||||
|
|
Loading…
Add table
Reference in a new issue