Improve editing messages with link previews.

Now preview state can be one of (allowed, cancelled, empty-in-edit).

In case of editing a message without preview we set the state to
empty-in-edit and it changes to allowed if the links in the message
are changed somehow.

That way we don't need to cancel the preview when editing a message
with a cancelled preview and at the same time adding a link to
a message that had no preview in the first place will add a preview.
This commit is contained in:
John Preston 2021-01-29 15:27:17 +04:00
parent fc4ed2ff91
commit 8f0e23bb25
16 changed files with 159 additions and 82 deletions

View file

@ -2449,7 +2449,7 @@ void ApiWrap::saveDraftsToCloud() {
auto flags = MTPmessages_SaveDraft::Flags(0);
auto &textWithTags = cloudDraft->textWithTags;
if (cloudDraft->previewCancelled) {
if (cloudDraft->previewState != Data::PreviewState::Allowed) {
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
}
if (cloudDraft->msgId) {

View file

@ -501,6 +501,11 @@ MessageLinksParser::MessageLinksParser(not_null<Ui::InputField*> field)
_field->installEventFilter(this);
}
void MessageLinksParser::parseNow() {
_timer.cancel();
parse();
}
bool MessageLinksParser::eventFilter(QObject *object, QEvent *event) {
if (object == _field) {
if (event->type() == QEvent::KeyPress) {

View file

@ -71,7 +71,9 @@ class MessageLinksParser : private QObject {
public:
MessageLinksParser(not_null<Ui::InputField*> field);
const rpl::variable<QStringList> &list() const;
void parseNow();
[[nodiscard]] const rpl::variable<QStringList> &list() const;
protected:
bool eventFilter(QObject *object, QEvent *event) override;

View file

@ -18,32 +18,29 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/localstorage.h"
namespace Data {
namespace {
} // namespace
Draft::Draft(
const TextWithTags &textWithTags,
MsgId msgId,
const MessageCursor &cursor,
bool previewCancelled,
PreviewState previewState,
mtpRequestId saveRequestId)
: textWithTags(textWithTags)
, msgId(msgId)
, cursor(cursor)
, previewCancelled(previewCancelled)
, previewState(previewState)
, saveRequestId(saveRequestId) {
}
Draft::Draft(
not_null<const Ui::InputField*> field,
MsgId msgId,
bool previewCancelled,
PreviewState previewState,
mtpRequestId saveRequestId)
: textWithTags(field->getTextWithTags())
, msgId(msgId)
, cursor(field)
, previewCancelled(previewCancelled) {
, previewState(previewState) {
}
void ApplyPeerCloudDraft(
@ -66,7 +63,9 @@ void ApplyPeerCloudDraft(
textWithTags,
replyTo,
MessageCursor(QFIXED_MAX, QFIXED_MAX, QFIXED_MAX),
draft.is_no_webpage());
(draft.is_no_webpage()
? Data::PreviewState::Cancelled
: Data::PreviewState::Allowed));
cloudDraft->date = draft.vdate().v;
history->setCloudDraft(std::move(cloudDraft));

View file

@ -26,25 +26,31 @@ void ClearPeerCloudDraft(
PeerId peerId,
TimeId date);
enum class PreviewState : char {
Allowed,
Cancelled,
EmptyOnEdit,
};
struct Draft {
Draft() = default;
Draft(
const TextWithTags &textWithTags,
MsgId msgId,
const MessageCursor &cursor,
bool previewCancelled,
PreviewState previewState,
mtpRequestId saveRequestId = 0);
Draft(
not_null<const Ui::InputField*> field,
MsgId msgId,
bool previewCancelled,
PreviewState previewState,
mtpRequestId saveRequestId = 0);
TimeId date = 0;
TextWithTags textWithTags;
MsgId msgId = 0; // replyToId for message draft, editMsgId for edit draft
MessageCursor cursor;
bool previewCancelled = false;
PreviewState previewState = PreviewState::Allowed;
mtpRequestId saveRequestId = 0;
};
@ -144,7 +150,7 @@ inline bool draftsAreEqual(const Draft *a, const Draft *b) {
return (a->textWithTags == b->textWithTags)
&& (a->msgId == b->msgId)
&& (a->previewCancelled == b->previewCancelled);
&& (a->previewState == b->previewState);
}
} // namespace Data

View file

@ -215,13 +215,13 @@ void History::createLocalDraftFromCloud() {
draft->textWithTags,
draft->msgId,
draft->cursor,
draft->previewCancelled));
draft->previewState));
existing = localDraft();
} else if (existing != draft) {
existing->textWithTags = draft->textWithTags;
existing->msgId = draft->msgId;
existing->cursor = draft->cursor;
existing->previewCancelled = draft->previewCancelled;
existing->previewState = draft->previewState;
}
existing->date = draft->date;
}
@ -280,7 +280,7 @@ Data::Draft *History::createCloudDraft(const Data::Draft *fromDraft) {
TextWithTags(),
0,
MessageCursor(),
false));
Data::PreviewState::Allowed));
cloudDraft()->date = TimeId(0);
} else {
auto existing = cloudDraft();
@ -289,13 +289,13 @@ Data::Draft *History::createCloudDraft(const Data::Draft *fromDraft) {
fromDraft->textWithTags,
fromDraft->msgId,
fromDraft->cursor,
fromDraft->previewCancelled));
fromDraft->previewState));
existing = cloudDraft();
} else if (existing != fromDraft) {
existing->textWithTags = fromDraft->textWithTags;
existing->msgId = fromDraft->msgId;
existing->cursor = fromDraft->cursor;
existing->previewCancelled = fromDraft->previewCancelled;
existing->previewState = fromDraft->previewState;
}
existing->date = base::unixtime::now();
}

View file

@ -174,6 +174,7 @@ HistoryWidget::HistoryWidget(
, _updateEditTimeLeftDisplay([=] { updateField(); })
, _fieldBarCancel(this, st::historyReplyCancel)
, _previewTimer([=] { requestPreview(); })
, _previewState(Data::PreviewState::Allowed)
, _topBar(this, controller)
, _scroll(this, st::historyScroll, false)
, _updateHistoryItems([=] { updateHistoryItemsByTimer(); })
@ -335,6 +336,10 @@ HistoryWidget::HistoryWidget(
_fieldLinksParser = std::make_unique<MessageLinksParser>(_field);
_fieldLinksParser->list().changes(
) | rpl::start_with_next([=](QStringList &&parsed) {
if (_previewState == Data::PreviewState::EmptyOnEdit
&& _parsedLinks != parsed) {
_previewState = Data::PreviewState::Allowed;
}
_parsedLinks = std::move(parsed);
checkPreview();
}, lifetime());
@ -1328,7 +1333,7 @@ void HistoryWidget::fieldChanged() {
updateSendButtonType();
if (!HasSendText(_field)) {
_previewCancelled = false;
_previewState = Data::PreviewState::Allowed;
}
if (updateCmdStartShown()) {
updateControlsVisibility();
@ -1377,10 +1382,17 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() {
if (!_history) return;
if (_editMsgId) {
_history->setLocalEditDraft(std::make_unique<Data::Draft>(_field, _editMsgId, _previewCancelled, _saveEditMsgRequestId));
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
_field,
_editMsgId,
_previewState,
_saveEditMsgRequestId));
} else {
if (_replyToId || !_field->empty()) {
_history->setLocalDraft(std::make_unique<Data::Draft>(_field, _replyToId, _previewCancelled));
_history->setLocalDraft(std::make_unique<Data::Draft>(
_field,
_replyToId,
_previewState));
} else {
_history->clearLocalDraft();
}
@ -1401,7 +1413,7 @@ void HistoryWidget::writeDraftTexts() {
Storage::MessageDraft{
_editMsgId ? _editMsgId : _replyToId,
_field->getTextWithTags(),
_previewCancelled,
_previewState,
});
if (_migrated) {
_migrated->clearDrafts();
@ -1476,7 +1488,11 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query, U
if (_history) {
TextWithTags textWithTags = { '@' + samePeerBot->username + ' ' + query, TextWithTags::Tags() };
MessageCursor cursor = { textWithTags.text.size(), textWithTags.text.size(), QFIXED_MAX };
_history->setLocalDraft(std::make_unique<Data::Draft>(textWithTags, 0, cursor, false));
_history->setLocalDraft(std::make_unique<Data::Draft>(
textWithTags,
0,
cursor,
Data::PreviewState::Allowed));
applyDraft();
return true;
}
@ -1497,7 +1513,7 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query, U
textWithTags,
to.currentReplyToId,
cursor,
false);
Data::PreviewState::Allowed);
if (to.section == Section::Replies) {
history->setDraft(
@ -1653,8 +1669,15 @@ void HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
setFieldText(draft->textWithTags, 0, fieldHistoryAction);
_field->setFocus();
draft->cursor.applyTo(_field);
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
_previewCancelled = draft->previewCancelled;
_textUpdateEvents = TextUpdateEvent::SaveDraft
| TextUpdateEvent::SendTyping;
// Save links from _field to _parsedLinks without generating preview.
_previewState = Data::PreviewState::Cancelled;
_fieldLinksParser->parseNow();
_parsedLinks = _fieldLinksParser->list().current();
_previewState = draft->previewState;
_replyEditMsg = nullptr;
if (const auto editDraft = _history->localEditDraft()) {
_editMsgId = editDraft->msgId;
@ -2986,7 +3009,7 @@ void HistoryWidget::saveEditMsg() {
cancelEdit();
return;
}
const auto webPageId = _previewCancelled
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
? CancelledWebPageId
: ((_previewData && _previewData->pendingTill >= 0)
? _previewData->id
@ -3106,7 +3129,7 @@ void HistoryWidget::send(Api::SendOptions options) {
return;
}
const auto webPageId = _previewCancelled
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
? CancelledWebPageId
: ((_previewData && _previewData->pendingTill >= 0)
? _previewData->id
@ -5580,7 +5603,7 @@ void HistoryWidget::setFieldText(
| TextUpdateEvent::SendTyping;
previewCancel();
_previewCancelled = false;
_previewState = Data::PreviewState::Allowed;
}
void HistoryWidget::clearFieldText(
@ -5623,7 +5646,7 @@ void HistoryWidget::replyToMessage(not_null<HistoryItem*> item) {
TextWithTags(),
item->id,
MessageCursor(),
false));
Data::PreviewState::Allowed));
}
} else {
_replyEditMsg = item;
@ -5670,7 +5693,7 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
_history->setLocalDraft(std::make_unique<Data::Draft>(
_field,
_replyToId,
_previewCancelled));
_previewState));
} else {
_history->clearLocalDraft();
}
@ -5688,12 +5711,14 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
}
return nullptr;
}();
const auto previewCancelled = !previewPage;
const auto previewState = previewPage
? Data::PreviewState::Allowed
: Data::PreviewState::EmptyOnEdit;
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
editData,
item->id,
cursor,
previewCancelled));
previewState));
applyDraft();
_previewData = previewPage;
@ -5853,7 +5878,7 @@ void HistoryWidget::cancelFieldAreaState() {
Ui::hideLayer();
_replyForwardPressed = false;
if (_previewData && _previewData->pendingTill >= 0) {
_previewCancelled = true;
_previewState = Data::PreviewState::Cancelled;
previewCancel();
_saveDraftText = true;
@ -5881,7 +5906,7 @@ void HistoryWidget::checkPreview() {
const auto previewRestricted = [&] {
return _peer && _peer->amRestricted(ChatRestriction::f_embed_links);
}();
if (_previewCancelled || previewRestricted) {
if (_previewState != Data::PreviewState::Allowed || previewRestricted) {
previewCancel();
return;
}
@ -5929,7 +5954,10 @@ void HistoryWidget::requestPreview() {
}).send();
}
void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtpRequestId req) {
void HistoryWidget::gotPreview(
QString links,
const MTPMessageMedia &result,
mtpRequestId req) {
if (req == _previewRequest) {
_previewRequest = 0;
}
@ -5937,10 +5965,12 @@ void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtp
const auto &data = result.c_messageMediaWebPage().vwebpage();
const auto page = session().data().processWebpage(data);
_previewCache.insert(links, page->id);
if (page->pendingTill > 0 && page->pendingTill <= base::unixtime::now()) {
if (page->pendingTill > 0
&& page->pendingTill <= base::unixtime::now()) {
page->pendingTill = -1;
}
if (links == _previewLinks && !_previewCancelled) {
if (links == _previewLinks
&& _previewState == Data::PreviewState::Allowed) {
_previewData = (page->id && page->pendingTill >= 0)
? page.get()
: nullptr;
@ -5949,7 +5979,8 @@ void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtp
session().data().sendWebPageGamePollNotifications();
} else if (result.type() == mtpc_messageMediaEmpty) {
_previewCache.insert(links, 0);
if (links == _previewLinks && !_previewCancelled) {
if (links == _previewLinks
&& _previewState == Data::PreviewState::Allowed) {
_previewData = nullptr;
updatePreview();
}

View file

@ -25,6 +25,10 @@ struct SendingAlbum;
enum class SendMediaType;
class MessageLinksParser;
namespace Data {
enum class PreviewState : char;
} // namespace Data
namespace SendMenu {
enum class Type;
} // namespace SendMenu
@ -617,7 +621,7 @@ private:
Ui::Text::String _previewTitle;
Ui::Text::String _previewDescription;
base::Timer _previewTimer;
bool _previewCancelled = false;
Data::PreviewState _previewState = Data::PreviewState();
bool _replyForwardPressed = false;

View file

@ -612,7 +612,8 @@ ComposeControls::ComposeControls(
_send,
st::historySendSize.height()))
, _sendMenuType(sendMenuType)
, _saveDraftTimer([=] { saveDraft(); }) {
, _saveDraftTimer([=] { saveDraft(); })
, _previewState(Data::PreviewState::Allowed) {
init();
}
@ -865,7 +866,7 @@ void ComposeControls::setFieldText(
| TextUpdateEvent::SendTyping;
_previewCancel();
_previewCancelled = false;
_previewState = Data::PreviewState::Allowed;
}
void ComposeControls::saveFieldToHistoryLocalDraft() {
@ -880,7 +881,7 @@ void ComposeControls::saveFieldToHistoryLocalDraft() {
std::make_unique<Data::Draft>(
_field,
_header->getDraftMessageId(),
_previewCancelled));
_previewState));
} else {
_history->clearDraft(draftKeyCurrent());
}
@ -964,7 +965,7 @@ void ComposeControls::init() {
_header->previewCancelled(
) | rpl::start_with_next([=] {
_previewCancelled = true;
_previewState = Data::PreviewState::Cancelled;
_saveDraftText = true;
_saveDraftStart = crl::now();
saveDraft();
@ -1224,7 +1225,7 @@ void ComposeControls::fieldChanged() {
}
updateSendButtonType();
if (!HasSendText(_field)) {
_previewCancelled = false;
_previewState = Data::PreviewState::Allowed;
}
if (updateBotCommandShown()) {
updateControlsVisibility();
@ -1294,7 +1295,7 @@ void ComposeControls::writeDraftTexts() {
Storage::MessageDraft{
_header->getDraftMessageId(),
_field->getTextWithTags(),
_previewCancelled,
_previewState,
});
}
@ -1353,7 +1354,8 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
_field->setFocus();
draft->cursor.applyTo(_field);
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
_previewCancelled = draft->previewCancelled;
_previewSetState(draft->previewState);
if (draft == editDraft) {
_header->editMessage({ _history->channelId(), draft->msgId });
_header->replyToMessage({});
@ -1837,14 +1839,16 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
}
return nullptr;
}();
const auto previewCancelled = !previewPage;
const auto previewState = previewPage
? Data::PreviewState::Allowed
: Data::PreviewState::EmptyOnEdit;
_history->setDraft(
draftKey(DraftType::Edit),
std::make_unique<Data::Draft>(
editData,
item->id,
cursor,
previewCancelled));
previewState));
applyDraft();
if (_autocomplete) {
@ -1883,7 +1887,7 @@ void ComposeControls::replyToMessage(FullMsgId id) {
TextWithTags(),
id.msg,
MessageCursor(),
false));
Data::PreviewState::Allowed));
}
} else {
_header->replyToMessage(id);
@ -1995,7 +1999,8 @@ void ComposeControls::initWebpageProcess() {
if (till > 0 && till <= base::unixtime::now()) {
till = -1;
}
if (links == *previewLinks && !_previewCancelled) {
if (links == *previewLinks
&& _previewState == Data::PreviewState::Allowed) {
*previewData = (page->id && page->pendingTill >= 0)
? page.get()
: nullptr;
@ -2003,7 +2008,8 @@ void ComposeControls::initWebpageProcess() {
}
}, [=](const MTPDmessageMediaEmpty &d) {
previewCache->insert({ links, 0 });
if (links == *previewLinks && !_previewCancelled) {
if (links == *previewLinks
&& _previewState == Data::PreviewState::Allowed) {
*previewData = nullptr;
updatePreview();
}
@ -2032,7 +2038,8 @@ void ComposeControls::initWebpageProcess() {
const auto checkPreview = crl::guard(_wrap.get(), [=] {
const auto previewRestricted = peer
&& peer->amRestricted(ChatRestriction::f_embed_links);
if (_previewCancelled || previewRestricted) {
if (_previewState != Data::PreviewState::Allowed
|| previewRestricted) {
_previewCancel();
return;
}
@ -2105,8 +2112,20 @@ void ComposeControls::initWebpageProcess() {
const auto fieldLinksParser =
lifetime.make_state<MessageLinksParser>(_field);
_previewSetState = [=](Data::PreviewState state) {
// Save links from _field to _parsedLinks without generating preview.
_previewState = Data::PreviewState::Cancelled;
fieldLinksParser->parseNow();
*parsedLinks = fieldLinksParser->list().current();
_previewState = state;
};
fieldLinksParser->list().changes(
) | rpl::start_with_next([=](QStringList &&parsed) {
if (_previewState == Data::PreviewState::EmptyOnEdit
&& *parsedLinks != parsed) {
_previewState = Data::PreviewState::Allowed;
}
*parsedLinks = std::move(parsed);
checkPreview();

View file

@ -34,6 +34,7 @@ namespace Data {
struct MessagePosition;
struct Draft;
class DraftKey;
enum class PreviewState : char;
} // namespace Data
namespace InlineBots {
@ -307,7 +308,8 @@ private:
bool _botCommandShown = false;
Fn<void()> _previewCancel;
bool _previewCancelled = false;
Fn<void(Data::PreviewState)> _previewSetState;
Data::PreviewState _previewState = Data::PreviewState();
rpl::lifetime _uploaderSubscriptions;

View file

@ -902,11 +902,7 @@ void RepliesWidget::send(Api::SendOptions options) {
return;
}
const auto webPageId = _composeControls->webPageId();/* _previewCancelled
? CancelledWebPageId
: ((_previewData && _previewData->pendingTill >= 0)
? _previewData->id
: WebPageId(0));*/
const auto webPageId = _composeControls->webPageId();
auto message = ApiWrap::MessageToSend(_history);
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();

View file

@ -523,11 +523,7 @@ void ScheduledWidget::send() {
}
void ScheduledWidget::send(Api::SendOptions options) {
const auto webPageId = _composeControls->webPageId();/* _previewCancelled
? CancelledWebPageId
: ((_previewData && _previewData->pendingTill >= 0)
? _previewData->id
: WebPageId(0));*/
const auto webPageId = _composeControls->webPageId();
auto message = ApiWrap::MessageToSend(_history);
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();

View file

@ -548,8 +548,11 @@ bool MainWidget::shareUrl(
QFIXED_MAX
};
auto history = peer->owner().history(peer);
history->setLocalDraft(
std::make_unique<Data::Draft>(textWithTags, 0, cursor, false));
history->setLocalDraft(std::make_unique<Data::Draft>(
textWithTags,
0,
cursor,
Data::PreviewState::Allowed));
history->clearLocalEditDraft();
history->session().changes().historyUpdated(
history,
@ -576,7 +579,11 @@ bool MainWidget::inlineSwitchChosen(PeerId peerId, const QString &botAndQuery) {
const auto h = peer->owner().history(peer);
TextWithTags textWithTags = { botAndQuery, TextWithTags::Tags() };
MessageCursor cursor = { botAndQuery.size(), botAndQuery.size(), QFIXED_MAX };
h->setLocalDraft(std::make_unique<Data::Draft>(textWithTags, 0, cursor, false));
h->setLocalDraft(std::make_unique<Data::Draft>(
textWithTags,
0,
cursor,
Data::PreviewState::Allowed));
h->clearLocalEditDraft();
h->session().changes().historyUpdated(
h,

View file

@ -958,7 +958,7 @@ void EnumerateDrafts(
key,
draft->msgId,
draft->textWithTags,
draft->previewCancelled,
draft->previewState,
draft->cursor);
}
if (replaceKey
@ -969,7 +969,7 @@ void EnumerateDrafts(
replaceKey,
replaceDraft.msgId,
replaceDraft.textWithTags,
replaceDraft.previewCancelled,
replaceDraft.previewState,
replaceCursor);
}
}
@ -1017,12 +1017,12 @@ void Account::writeDrafts(
auto&&, // key
MsgId, // msgId
const TextWithTags &text,
bool, // previewCancelled
Data::PreviewState,
auto&&) { // cursor
size += sizeof(qint32) // key
+ Serialize::stringSize(text.text)
+ sizeof(quint32) + TextUtilities::SerializeTagsSize(text.tags)
+ 2 * sizeof(qint32); // msgId, previewCancelled
+ 2 * sizeof(qint32); // msgId, previewState
};
EnumerateDrafts(
map,
@ -1043,14 +1043,14 @@ void Account::writeDrafts(
const Data::DraftKey &key,
MsgId msgId,
const TextWithTags &text,
bool previewCancelled,
Data::PreviewState previewState,
auto&&) { // cursor
data.stream
<< key.serialize()
<< text.text
<< TextUtilities::SerializeTags(text.tags)
<< qint32(msgId)
<< qint32(previewCancelled ? 1 : 0);
<< qint32(previewState);
};
EnumerateDrafts(
map,
@ -1109,7 +1109,7 @@ void Account::writeDraftCursors(
auto&&, // key
MsgId, // msgId
auto&&, // text
bool, // previewCancelled
Data::PreviewState,
const MessageCursor &cursor) { // cursor
data.stream
<< qint32(cursor.position)
@ -1249,23 +1249,29 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
for (auto i = 0; i != count; ++i) {
TextWithTags data;
QByteArray tagsSerialized;
qint32 keyValue = 0, messageId = 0, previewCancelled = 0;
qint32 keyValue = 0, messageId = 0, uncheckedPreviewState = 0;
draft.stream
>> keyValue
>> data.text
>> tagsSerialized
>> messageId
>> previewCancelled;
>> uncheckedPreviewState;
data.tags = TextUtilities::DeserializeTags(
tagsSerialized,
data.text.size());
auto previewState = Data::PreviewState::Allowed;
switch (static_cast<Data::PreviewState>(uncheckedPreviewState)) {
case Data::PreviewState::Cancelled:
case Data::PreviewState::EmptyOnEdit:
previewState = Data::PreviewState(uncheckedPreviewState);
}
const auto key = Data::DraftKey::FromSerialized(keyValue);
if (key && key != Data::DraftKey::Cloud()) {
map.emplace(key, std::make_unique<Data::Draft>(
data,
messageId,
MessageCursor(),
previewCancelled));
previewState));
}
}
if (draft.stream.status() != QDataStream::Ok) {
@ -1326,14 +1332,18 @@ void Account::readDraftsWithCursorsLegacy(
msgData,
msgReplyTo,
MessageCursor(),
msgPreviewCancelled));
(msgPreviewCancelled
? Data::PreviewState::Cancelled
: Data::PreviewState::Allowed)));
}
if (editMsgId) {
map.emplace(Data::DraftKey::LocalEdit(), std::make_unique<Data::Draft>(
editData,
editMsgId,
MessageCursor(),
editPreviewCancelled));
(editPreviewCancelled
? Data::PreviewState::Cancelled
: Data::PreviewState::Allowed)));
}
readDraftCursors(peerId, map);
history->setDraftsMap(std::move(map));

View file

@ -52,7 +52,7 @@ enum class StartResult : uchar;
struct MessageDraft {
MsgId msgId = 0;
TextWithTags textWithTags;
bool previewCancelled = false;
Data::PreviewState previewState = Data::PreviewState::Allowed;
};
class Account final {

View file

@ -155,7 +155,7 @@ Data::Draft OccupiedDraft(const QString &normalizedName) {
+ normalizedName },
MsgId(0),
MessageCursor(),
false
Data::PreviewState::Allowed
};
}