diff --git a/Telegram/SourceFiles/iv/editor/iv_editor_state.cpp b/Telegram/SourceFiles/iv/editor/iv_editor_state.cpp index ab4e5e742d..58594a06cf 100644 --- a/Telegram/SourceFiles/iv/editor/iv_editor_state.cpp +++ b/Telegram/SourceFiles/iv/editor/iv_editor_state.cpp @@ -3135,8 +3135,9 @@ std::optional State::normalizeTextOnlyListItemForInsertion( return -1; } -std::optional State::normalizeTextOnlyQuoteForInsertion( - const BlockContainerPath &container) { +std::optional State::normalizeTextOnlyQuoteSurface( + const BlockContainerPath &container, + bool keepEmptyParagraph) { if (container.steps.empty()) { return std::nullopt; } @@ -3159,14 +3160,19 @@ std::optional State::normalizeTextOnlyQuoteForInsertion( auto paragraph = MakeParagraphBlock(); paragraph.text = std::move(owner->text); owner->text = RichText(); - if (!BlockIsEmpty(paragraph)) { - clearTemporaryDownParagraph(); - owner->blocks.push_back(std::move(paragraph)); + clearTemporaryDownParagraph(); + if (keepEmptyParagraph || !BlockIsEmpty(paragraph)) { + owner->blocks.insert(owner->blocks.begin(), std::move(paragraph)); return 0; } return -1; } +std::optional State::normalizeTextOnlyQuoteForInsertion( + const BlockContainerPath &container) { + return normalizeTextOnlyQuoteSurface(container, false); +} + bool State::shouldReplaceActiveTextOnlyBlock( const TextNodeDescriptor &descriptor, const std::vector &blocks) const { @@ -3259,6 +3265,32 @@ auto State::resolveActiveTextInsertTarget() }, }; } + if (descriptor->leaf.kind == LeafKind::BlockText) { + if (const auto owner = block(descriptor->leaf.block); + owner + && owner->kind == BlockKind::Quote + && !owner->pullquote + && owner->blocks.empty()) { + const auto container = BlockChildrenContainer( + descriptor->leaf.block); + if (!normalizeTextOnlyQuoteSurface(container, true)) { + return std::nullopt; + } + return ActiveTextInsertTarget{ + .leaf = { + .kind = LeafKind::BlockText, + .block = { + .container = container, + .index = 0, + }, + }, + .anchor = { + .container = container, + .blockIndex = 0, + }, + }; + } + } return ActiveTextInsertTarget{ .leaf = descriptor->leaf, .anchor = descriptor->insertionAnchor, diff --git a/Telegram/SourceFiles/iv/editor/iv_editor_state.h b/Telegram/SourceFiles/iv/editor/iv_editor_state.h index c97f296078..0aa85b9186 100644 --- a/Telegram/SourceFiles/iv/editor/iv_editor_state.h +++ b/Telegram/SourceFiles/iv/editor/iv_editor_state.h @@ -499,6 +499,9 @@ private: [[nodiscard]] InsertionAnchor resolveActiveInsertionTarget() const; [[nodiscard]] std::optional normalizeTextOnlyListItemForInsertion( const BlockContainerPath &container); + [[nodiscard]] std::optional normalizeTextOnlyQuoteSurface( + const BlockContainerPath &container, + bool keepEmptyParagraph); [[nodiscard]] std::optional normalizeTextOnlyQuoteForInsertion( const BlockContainerPath &container); [[nodiscard]] bool shouldReplaceActiveTextOnlyBlock( diff --git a/Telegram/SourceFiles/iv/iv_rich_message_serializer.cpp b/Telegram/SourceFiles/iv/iv_rich_message_serializer.cpp index 4556a5a029..d17bde0e1d 100644 --- a/Telegram/SourceFiles/iv/iv_rich_message_serializer.cpp +++ b/Telegram/SourceFiles/iv/iv_rich_message_serializer.cpp @@ -629,6 +629,19 @@ struct SerializeContext { : std::nullopt; } +[[nodiscard]] bool AppendSerializedParagraphBlock( + QVector *blocks, + const RichText &text, + const QString &anchorId, + SerializeContext *context) { + const auto paragraph = SerializeParagraphBlock(text, anchorId, context); + if (!paragraph) { + return false; + } + blocks->push_back(*paragraph); + return true; +} + [[nodiscard]] std::optional SerializeTableCell( const TableCell &cell, SerializeContext *context) { @@ -759,10 +772,15 @@ struct SerializeContext { *caption)) : std::nullopt; } - if (HasRichTextContent(block.text)) { + auto blocks = QVector(); + if (HasRichTextContent(block.text) + && !AppendSerializedParagraphBlock( + &blocks, + block.text, + QString(), + context)) { return std::nullopt; } - auto blocks = QVector(); const auto nested = SerializeBlocks(block.blocks, context); if (!nested) { return std::nullopt; @@ -793,14 +811,13 @@ struct SerializeContext { flags |= Flag::f_num; auto blocks = QVector(); if (HasRichTextContent(item.text) || !item.anchorId.isEmpty()) { - const auto paragraph = SerializeParagraphBlock( - item.text, - item.anchorId, - context); - if (!paragraph) { + if (!AppendSerializedParagraphBlock( + &blocks, + item.text, + item.anchorId, + context)) { return std::nullopt; } - blocks.push_back(*paragraph); } const auto nested = SerializeBlocks(item.blocks, context); if (!nested) { @@ -858,14 +875,13 @@ struct SerializeContext { } auto blocks = QVector(); if (HasRichTextContent(item.text) || !item.anchorId.isEmpty()) { - const auto paragraph = SerializeParagraphBlock( - item.text, - item.anchorId, - context); - if (!paragraph) { + if (!AppendSerializedParagraphBlock( + &blocks, + item.text, + item.anchorId, + context)) { return std::nullopt; } - blocks.push_back(*paragraph); } const auto nested = SerializeBlocks(item.blocks, context); if (!nested) {