Browse Source

Preserve newer composer edits when a reply finishes sending

master
evgeny 5 days ago
parent
commit
ba0b21b999
  1. 8
      tools/chatgui/src/inputbar.cpp
  2. 2
      tools/chatgui/src/inputbar.h
  3. 11
      tools/chatgui/tests/test_file_drop.cpp

8
tools/chatgui/src/inputbar.cpp

@ -264,7 +264,7 @@ quint64 InputBar::beginReplySend(const QByteArray& reply, quint64 generation, co
const QString& text, const QString& source) { const QString& text, const QString& source) {
if (reply.isEmpty()) return 0; if (reply.isEmpty()) return 0;
const quint64 request = ++m_submissionSequence; 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); GUI_DEBUG("reply: submit ch=%s id=%s request=%llu", qPrintable(target), reply.toHex().constData(), (unsigned long long)request);
return request; return request;
} }
@ -281,8 +281,8 @@ void InputBar::submissionResult(quint64 request, bool success) {
return; return;
} }
if (!pending.text.isEmpty() && pending.textRevision == m_input->document()->revision()) m_input->clear(); if (!pending.text.isEmpty() && pending.textRevision == m_input->document()->revision()) m_input->clear();
if (!pending.source.isEmpty() && pending.source == m_pendingAttachSrc) clearPendingAttachment(); if (!pending.source.isEmpty() && pending.attachmentRevision == m_attachmentRevision) clearPendingAttachment();
if (!replySending() && !m_replyFailed) clearReply(); if (!replySending() && !m_replyFailed && m_input->toPlainText().isEmpty() && m_pendingAttachSrc.isEmpty()) clearReply();
} }
/* Qt доставляет drop в viewport, а не в QTextEdit/QListView. Родитель composer принимает drop на кнопках. */ /* Qt доставляет drop в viewport, а не в QTextEdit/QListView. Родитель composer принимает drop на кнопках. */
@ -558,6 +558,7 @@ bool InputBar::prepareAttachment(const QString& srcPath, quint64 context) {
} }
m_pendingAttachSrc = srcPath; m_pendingAttachSrc = srcPath;
++m_attachmentRevision;
m_pendingAttachDest = destPath; m_pendingAttachDest = destPath;
m_pendingAttachName = fi.fileName(); m_pendingAttachName = fi.fileName();
m_pendingAttachSize = fi.size(); m_pendingAttachSize = fi.size();
@ -576,6 +577,7 @@ bool InputBar::prepareAttachment(const QString& srcPath, quint64 context) {
} }
void InputBar::clearPendingAttachment() { void InputBar::clearPendingAttachment() {
++m_attachmentRevision;
m_pendingAttachSrc.clear(); m_pendingAttachSrc.clear();
m_pendingAttachDest.clear(); m_pendingAttachDest.clear();
m_pendingAttachName.clear(); m_pendingAttachName.clear();

2
tools/chatgui/src/inputbar.h

@ -66,6 +66,7 @@ private:
quint64 generation; quint64 generation;
QString target, text, source; QString target, text, source;
int textRevision; int textRevision;
quint64 attachmentRevision;
}; };
quint64 beginReplySend(const QByteArray& reply, quint64 generation, const QString& target, quint64 beginReplySend(const QByteArray& reply, quint64 generation, const QString& target,
const QString& text = {}, const QString& source = {}); const QString& text = {}, const QString& source = {});
@ -75,6 +76,7 @@ private:
QByteArray m_replyTo, m_recordReply; QByteArray m_replyTo, m_recordReply;
quint64 m_replyGeneration = 0, m_recordReplyGeneration = 0, m_submissionSequence = 0; quint64 m_replyGeneration = 0, m_recordReplyGeneration = 0, m_submissionSequence = 0;
bool m_replyFailed = false; bool m_replyFailed = false;
quint64 m_attachmentRevision = 0;
QHash<quint64, PendingReply> m_pendingReplies; QHash<quint64, PendingReply> m_pendingReplies;
QTextEdit *m_input; QTextEdit *m_input;

11
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()); 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<QTextEdit*>(); 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() { void initTestCase() {
debug_config_init(); debug_set_category_level(DEBUG_CATEGORY_GENERAL, DEBUG_LEVEL_DEBUG); debug_config_init(); debug_set_category_level(DEBUG_CATEGORY_GENERAL, DEBUG_LEVEL_DEBUG);
QApplication::setAttribute(Qt::AA_DontUseNativeDialogs); QApplication::setAttribute(Qt::AA_DontUseNativeDialogs);

Loading…
Cancel
Save