From 2f9ae75a654571dc4abc4b44aee882d9a165f4c3 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 21 Aug 2023 11:00:38 +0200 Subject: [PATCH] Message edit: check changes correctly. --- .../chat_helpers/message_field.cpp | 19 +++++++++- .../SourceFiles/chat_helpers/message_field.h | 9 +++-- .../SourceFiles/history/history_widget.cpp | 24 +++++++++---- .../history_view_compose_controls.cpp | 36 ++++++++++++++++--- .../controls/history_view_compose_controls.h | 1 + 5 files changed, 75 insertions(+), 14 deletions(-) diff --git a/Telegram/SourceFiles/chat_helpers/message_field.cpp b/Telegram/SourceFiles/chat_helpers/message_field.cpp index b0e263c4a..304c7d3a0 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.cpp +++ b/Telegram/SourceFiles/chat_helpers/message_field.cpp @@ -279,6 +279,19 @@ TextWithTags PrepareEditText(not_null item) { }; } +bool EditTextChanged( + not_null 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)); +} + Fntype() == 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; } diff --git a/Telegram/SourceFiles/chat_helpers/message_field.h b/Telegram/SourceFiles/chat_helpers/message_field.h index 13012557b..acc2808a1 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.h +++ b/Telegram/SourceFiles/chat_helpers/message_field.h @@ -37,8 +37,11 @@ namespace Ui { class PopupMenu; } // namespace Ui -QString PrepareMentionTag(not_null user); -TextWithTags PrepareEditText(not_null item); +[[nodiscard]] QString PrepareMentionTag(not_null user); +[[nodiscard]] TextWithTags PrepareEditText(not_null item); +[[nodiscard]] bool EditTextChanged( + not_null item, + const TextWithTags &updated); Fn field); void parseNow(); + void setDisabled(bool disabled); [[nodiscard]] const rpl::variable &list() const; @@ -126,6 +130,7 @@ private: not_null _field; rpl::variable _list; int _lastLength = 0; + bool _disabled = false; base::Timer _timer; base::qt_connection _connection; diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 28b06d829..3be81b775 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -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 &&close) { diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index 7ad07e755..e6a4717d8 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -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 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 &&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(); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h index 925555832..06d8ae9a8 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.h @@ -196,6 +196,7 @@ public: void editMessage(FullMsgId id); void cancelEditMessage(); + void maybeCancelEditMessage(); // Confirm if changed and cancel. void replyToMessage(FullMsgId id); void cancelReplyMessage();