diff --git a/tools/chatgui/src/inputbar.cpp b/tools/chatgui/src/inputbar.cpp index 1265962d..dbc30fa5 100644 --- a/tools/chatgui/src/inputbar.cpp +++ b/tools/chatgui/src/inputbar.cpp @@ -264,7 +264,7 @@ quint64 InputBar::beginReplySend(const QByteArray& reply, quint64 generation, co const QString& text, const QString& source) { if (reply.isEmpty()) return 0; const quint64 request = ++m_submissionSequence; - m_pendingReplies.insert(request, {generation, target, text, source, m_input->document()->revision()}); + m_pendingReplies.insert(request, {generation, target, text, source, m_input->document()->revision(), m_attachmentRevision}); GUI_DEBUG("reply: submit ch=%s id=%s request=%llu", qPrintable(target), reply.toHex().constData(), (unsigned long long)request); return request; } @@ -281,8 +281,8 @@ void InputBar::submissionResult(quint64 request, bool success) { return; } if (!pending.text.isEmpty() && pending.textRevision == m_input->document()->revision()) m_input->clear(); - if (!pending.source.isEmpty() && pending.source == m_pendingAttachSrc) clearPendingAttachment(); - if (!replySending() && !m_replyFailed) clearReply(); + if (!pending.source.isEmpty() && pending.attachmentRevision == m_attachmentRevision) clearPendingAttachment(); + if (!replySending() && !m_replyFailed && m_input->toPlainText().isEmpty() && m_pendingAttachSrc.isEmpty()) clearReply(); } /* Qt доставляет drop в viewport, а не в QTextEdit/QListView. Родитель composer принимает drop на кнопках. */ @@ -558,6 +558,7 @@ bool InputBar::prepareAttachment(const QString& srcPath, quint64 context) { } m_pendingAttachSrc = srcPath; + ++m_attachmentRevision; m_pendingAttachDest = destPath; m_pendingAttachName = fi.fileName(); m_pendingAttachSize = fi.size(); @@ -576,6 +577,7 @@ bool InputBar::prepareAttachment(const QString& srcPath, quint64 context) { } void InputBar::clearPendingAttachment() { + ++m_attachmentRevision; m_pendingAttachSrc.clear(); m_pendingAttachDest.clear(); m_pendingAttachName.clear(); diff --git a/tools/chatgui/src/inputbar.h b/tools/chatgui/src/inputbar.h index 519cd3d4..07595f3d 100644 --- a/tools/chatgui/src/inputbar.h +++ b/tools/chatgui/src/inputbar.h @@ -66,6 +66,7 @@ private: quint64 generation; QString target, text, source; int textRevision; + quint64 attachmentRevision; }; quint64 beginReplySend(const QByteArray& reply, quint64 generation, const QString& target, const QString& text = {}, const QString& source = {}); @@ -75,6 +76,7 @@ private: QByteArray m_replyTo, m_recordReply; quint64 m_replyGeneration = 0, m_recordReplyGeneration = 0, m_submissionSequence = 0; bool m_replyFailed = false; + quint64 m_attachmentRevision = 0; QHash m_pendingReplies; QTextEdit *m_input; diff --git a/tools/chatgui/tests/test_file_drop.cpp b/tools/chatgui/tests/test_file_drop.cpp index 7e1798bf..206587a1 100644 --- a/tools/chatgui/tests/test_file_drop.cpp +++ b/tools/chatgui/tests/test_file_drop.cpp @@ -87,6 +87,17 @@ private slots: editor->setPlainText("next"); QTest::keyClick(editor, Qt::Key_Return); QVERIFY(texts[1][1].toByteArray().isEmpty()); } + void replyResultKeepsTextWrittenWhileSending() { + InputBar bar(nullptr, nullptr); bar.show(); bar.setRecordingContext("/tmp", "123"); + auto* editor = bar.findChild(); QVERIFY(editor); + const QByteArray original(32, 'a'); bar.setReply(original, "Alice", "Original"); + QSignalSpy sends(&bar, &InputBar::sendMessage); + editor->setPlainText("first"); QTest::keyClick(editor, Qt::Key_Return); + editor->setPlainText("second"); bar.submissionResult(sends[0][2].toULongLong(), true); + QCOMPARE(editor->toPlainText(), QString("second")); QTest::keyClick(editor, Qt::Key_Return); + QCOMPARE(sends.size(), 2); QCOMPARE(sends[1][1].toByteArray(), original); + } + void initTestCase() { debug_config_init(); debug_set_category_level(DEBUG_CATEGORY_GENERAL, DEBUG_LEVEL_DEBUG); QApplication::setAttribute(Qt::AA_DontUseNativeDialogs);