mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
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:
parent
fc4ed2ff91
commit
8f0e23bb25
16 changed files with 159 additions and 82 deletions
|
@ -2449,7 +2449,7 @@ void ApiWrap::saveDraftsToCloud() {
|
||||||
|
|
||||||
auto flags = MTPmessages_SaveDraft::Flags(0);
|
auto flags = MTPmessages_SaveDraft::Flags(0);
|
||||||
auto &textWithTags = cloudDraft->textWithTags;
|
auto &textWithTags = cloudDraft->textWithTags;
|
||||||
if (cloudDraft->previewCancelled) {
|
if (cloudDraft->previewState != Data::PreviewState::Allowed) {
|
||||||
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
|
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
|
||||||
}
|
}
|
||||||
if (cloudDraft->msgId) {
|
if (cloudDraft->msgId) {
|
||||||
|
|
|
@ -501,6 +501,11 @@ MessageLinksParser::MessageLinksParser(not_null<Ui::InputField*> field)
|
||||||
_field->installEventFilter(this);
|
_field->installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageLinksParser::parseNow() {
|
||||||
|
_timer.cancel();
|
||||||
|
parse();
|
||||||
|
}
|
||||||
|
|
||||||
bool MessageLinksParser::eventFilter(QObject *object, QEvent *event) {
|
bool MessageLinksParser::eventFilter(QObject *object, QEvent *event) {
|
||||||
if (object == _field) {
|
if (object == _field) {
|
||||||
if (event->type() == QEvent::KeyPress) {
|
if (event->type() == QEvent::KeyPress) {
|
||||||
|
|
|
@ -71,7 +71,9 @@ class MessageLinksParser : private QObject {
|
||||||
public:
|
public:
|
||||||
MessageLinksParser(not_null<Ui::InputField*> field);
|
MessageLinksParser(not_null<Ui::InputField*> field);
|
||||||
|
|
||||||
const rpl::variable<QStringList> &list() const;
|
void parseNow();
|
||||||
|
|
||||||
|
[[nodiscard]] const rpl::variable<QStringList> &list() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
|
|
|
@ -18,32 +18,29 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
namespace {
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
Draft::Draft(
|
Draft::Draft(
|
||||||
const TextWithTags &textWithTags,
|
const TextWithTags &textWithTags,
|
||||||
MsgId msgId,
|
MsgId msgId,
|
||||||
const MessageCursor &cursor,
|
const MessageCursor &cursor,
|
||||||
bool previewCancelled,
|
PreviewState previewState,
|
||||||
mtpRequestId saveRequestId)
|
mtpRequestId saveRequestId)
|
||||||
: textWithTags(textWithTags)
|
: textWithTags(textWithTags)
|
||||||
, msgId(msgId)
|
, msgId(msgId)
|
||||||
, cursor(cursor)
|
, cursor(cursor)
|
||||||
, previewCancelled(previewCancelled)
|
, previewState(previewState)
|
||||||
, saveRequestId(saveRequestId) {
|
, saveRequestId(saveRequestId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Draft::Draft(
|
Draft::Draft(
|
||||||
not_null<const Ui::InputField*> field,
|
not_null<const Ui::InputField*> field,
|
||||||
MsgId msgId,
|
MsgId msgId,
|
||||||
bool previewCancelled,
|
PreviewState previewState,
|
||||||
mtpRequestId saveRequestId)
|
mtpRequestId saveRequestId)
|
||||||
: textWithTags(field->getTextWithTags())
|
: textWithTags(field->getTextWithTags())
|
||||||
, msgId(msgId)
|
, msgId(msgId)
|
||||||
, cursor(field)
|
, cursor(field)
|
||||||
, previewCancelled(previewCancelled) {
|
, previewState(previewState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyPeerCloudDraft(
|
void ApplyPeerCloudDraft(
|
||||||
|
@ -66,7 +63,9 @@ void ApplyPeerCloudDraft(
|
||||||
textWithTags,
|
textWithTags,
|
||||||
replyTo,
|
replyTo,
|
||||||
MessageCursor(QFIXED_MAX, QFIXED_MAX, QFIXED_MAX),
|
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;
|
cloudDraft->date = draft.vdate().v;
|
||||||
|
|
||||||
history->setCloudDraft(std::move(cloudDraft));
|
history->setCloudDraft(std::move(cloudDraft));
|
||||||
|
|
|
@ -26,25 +26,31 @@ void ClearPeerCloudDraft(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
TimeId date);
|
TimeId date);
|
||||||
|
|
||||||
|
enum class PreviewState : char {
|
||||||
|
Allowed,
|
||||||
|
Cancelled,
|
||||||
|
EmptyOnEdit,
|
||||||
|
};
|
||||||
|
|
||||||
struct Draft {
|
struct Draft {
|
||||||
Draft() = default;
|
Draft() = default;
|
||||||
Draft(
|
Draft(
|
||||||
const TextWithTags &textWithTags,
|
const TextWithTags &textWithTags,
|
||||||
MsgId msgId,
|
MsgId msgId,
|
||||||
const MessageCursor &cursor,
|
const MessageCursor &cursor,
|
||||||
bool previewCancelled,
|
PreviewState previewState,
|
||||||
mtpRequestId saveRequestId = 0);
|
mtpRequestId saveRequestId = 0);
|
||||||
Draft(
|
Draft(
|
||||||
not_null<const Ui::InputField*> field,
|
not_null<const Ui::InputField*> field,
|
||||||
MsgId msgId,
|
MsgId msgId,
|
||||||
bool previewCancelled,
|
PreviewState previewState,
|
||||||
mtpRequestId saveRequestId = 0);
|
mtpRequestId saveRequestId = 0);
|
||||||
|
|
||||||
TimeId date = 0;
|
TimeId date = 0;
|
||||||
TextWithTags textWithTags;
|
TextWithTags textWithTags;
|
||||||
MsgId msgId = 0; // replyToId for message draft, editMsgId for edit draft
|
MsgId msgId = 0; // replyToId for message draft, editMsgId for edit draft
|
||||||
MessageCursor cursor;
|
MessageCursor cursor;
|
||||||
bool previewCancelled = false;
|
PreviewState previewState = PreviewState::Allowed;
|
||||||
mtpRequestId saveRequestId = 0;
|
mtpRequestId saveRequestId = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -144,7 +150,7 @@ inline bool draftsAreEqual(const Draft *a, const Draft *b) {
|
||||||
|
|
||||||
return (a->textWithTags == b->textWithTags)
|
return (a->textWithTags == b->textWithTags)
|
||||||
&& (a->msgId == b->msgId)
|
&& (a->msgId == b->msgId)
|
||||||
&& (a->previewCancelled == b->previewCancelled);
|
&& (a->previewState == b->previewState);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -215,13 +215,13 @@ void History::createLocalDraftFromCloud() {
|
||||||
draft->textWithTags,
|
draft->textWithTags,
|
||||||
draft->msgId,
|
draft->msgId,
|
||||||
draft->cursor,
|
draft->cursor,
|
||||||
draft->previewCancelled));
|
draft->previewState));
|
||||||
existing = localDraft();
|
existing = localDraft();
|
||||||
} else if (existing != draft) {
|
} else if (existing != draft) {
|
||||||
existing->textWithTags = draft->textWithTags;
|
existing->textWithTags = draft->textWithTags;
|
||||||
existing->msgId = draft->msgId;
|
existing->msgId = draft->msgId;
|
||||||
existing->cursor = draft->cursor;
|
existing->cursor = draft->cursor;
|
||||||
existing->previewCancelled = draft->previewCancelled;
|
existing->previewState = draft->previewState;
|
||||||
}
|
}
|
||||||
existing->date = draft->date;
|
existing->date = draft->date;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ Data::Draft *History::createCloudDraft(const Data::Draft *fromDraft) {
|
||||||
TextWithTags(),
|
TextWithTags(),
|
||||||
0,
|
0,
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
false));
|
Data::PreviewState::Allowed));
|
||||||
cloudDraft()->date = TimeId(0);
|
cloudDraft()->date = TimeId(0);
|
||||||
} else {
|
} else {
|
||||||
auto existing = cloudDraft();
|
auto existing = cloudDraft();
|
||||||
|
@ -289,13 +289,13 @@ Data::Draft *History::createCloudDraft(const Data::Draft *fromDraft) {
|
||||||
fromDraft->textWithTags,
|
fromDraft->textWithTags,
|
||||||
fromDraft->msgId,
|
fromDraft->msgId,
|
||||||
fromDraft->cursor,
|
fromDraft->cursor,
|
||||||
fromDraft->previewCancelled));
|
fromDraft->previewState));
|
||||||
existing = cloudDraft();
|
existing = cloudDraft();
|
||||||
} else if (existing != fromDraft) {
|
} else if (existing != fromDraft) {
|
||||||
existing->textWithTags = fromDraft->textWithTags;
|
existing->textWithTags = fromDraft->textWithTags;
|
||||||
existing->msgId = fromDraft->msgId;
|
existing->msgId = fromDraft->msgId;
|
||||||
existing->cursor = fromDraft->cursor;
|
existing->cursor = fromDraft->cursor;
|
||||||
existing->previewCancelled = fromDraft->previewCancelled;
|
existing->previewState = fromDraft->previewState;
|
||||||
}
|
}
|
||||||
existing->date = base::unixtime::now();
|
existing->date = base::unixtime::now();
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,6 +174,7 @@ HistoryWidget::HistoryWidget(
|
||||||
, _updateEditTimeLeftDisplay([=] { updateField(); })
|
, _updateEditTimeLeftDisplay([=] { updateField(); })
|
||||||
, _fieldBarCancel(this, st::historyReplyCancel)
|
, _fieldBarCancel(this, st::historyReplyCancel)
|
||||||
, _previewTimer([=] { requestPreview(); })
|
, _previewTimer([=] { requestPreview(); })
|
||||||
|
, _previewState(Data::PreviewState::Allowed)
|
||||||
, _topBar(this, controller)
|
, _topBar(this, controller)
|
||||||
, _scroll(this, st::historyScroll, false)
|
, _scroll(this, st::historyScroll, false)
|
||||||
, _updateHistoryItems([=] { updateHistoryItemsByTimer(); })
|
, _updateHistoryItems([=] { updateHistoryItemsByTimer(); })
|
||||||
|
@ -335,6 +336,10 @@ HistoryWidget::HistoryWidget(
|
||||||
_fieldLinksParser = std::make_unique<MessageLinksParser>(_field);
|
_fieldLinksParser = std::make_unique<MessageLinksParser>(_field);
|
||||||
_fieldLinksParser->list().changes(
|
_fieldLinksParser->list().changes(
|
||||||
) | rpl::start_with_next([=](QStringList &&parsed) {
|
) | rpl::start_with_next([=](QStringList &&parsed) {
|
||||||
|
if (_previewState == Data::PreviewState::EmptyOnEdit
|
||||||
|
&& _parsedLinks != parsed) {
|
||||||
|
_previewState = Data::PreviewState::Allowed;
|
||||||
|
}
|
||||||
_parsedLinks = std::move(parsed);
|
_parsedLinks = std::move(parsed);
|
||||||
checkPreview();
|
checkPreview();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
@ -1328,7 +1333,7 @@ void HistoryWidget::fieldChanged() {
|
||||||
|
|
||||||
updateSendButtonType();
|
updateSendButtonType();
|
||||||
if (!HasSendText(_field)) {
|
if (!HasSendText(_field)) {
|
||||||
_previewCancelled = false;
|
_previewState = Data::PreviewState::Allowed;
|
||||||
}
|
}
|
||||||
if (updateCmdStartShown()) {
|
if (updateCmdStartShown()) {
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
|
@ -1377,10 +1382,17 @@ void HistoryWidget::saveFieldToHistoryLocalDraft() {
|
||||||
if (!_history) return;
|
if (!_history) return;
|
||||||
|
|
||||||
if (_editMsgId) {
|
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 {
|
} else {
|
||||||
if (_replyToId || !_field->empty()) {
|
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 {
|
} else {
|
||||||
_history->clearLocalDraft();
|
_history->clearLocalDraft();
|
||||||
}
|
}
|
||||||
|
@ -1401,7 +1413,7 @@ void HistoryWidget::writeDraftTexts() {
|
||||||
Storage::MessageDraft{
|
Storage::MessageDraft{
|
||||||
_editMsgId ? _editMsgId : _replyToId,
|
_editMsgId ? _editMsgId : _replyToId,
|
||||||
_field->getTextWithTags(),
|
_field->getTextWithTags(),
|
||||||
_previewCancelled,
|
_previewState,
|
||||||
});
|
});
|
||||||
if (_migrated) {
|
if (_migrated) {
|
||||||
_migrated->clearDrafts();
|
_migrated->clearDrafts();
|
||||||
|
@ -1476,7 +1488,11 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query, U
|
||||||
if (_history) {
|
if (_history) {
|
||||||
TextWithTags textWithTags = { '@' + samePeerBot->username + ' ' + query, TextWithTags::Tags() };
|
TextWithTags textWithTags = { '@' + samePeerBot->username + ' ' + query, TextWithTags::Tags() };
|
||||||
MessageCursor cursor = { textWithTags.text.size(), textWithTags.text.size(), QFIXED_MAX };
|
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();
|
applyDraft();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1497,7 +1513,7 @@ bool HistoryWidget::notify_switchInlineBotButtonReceived(const QString &query, U
|
||||||
textWithTags,
|
textWithTags,
|
||||||
to.currentReplyToId,
|
to.currentReplyToId,
|
||||||
cursor,
|
cursor,
|
||||||
false);
|
Data::PreviewState::Allowed);
|
||||||
|
|
||||||
if (to.section == Section::Replies) {
|
if (to.section == Section::Replies) {
|
||||||
history->setDraft(
|
history->setDraft(
|
||||||
|
@ -1653,8 +1669,15 @@ void HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
setFieldText(draft->textWithTags, 0, fieldHistoryAction);
|
setFieldText(draft->textWithTags, 0, fieldHistoryAction);
|
||||||
_field->setFocus();
|
_field->setFocus();
|
||||||
draft->cursor.applyTo(_field);
|
draft->cursor.applyTo(_field);
|
||||||
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
|
_textUpdateEvents = TextUpdateEvent::SaveDraft
|
||||||
_previewCancelled = draft->previewCancelled;
|
| 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;
|
_replyEditMsg = nullptr;
|
||||||
if (const auto editDraft = _history->localEditDraft()) {
|
if (const auto editDraft = _history->localEditDraft()) {
|
||||||
_editMsgId = editDraft->msgId;
|
_editMsgId = editDraft->msgId;
|
||||||
|
@ -2986,7 +3009,7 @@ void HistoryWidget::saveEditMsg() {
|
||||||
cancelEdit();
|
cancelEdit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto webPageId = _previewCancelled
|
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
|
||||||
? CancelledWebPageId
|
? CancelledWebPageId
|
||||||
: ((_previewData && _previewData->pendingTill >= 0)
|
: ((_previewData && _previewData->pendingTill >= 0)
|
||||||
? _previewData->id
|
? _previewData->id
|
||||||
|
@ -3106,7 +3129,7 @@ void HistoryWidget::send(Api::SendOptions options) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto webPageId = _previewCancelled
|
const auto webPageId = (_previewState != Data::PreviewState::Allowed)
|
||||||
? CancelledWebPageId
|
? CancelledWebPageId
|
||||||
: ((_previewData && _previewData->pendingTill >= 0)
|
: ((_previewData && _previewData->pendingTill >= 0)
|
||||||
? _previewData->id
|
? _previewData->id
|
||||||
|
@ -5580,7 +5603,7 @@ void HistoryWidget::setFieldText(
|
||||||
| TextUpdateEvent::SendTyping;
|
| TextUpdateEvent::SendTyping;
|
||||||
|
|
||||||
previewCancel();
|
previewCancel();
|
||||||
_previewCancelled = false;
|
_previewState = Data::PreviewState::Allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::clearFieldText(
|
void HistoryWidget::clearFieldText(
|
||||||
|
@ -5623,7 +5646,7 @@ void HistoryWidget::replyToMessage(not_null<HistoryItem*> item) {
|
||||||
TextWithTags(),
|
TextWithTags(),
|
||||||
item->id,
|
item->id,
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
false));
|
Data::PreviewState::Allowed));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_replyEditMsg = item;
|
_replyEditMsg = item;
|
||||||
|
@ -5670,7 +5693,7 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
|
||||||
_history->setLocalDraft(std::make_unique<Data::Draft>(
|
_history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||||
_field,
|
_field,
|
||||||
_replyToId,
|
_replyToId,
|
||||||
_previewCancelled));
|
_previewState));
|
||||||
} else {
|
} else {
|
||||||
_history->clearLocalDraft();
|
_history->clearLocalDraft();
|
||||||
}
|
}
|
||||||
|
@ -5688,12 +5711,14 @@ void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}();
|
}();
|
||||||
const auto previewCancelled = !previewPage;
|
const auto previewState = previewPage
|
||||||
|
? Data::PreviewState::Allowed
|
||||||
|
: Data::PreviewState::EmptyOnEdit;
|
||||||
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
|
_history->setLocalEditDraft(std::make_unique<Data::Draft>(
|
||||||
editData,
|
editData,
|
||||||
item->id,
|
item->id,
|
||||||
cursor,
|
cursor,
|
||||||
previewCancelled));
|
previewState));
|
||||||
applyDraft();
|
applyDraft();
|
||||||
|
|
||||||
_previewData = previewPage;
|
_previewData = previewPage;
|
||||||
|
@ -5853,7 +5878,7 @@ void HistoryWidget::cancelFieldAreaState() {
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
_replyForwardPressed = false;
|
_replyForwardPressed = false;
|
||||||
if (_previewData && _previewData->pendingTill >= 0) {
|
if (_previewData && _previewData->pendingTill >= 0) {
|
||||||
_previewCancelled = true;
|
_previewState = Data::PreviewState::Cancelled;
|
||||||
previewCancel();
|
previewCancel();
|
||||||
|
|
||||||
_saveDraftText = true;
|
_saveDraftText = true;
|
||||||
|
@ -5881,7 +5906,7 @@ void HistoryWidget::checkPreview() {
|
||||||
const auto previewRestricted = [&] {
|
const auto previewRestricted = [&] {
|
||||||
return _peer && _peer->amRestricted(ChatRestriction::f_embed_links);
|
return _peer && _peer->amRestricted(ChatRestriction::f_embed_links);
|
||||||
}();
|
}();
|
||||||
if (_previewCancelled || previewRestricted) {
|
if (_previewState != Data::PreviewState::Allowed || previewRestricted) {
|
||||||
previewCancel();
|
previewCancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5929,7 +5954,10 @@ void HistoryWidget::requestPreview() {
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtpRequestId req) {
|
void HistoryWidget::gotPreview(
|
||||||
|
QString links,
|
||||||
|
const MTPMessageMedia &result,
|
||||||
|
mtpRequestId req) {
|
||||||
if (req == _previewRequest) {
|
if (req == _previewRequest) {
|
||||||
_previewRequest = 0;
|
_previewRequest = 0;
|
||||||
}
|
}
|
||||||
|
@ -5937,10 +5965,12 @@ void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtp
|
||||||
const auto &data = result.c_messageMediaWebPage().vwebpage();
|
const auto &data = result.c_messageMediaWebPage().vwebpage();
|
||||||
const auto page = session().data().processWebpage(data);
|
const auto page = session().data().processWebpage(data);
|
||||||
_previewCache.insert(links, page->id);
|
_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;
|
page->pendingTill = -1;
|
||||||
}
|
}
|
||||||
if (links == _previewLinks && !_previewCancelled) {
|
if (links == _previewLinks
|
||||||
|
&& _previewState == Data::PreviewState::Allowed) {
|
||||||
_previewData = (page->id && page->pendingTill >= 0)
|
_previewData = (page->id && page->pendingTill >= 0)
|
||||||
? page.get()
|
? page.get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
@ -5949,7 +5979,8 @@ void HistoryWidget::gotPreview(QString links, const MTPMessageMedia &result, mtp
|
||||||
session().data().sendWebPageGamePollNotifications();
|
session().data().sendWebPageGamePollNotifications();
|
||||||
} else if (result.type() == mtpc_messageMediaEmpty) {
|
} else if (result.type() == mtpc_messageMediaEmpty) {
|
||||||
_previewCache.insert(links, 0);
|
_previewCache.insert(links, 0);
|
||||||
if (links == _previewLinks && !_previewCancelled) {
|
if (links == _previewLinks
|
||||||
|
&& _previewState == Data::PreviewState::Allowed) {
|
||||||
_previewData = nullptr;
|
_previewData = nullptr;
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,10 @@ struct SendingAlbum;
|
||||||
enum class SendMediaType;
|
enum class SendMediaType;
|
||||||
class MessageLinksParser;
|
class MessageLinksParser;
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
enum class PreviewState : char;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
namespace SendMenu {
|
namespace SendMenu {
|
||||||
enum class Type;
|
enum class Type;
|
||||||
} // namespace SendMenu
|
} // namespace SendMenu
|
||||||
|
@ -617,7 +621,7 @@ private:
|
||||||
Ui::Text::String _previewTitle;
|
Ui::Text::String _previewTitle;
|
||||||
Ui::Text::String _previewDescription;
|
Ui::Text::String _previewDescription;
|
||||||
base::Timer _previewTimer;
|
base::Timer _previewTimer;
|
||||||
bool _previewCancelled = false;
|
Data::PreviewState _previewState = Data::PreviewState();
|
||||||
|
|
||||||
bool _replyForwardPressed = false;
|
bool _replyForwardPressed = false;
|
||||||
|
|
||||||
|
|
|
@ -612,7 +612,8 @@ ComposeControls::ComposeControls(
|
||||||
_send,
|
_send,
|
||||||
st::historySendSize.height()))
|
st::historySendSize.height()))
|
||||||
, _sendMenuType(sendMenuType)
|
, _sendMenuType(sendMenuType)
|
||||||
, _saveDraftTimer([=] { saveDraft(); }) {
|
, _saveDraftTimer([=] { saveDraft(); })
|
||||||
|
, _previewState(Data::PreviewState::Allowed) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,7 +866,7 @@ void ComposeControls::setFieldText(
|
||||||
| TextUpdateEvent::SendTyping;
|
| TextUpdateEvent::SendTyping;
|
||||||
|
|
||||||
_previewCancel();
|
_previewCancel();
|
||||||
_previewCancelled = false;
|
_previewState = Data::PreviewState::Allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComposeControls::saveFieldToHistoryLocalDraft() {
|
void ComposeControls::saveFieldToHistoryLocalDraft() {
|
||||||
|
@ -880,7 +881,7 @@ void ComposeControls::saveFieldToHistoryLocalDraft() {
|
||||||
std::make_unique<Data::Draft>(
|
std::make_unique<Data::Draft>(
|
||||||
_field,
|
_field,
|
||||||
_header->getDraftMessageId(),
|
_header->getDraftMessageId(),
|
||||||
_previewCancelled));
|
_previewState));
|
||||||
} else {
|
} else {
|
||||||
_history->clearDraft(draftKeyCurrent());
|
_history->clearDraft(draftKeyCurrent());
|
||||||
}
|
}
|
||||||
|
@ -964,7 +965,7 @@ void ComposeControls::init() {
|
||||||
|
|
||||||
_header->previewCancelled(
|
_header->previewCancelled(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
_previewCancelled = true;
|
_previewState = Data::PreviewState::Cancelled;
|
||||||
_saveDraftText = true;
|
_saveDraftText = true;
|
||||||
_saveDraftStart = crl::now();
|
_saveDraftStart = crl::now();
|
||||||
saveDraft();
|
saveDraft();
|
||||||
|
@ -1224,7 +1225,7 @@ void ComposeControls::fieldChanged() {
|
||||||
}
|
}
|
||||||
updateSendButtonType();
|
updateSendButtonType();
|
||||||
if (!HasSendText(_field)) {
|
if (!HasSendText(_field)) {
|
||||||
_previewCancelled = false;
|
_previewState = Data::PreviewState::Allowed;
|
||||||
}
|
}
|
||||||
if (updateBotCommandShown()) {
|
if (updateBotCommandShown()) {
|
||||||
updateControlsVisibility();
|
updateControlsVisibility();
|
||||||
|
@ -1294,7 +1295,7 @@ void ComposeControls::writeDraftTexts() {
|
||||||
Storage::MessageDraft{
|
Storage::MessageDraft{
|
||||||
_header->getDraftMessageId(),
|
_header->getDraftMessageId(),
|
||||||
_field->getTextWithTags(),
|
_field->getTextWithTags(),
|
||||||
_previewCancelled,
|
_previewState,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1353,7 +1354,8 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
|
||||||
_field->setFocus();
|
_field->setFocus();
|
||||||
draft->cursor.applyTo(_field);
|
draft->cursor.applyTo(_field);
|
||||||
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
|
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
|
||||||
_previewCancelled = draft->previewCancelled;
|
_previewSetState(draft->previewState);
|
||||||
|
|
||||||
if (draft == editDraft) {
|
if (draft == editDraft) {
|
||||||
_header->editMessage({ _history->channelId(), draft->msgId });
|
_header->editMessage({ _history->channelId(), draft->msgId });
|
||||||
_header->replyToMessage({});
|
_header->replyToMessage({});
|
||||||
|
@ -1837,14 +1839,16 @@ void ComposeControls::editMessage(not_null<HistoryItem*> item) {
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}();
|
}();
|
||||||
const auto previewCancelled = !previewPage;
|
const auto previewState = previewPage
|
||||||
|
? Data::PreviewState::Allowed
|
||||||
|
: Data::PreviewState::EmptyOnEdit;
|
||||||
_history->setDraft(
|
_history->setDraft(
|
||||||
draftKey(DraftType::Edit),
|
draftKey(DraftType::Edit),
|
||||||
std::make_unique<Data::Draft>(
|
std::make_unique<Data::Draft>(
|
||||||
editData,
|
editData,
|
||||||
item->id,
|
item->id,
|
||||||
cursor,
|
cursor,
|
||||||
previewCancelled));
|
previewState));
|
||||||
applyDraft();
|
applyDraft();
|
||||||
|
|
||||||
if (_autocomplete) {
|
if (_autocomplete) {
|
||||||
|
@ -1883,7 +1887,7 @@ void ComposeControls::replyToMessage(FullMsgId id) {
|
||||||
TextWithTags(),
|
TextWithTags(),
|
||||||
id.msg,
|
id.msg,
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
false));
|
Data::PreviewState::Allowed));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_header->replyToMessage(id);
|
_header->replyToMessage(id);
|
||||||
|
@ -1995,7 +1999,8 @@ void ComposeControls::initWebpageProcess() {
|
||||||
if (till > 0 && till <= base::unixtime::now()) {
|
if (till > 0 && till <= base::unixtime::now()) {
|
||||||
till = -1;
|
till = -1;
|
||||||
}
|
}
|
||||||
if (links == *previewLinks && !_previewCancelled) {
|
if (links == *previewLinks
|
||||||
|
&& _previewState == Data::PreviewState::Allowed) {
|
||||||
*previewData = (page->id && page->pendingTill >= 0)
|
*previewData = (page->id && page->pendingTill >= 0)
|
||||||
? page.get()
|
? page.get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
@ -2003,7 +2008,8 @@ void ComposeControls::initWebpageProcess() {
|
||||||
}
|
}
|
||||||
}, [=](const MTPDmessageMediaEmpty &d) {
|
}, [=](const MTPDmessageMediaEmpty &d) {
|
||||||
previewCache->insert({ links, 0 });
|
previewCache->insert({ links, 0 });
|
||||||
if (links == *previewLinks && !_previewCancelled) {
|
if (links == *previewLinks
|
||||||
|
&& _previewState == Data::PreviewState::Allowed) {
|
||||||
*previewData = nullptr;
|
*previewData = nullptr;
|
||||||
updatePreview();
|
updatePreview();
|
||||||
}
|
}
|
||||||
|
@ -2032,7 +2038,8 @@ void ComposeControls::initWebpageProcess() {
|
||||||
const auto checkPreview = crl::guard(_wrap.get(), [=] {
|
const auto checkPreview = crl::guard(_wrap.get(), [=] {
|
||||||
const auto previewRestricted = peer
|
const auto previewRestricted = peer
|
||||||
&& peer->amRestricted(ChatRestriction::f_embed_links);
|
&& peer->amRestricted(ChatRestriction::f_embed_links);
|
||||||
if (_previewCancelled || previewRestricted) {
|
if (_previewState != Data::PreviewState::Allowed
|
||||||
|
|| previewRestricted) {
|
||||||
_previewCancel();
|
_previewCancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2105,8 +2112,20 @@ void ComposeControls::initWebpageProcess() {
|
||||||
const auto fieldLinksParser =
|
const auto fieldLinksParser =
|
||||||
lifetime.make_state<MessageLinksParser>(_field);
|
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(
|
fieldLinksParser->list().changes(
|
||||||
) | rpl::start_with_next([=](QStringList &&parsed) {
|
) | rpl::start_with_next([=](QStringList &&parsed) {
|
||||||
|
if (_previewState == Data::PreviewState::EmptyOnEdit
|
||||||
|
&& *parsedLinks != parsed) {
|
||||||
|
_previewState = Data::PreviewState::Allowed;
|
||||||
|
}
|
||||||
*parsedLinks = std::move(parsed);
|
*parsedLinks = std::move(parsed);
|
||||||
|
|
||||||
checkPreview();
|
checkPreview();
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace Data {
|
||||||
struct MessagePosition;
|
struct MessagePosition;
|
||||||
struct Draft;
|
struct Draft;
|
||||||
class DraftKey;
|
class DraftKey;
|
||||||
|
enum class PreviewState : char;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
namespace InlineBots {
|
namespace InlineBots {
|
||||||
|
@ -307,7 +308,8 @@ private:
|
||||||
bool _botCommandShown = false;
|
bool _botCommandShown = false;
|
||||||
|
|
||||||
Fn<void()> _previewCancel;
|
Fn<void()> _previewCancel;
|
||||||
bool _previewCancelled = false;
|
Fn<void(Data::PreviewState)> _previewSetState;
|
||||||
|
Data::PreviewState _previewState = Data::PreviewState();
|
||||||
|
|
||||||
rpl::lifetime _uploaderSubscriptions;
|
rpl::lifetime _uploaderSubscriptions;
|
||||||
|
|
||||||
|
|
|
@ -902,11 +902,7 @@ void RepliesWidget::send(Api::SendOptions options) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto webPageId = _composeControls->webPageId();/* _previewCancelled
|
const auto webPageId = _composeControls->webPageId();
|
||||||
? CancelledWebPageId
|
|
||||||
: ((_previewData && _previewData->pendingTill >= 0)
|
|
||||||
? _previewData->id
|
|
||||||
: WebPageId(0));*/
|
|
||||||
|
|
||||||
auto message = ApiWrap::MessageToSend(_history);
|
auto message = ApiWrap::MessageToSend(_history);
|
||||||
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
||||||
|
|
|
@ -523,11 +523,7 @@ void ScheduledWidget::send() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScheduledWidget::send(Api::SendOptions options) {
|
void ScheduledWidget::send(Api::SendOptions options) {
|
||||||
const auto webPageId = _composeControls->webPageId();/* _previewCancelled
|
const auto webPageId = _composeControls->webPageId();
|
||||||
? CancelledWebPageId
|
|
||||||
: ((_previewData && _previewData->pendingTill >= 0)
|
|
||||||
? _previewData->id
|
|
||||||
: WebPageId(0));*/
|
|
||||||
|
|
||||||
auto message = ApiWrap::MessageToSend(_history);
|
auto message = ApiWrap::MessageToSend(_history);
|
||||||
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
message.textWithTags = _composeControls->getTextWithAppliedMarkdown();
|
||||||
|
|
|
@ -548,8 +548,11 @@ bool MainWidget::shareUrl(
|
||||||
QFIXED_MAX
|
QFIXED_MAX
|
||||||
};
|
};
|
||||||
auto history = peer->owner().history(peer);
|
auto history = peer->owner().history(peer);
|
||||||
history->setLocalDraft(
|
history->setLocalDraft(std::make_unique<Data::Draft>(
|
||||||
std::make_unique<Data::Draft>(textWithTags, 0, cursor, false));
|
textWithTags,
|
||||||
|
0,
|
||||||
|
cursor,
|
||||||
|
Data::PreviewState::Allowed));
|
||||||
history->clearLocalEditDraft();
|
history->clearLocalEditDraft();
|
||||||
history->session().changes().historyUpdated(
|
history->session().changes().historyUpdated(
|
||||||
history,
|
history,
|
||||||
|
@ -576,7 +579,11 @@ bool MainWidget::inlineSwitchChosen(PeerId peerId, const QString &botAndQuery) {
|
||||||
const auto h = peer->owner().history(peer);
|
const auto h = peer->owner().history(peer);
|
||||||
TextWithTags textWithTags = { botAndQuery, TextWithTags::Tags() };
|
TextWithTags textWithTags = { botAndQuery, TextWithTags::Tags() };
|
||||||
MessageCursor cursor = { botAndQuery.size(), botAndQuery.size(), QFIXED_MAX };
|
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->clearLocalEditDraft();
|
||||||
h->session().changes().historyUpdated(
|
h->session().changes().historyUpdated(
|
||||||
h,
|
h,
|
||||||
|
|
|
@ -958,7 +958,7 @@ void EnumerateDrafts(
|
||||||
key,
|
key,
|
||||||
draft->msgId,
|
draft->msgId,
|
||||||
draft->textWithTags,
|
draft->textWithTags,
|
||||||
draft->previewCancelled,
|
draft->previewState,
|
||||||
draft->cursor);
|
draft->cursor);
|
||||||
}
|
}
|
||||||
if (replaceKey
|
if (replaceKey
|
||||||
|
@ -969,7 +969,7 @@ void EnumerateDrafts(
|
||||||
replaceKey,
|
replaceKey,
|
||||||
replaceDraft.msgId,
|
replaceDraft.msgId,
|
||||||
replaceDraft.textWithTags,
|
replaceDraft.textWithTags,
|
||||||
replaceDraft.previewCancelled,
|
replaceDraft.previewState,
|
||||||
replaceCursor);
|
replaceCursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1017,12 +1017,12 @@ void Account::writeDrafts(
|
||||||
auto&&, // key
|
auto&&, // key
|
||||||
MsgId, // msgId
|
MsgId, // msgId
|
||||||
const TextWithTags &text,
|
const TextWithTags &text,
|
||||||
bool, // previewCancelled
|
Data::PreviewState,
|
||||||
auto&&) { // cursor
|
auto&&) { // cursor
|
||||||
size += sizeof(qint32) // key
|
size += sizeof(qint32) // key
|
||||||
+ Serialize::stringSize(text.text)
|
+ Serialize::stringSize(text.text)
|
||||||
+ sizeof(quint32) + TextUtilities::SerializeTagsSize(text.tags)
|
+ sizeof(quint32) + TextUtilities::SerializeTagsSize(text.tags)
|
||||||
+ 2 * sizeof(qint32); // msgId, previewCancelled
|
+ 2 * sizeof(qint32); // msgId, previewState
|
||||||
};
|
};
|
||||||
EnumerateDrafts(
|
EnumerateDrafts(
|
||||||
map,
|
map,
|
||||||
|
@ -1043,14 +1043,14 @@ void Account::writeDrafts(
|
||||||
const Data::DraftKey &key,
|
const Data::DraftKey &key,
|
||||||
MsgId msgId,
|
MsgId msgId,
|
||||||
const TextWithTags &text,
|
const TextWithTags &text,
|
||||||
bool previewCancelled,
|
Data::PreviewState previewState,
|
||||||
auto&&) { // cursor
|
auto&&) { // cursor
|
||||||
data.stream
|
data.stream
|
||||||
<< key.serialize()
|
<< key.serialize()
|
||||||
<< text.text
|
<< text.text
|
||||||
<< TextUtilities::SerializeTags(text.tags)
|
<< TextUtilities::SerializeTags(text.tags)
|
||||||
<< qint32(msgId)
|
<< qint32(msgId)
|
||||||
<< qint32(previewCancelled ? 1 : 0);
|
<< qint32(previewState);
|
||||||
};
|
};
|
||||||
EnumerateDrafts(
|
EnumerateDrafts(
|
||||||
map,
|
map,
|
||||||
|
@ -1109,7 +1109,7 @@ void Account::writeDraftCursors(
|
||||||
auto&&, // key
|
auto&&, // key
|
||||||
MsgId, // msgId
|
MsgId, // msgId
|
||||||
auto&&, // text
|
auto&&, // text
|
||||||
bool, // previewCancelled
|
Data::PreviewState,
|
||||||
const MessageCursor &cursor) { // cursor
|
const MessageCursor &cursor) { // cursor
|
||||||
data.stream
|
data.stream
|
||||||
<< qint32(cursor.position)
|
<< qint32(cursor.position)
|
||||||
|
@ -1249,23 +1249,29 @@ void Account::readDraftsWithCursors(not_null<History*> history) {
|
||||||
for (auto i = 0; i != count; ++i) {
|
for (auto i = 0; i != count; ++i) {
|
||||||
TextWithTags data;
|
TextWithTags data;
|
||||||
QByteArray tagsSerialized;
|
QByteArray tagsSerialized;
|
||||||
qint32 keyValue = 0, messageId = 0, previewCancelled = 0;
|
qint32 keyValue = 0, messageId = 0, uncheckedPreviewState = 0;
|
||||||
draft.stream
|
draft.stream
|
||||||
>> keyValue
|
>> keyValue
|
||||||
>> data.text
|
>> data.text
|
||||||
>> tagsSerialized
|
>> tagsSerialized
|
||||||
>> messageId
|
>> messageId
|
||||||
>> previewCancelled;
|
>> uncheckedPreviewState;
|
||||||
data.tags = TextUtilities::DeserializeTags(
|
data.tags = TextUtilities::DeserializeTags(
|
||||||
tagsSerialized,
|
tagsSerialized,
|
||||||
data.text.size());
|
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);
|
const auto key = Data::DraftKey::FromSerialized(keyValue);
|
||||||
if (key && key != Data::DraftKey::Cloud()) {
|
if (key && key != Data::DraftKey::Cloud()) {
|
||||||
map.emplace(key, std::make_unique<Data::Draft>(
|
map.emplace(key, std::make_unique<Data::Draft>(
|
||||||
data,
|
data,
|
||||||
messageId,
|
messageId,
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
previewCancelled));
|
previewState));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (draft.stream.status() != QDataStream::Ok) {
|
if (draft.stream.status() != QDataStream::Ok) {
|
||||||
|
@ -1326,14 +1332,18 @@ void Account::readDraftsWithCursorsLegacy(
|
||||||
msgData,
|
msgData,
|
||||||
msgReplyTo,
|
msgReplyTo,
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
msgPreviewCancelled));
|
(msgPreviewCancelled
|
||||||
|
? Data::PreviewState::Cancelled
|
||||||
|
: Data::PreviewState::Allowed)));
|
||||||
}
|
}
|
||||||
if (editMsgId) {
|
if (editMsgId) {
|
||||||
map.emplace(Data::DraftKey::LocalEdit(), std::make_unique<Data::Draft>(
|
map.emplace(Data::DraftKey::LocalEdit(), std::make_unique<Data::Draft>(
|
||||||
editData,
|
editData,
|
||||||
editMsgId,
|
editMsgId,
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
editPreviewCancelled));
|
(editPreviewCancelled
|
||||||
|
? Data::PreviewState::Cancelled
|
||||||
|
: Data::PreviewState::Allowed)));
|
||||||
}
|
}
|
||||||
readDraftCursors(peerId, map);
|
readDraftCursors(peerId, map);
|
||||||
history->setDraftsMap(std::move(map));
|
history->setDraftsMap(std::move(map));
|
||||||
|
|
|
@ -52,7 +52,7 @@ enum class StartResult : uchar;
|
||||||
struct MessageDraft {
|
struct MessageDraft {
|
||||||
MsgId msgId = 0;
|
MsgId msgId = 0;
|
||||||
TextWithTags textWithTags;
|
TextWithTags textWithTags;
|
||||||
bool previewCancelled = false;
|
Data::PreviewState previewState = Data::PreviewState::Allowed;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Account final {
|
class Account final {
|
||||||
|
|
|
@ -155,7 +155,7 @@ Data::Draft OccupiedDraft(const QString &normalizedName) {
|
||||||
+ normalizedName },
|
+ normalizedName },
|
||||||
MsgId(0),
|
MsgId(0),
|
||||||
MessageCursor(),
|
MessageCursor(),
|
||||||
false
|
Data::PreviewState::Allowed
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue