Message edit: check changes correctly.

This commit is contained in:
John Preston 2023-08-21 11:00:38 +02:00
parent e8e74e7ac7
commit 2f9ae75a65
5 changed files with 75 additions and 14 deletions

View File

@ -279,6 +279,19 @@ TextWithTags PrepareEditText(not_null<HistoryItem*> item) {
};
}
bool EditTextChanged(
not_null<HistoryItem*> item,
const TextWithTags &updated) {
const auto original = PrepareEditText(item);
// Tags can be different for the same entities, because for
// animated emoji each tag contains a different random number.
// So we compare entities instead of tags.
return (original.text != updated.text)
|| (TextUtilities::ConvertTextTagsToEntities(original.tags)
!= TextUtilities::ConvertTextTagsToEntities(updated.tags));
}
Fn<bool(
Ui::InputField::EditLinkSelection selection,
QString text,
@ -595,6 +608,10 @@ void MessageLinksParser::parseNow() {
parse();
}
void MessageLinksParser::setDisabled(bool disabled) {
_disabled = disabled;
}
bool MessageLinksParser::eventFilter(QObject *object, QEvent *event) {
if (object == _field) {
if (event->type() == QEvent::KeyPress) {
@ -625,7 +642,7 @@ void MessageLinksParser::parse() {
const auto &text = textWithTags.text;
const auto &tags = textWithTags.tags;
const auto &markdownTags = _field->getMarkdownTags();
if (text.isEmpty()) {
if (_disabled || text.isEmpty()) {
_list = QStringList();
return;
}

View File

@ -37,8 +37,11 @@ namespace Ui {
class PopupMenu;
} // namespace Ui
QString PrepareMentionTag(not_null<UserData*> user);
TextWithTags PrepareEditText(not_null<HistoryItem*> item);
[[nodiscard]] QString PrepareMentionTag(not_null<UserData*> user);
[[nodiscard]] TextWithTags PrepareEditText(not_null<HistoryItem*> item);
[[nodiscard]] bool EditTextChanged(
not_null<HistoryItem*> item,
const TextWithTags &updated);
Fn<bool(
Ui::InputField::EditLinkSelection selection,
@ -99,6 +102,7 @@ public:
MessageLinksParser(not_null<Ui::InputField*> field);
void parseNow();
void setDisabled(bool disabled);
[[nodiscard]] const rpl::variable<QStringList> &list() const;
@ -126,6 +130,7 @@ private:
not_null<Ui::InputField*> _field;
rpl::variable<QStringList> _list;
int _lastLength = 0;
bool _disabled = false;
base::Timer _timer;
base::qt_connection _connection;

View File

@ -1918,12 +1918,6 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
_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;
_processingReplyItem = _replyEditMsg = nullptr;
_processingReplyId = _replyToId = 0;
setEditMsgId(editMsgId);
@ -1941,6 +1935,19 @@ bool HistoryWidget::applyDraft(FieldHistoryAction fieldHistoryAction) {
_processingReplyId = draft ? draft->msgId : MsgId();
processReply();
}
// Save links from _field to _parsedLinks without generating preview.
_previewState = Data::PreviewState::Cancelled;
if (_editMsgId) {
_fieldLinksParser->setDisabled(!_replyEditMsg
|| (_replyEditMsg->media()
&& !_replyEditMsg->media()->webpage()));
}
_fieldLinksParser->parseNow();
_parsedLinks = _fieldLinksParser->list().current();
_previewState = draft->previewState;
checkPreview();
return true;
}
@ -2473,6 +2480,9 @@ void HistoryWidget::registerDraftSource() {
void HistoryWidget::setEditMsgId(MsgId msgId) {
unregisterDraftSources();
_editMsgId = msgId;
if (_fieldLinksParser && !_editMsgId) {
_fieldLinksParser->setDisabled(false);
}
if (!msgId) {
_canReplaceMedia = false;
}
@ -7608,7 +7618,7 @@ void HistoryWidget::escape() {
cancelInlineBot();
} else if (_editMsgId) {
if (_replyEditMsg
&& PrepareEditText(_replyEditMsg) != _field->getTextWithTags()) {
&& EditTextChanged(_replyEditMsg, _field->getTextWithTags())) {
controller()->show(Ui::MakeConfirmBox({
.text = tr::lng_cancel_edit_post_sure(),
.confirmed = crl::guard(this, [this](Fn<void()> &&close) {

View File

@ -129,7 +129,7 @@ public:
[[nodiscard]] Data::PreviewState state() const;
void setState(Data::PreviewState value);
void refreshState(Data::PreviewState value);
void refreshState(Data::PreviewState value, bool disable);
[[nodiscard]] rpl::producer<> paintRequests() const;
[[nodiscard]] rpl::producer<QString> titleChanges() const;
@ -219,12 +219,16 @@ void WebpageProcessor::setState(Data::PreviewState value) {
_previewState = value;
}
void WebpageProcessor::refreshState(Data::PreviewState value) {
void WebpageProcessor::refreshState(
Data::PreviewState value,
bool disable) {
// Save links from _field to _parsedLinks without generating preview.
_previewState = Data::PreviewState::Cancelled;
_fieldLinksParser.setDisabled(disable);
_fieldLinksParser.parseNow();
_parsedLinks = _fieldLinksParser.list().current();
_previewState = value;
checkPreview();
}
void WebpageProcessor::cancel() {
@ -2163,6 +2167,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
}
_header->editMessage({});
_header->replyToMessage({});
_preview->refreshState(Data::PreviewState::Allowed, false);
_canReplaceMedia = false;
_photoEditMedia = nullptr;
return;
@ -2176,13 +2181,15 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
draft->cursor.applyTo(_field);
_textUpdateEvents = TextUpdateEvent::SaveDraft | TextUpdateEvent::SendTyping;
if (_preview) {
_preview->refreshState(draft->previewState);
const auto disablePreview = (editDraft != nullptr);
_preview->refreshState(draft->previewState, disablePreview);
}
if (draft == editDraft) {
const auto resolve = [=] {
if (const auto item = _history->owner().message(editingId)) {
const auto media = item->media();
const auto disablePreview = media && !media->webpage();
_canReplaceMedia = media && media->allowsEditMedia();
_photoEditMedia = (_canReplaceMedia
&& _regularWindow
@ -2196,6 +2203,7 @@ void ComposeControls::applyDraft(FieldHistoryAction fieldHistoryAction) {
item->fullId());
}
_header->editMessage(editingId, _photoEditMedia != nullptr);
_preview->refreshState(_preview->state(), disablePreview);
return true;
}
_canReplaceMedia = false;
@ -2937,6 +2945,26 @@ void ComposeControls::cancelEditMessage() {
saveDraft();
}
void ComposeControls::maybeCancelEditMessage() {
Expects(_history != nullptr);
const auto item = _history->owner().message(_header->editMsgId());
if (item && EditTextChanged(item, _field->getTextWithTags())) {
const auto guard = _field.get();
_show->show(Ui::MakeConfirmBox({
.text = tr::lng_cancel_edit_post_sure(),
.confirmed = crl::guard(guard, [this](Fn<void()> &&close) {
cancelEditMessage();
close();
}),
.confirmText = tr::lng_cancel_edit_post_yes(),
.cancelText = tr::lng_cancel_edit_post_no(),
}));
} else {
cancelEditMessage();
}
}
void ComposeControls::replyToMessage(FullMsgId id) {
Expects(_history != nullptr);
Expects(draftKeyCurrent() != Data::DraftKey::None());
@ -3012,7 +3040,7 @@ bool ComposeControls::handleCancelRequest() {
_autocomplete->hideAnimated();
return true;
} else if (isEditingMessage()) {
cancelEditMessage();
maybeCancelEditMessage();
return true;
} else if (readyToForward()) {
cancelForward();

View File

@ -196,6 +196,7 @@ public:
void editMessage(FullMsgId id);
void cancelEditMessage();
void maybeCancelEditMessage(); // Confirm if changed and cancel.
void replyToMessage(FullMsgId id);
void cancelReplyMessage();