mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +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 &textWithTags = cloudDraft->textWithTags;
|
||||
if (cloudDraft->previewCancelled) {
|
||||
if (cloudDraft->previewState != Data::PreviewState::Allowed) {
|
||||
flags |= MTPmessages_SaveDraft::Flag::f_no_webpage;
|
||||
}
|
||||
if (cloudDraft->msgId) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -155,7 +155,7 @@ Data::Draft OccupiedDraft(const QString &normalizedName) {
|
|||
+ normalizedName },
|
||||
MsgId(0),
|
||||
MessageCursor(),
|
||||
false
|
||||
Data::PreviewState::Allowed
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue