Carry the field draft into the editor on Article

This commit is contained in:
John Preston
2026-06-27 03:23:08 +04:00
parent 90fbd23788
commit 20d5499b54
3 changed files with 99 additions and 1 deletions
@@ -547,9 +547,27 @@ public:
}
}
const auto cloudDraft = history->cloudDraft(topicRootId, monoforumPeerId);
const auto page = (cloudDraft && cloudDraft->hasRichMessage())
const auto hasRichDraft = (cloudDraft && cloudDraft->hasRichMessage());
const auto page = hasRichDraft
? std::make_shared<RichPage>(*cloudDraft->richMessage)
: std::make_shared<RichPage>();
if (!hasRichDraft) {
if (const auto entry = LookupComposeThreadEntry(composeKey)) {
if (entry->readDraft) {
if (const auto draft = entry->readDraft()) {
const auto &withTags = draft->textWithTags;
auto migrated = SplitTextIntoRichPage({
withTags.text,
TextUtilities::ConvertTextTagsToEntities(
withTags.tags),
});
if (!migrated.blocks.empty()) {
*page = std::move(migrated);
}
}
}
}
}
auto articleSession = std::shared_ptr<ArticleSession>(new ArticleSession(
session,
peer,
+79
View File
@@ -2094,4 +2094,83 @@ std::optional<TextWithEntities> SerializeAsSimple(const RichPage &page) {
return result;
}
RichPage SplitTextIntoRichPage(TextWithEntities text) {
auto page = RichPage();
const auto emitParagraphs = [&](int from, int to) {
auto lineStart = from;
for (auto i = from; i <= to; ++i) {
if (i == to || text.text[i] == QChar('\n')) {
auto line = Ui::Text::Mid(text, lineStart, i - lineStart);
TextUtilities::Trim(line);
if (!line.empty()) {
page.blocks.push_back(Block{
.kind = BlockKind::Paragraph,
.text = { std::move(line) },
});
}
lineStart = i + 1;
}
}
};
struct Segment {
int offset = 0;
int length = 0;
EntityType type = EntityType::Invalid;
QString data;
};
auto segments = std::vector<Segment>();
for (const auto &entity : text.entities) {
const auto type = entity.type();
if (type == EntityType::Pre || type == EntityType::Blockquote) {
segments.push_back({
entity.offset(),
entity.length(),
type,
entity.data(),
});
}
}
ranges::sort(segments, ranges::less(), &Segment::offset);
auto cursor = 0;
const auto size = int(text.text.size());
for (const auto &segment : segments) {
if (segment.offset < cursor) {
continue;
}
emitParagraphs(cursor, segment.offset);
auto body = Ui::Text::Mid(text, segment.offset, segment.length);
const auto fullSize = int(body.text.size());
body.entities.erase(
ranges::remove_if(body.entities, [&](const EntityInText &e) {
return (e.type() == segment.type)
&& (e.offset() == 0)
&& (e.length() == fullSize);
}),
body.entities.end());
TextUtilities::Trim(body);
cursor = segment.offset + segment.length;
if (body.empty()) {
continue;
}
if (segment.type == EntityType::Pre) {
page.blocks.push_back(Block{
.kind = BlockKind::Code,
.text = { std::move(body) },
.language = segment.data,
});
} else {
page.blocks.push_back(Block{
.kind = BlockKind::Quote,
.text = { std::move(body) },
});
}
}
emitParagraphs(cursor, size);
return page;
}
} // namespace Iv
+1
View File
@@ -286,6 +286,7 @@ struct RichPageLinkUrl {
const MTPDwebPage &webpage);
[[nodiscard]] std::optional<TextWithEntities> SerializeAsSimple(
const RichPage &page);
[[nodiscard]] RichPage SplitTextIntoRichPage(TextWithEntities text);
[[nodiscard]] TextWithEntities FlattenRichPageSummary(
const RichPage &page);
[[nodiscard]] TextWithEntities FlattenRichPageSummary(