Gate flatten offer on lossless rich drafts

This commit is contained in:
John Preston
2026-07-01 13:17:26 +04:00
parent bd4a6b4fe3
commit 340eb6a9f4
7 changed files with 136 additions and 6 deletions
@@ -5490,9 +5490,24 @@ void HistoryWidget::sendRichDraft(
}
if (!session().premium()
&& Iv::RichPageUsesPremiumFormatting(*page)) {
ShowPremiumPreviewToBuy(
controller(),
PremiumFeature::RichFormatting);
if (Iv::RichPageIsFlattenSafe(*page)) {
const auto weak = base::make_weak(this);
Iv::Editor::OfferRichMessagePremiumChoice(
controller()->uiShow(),
&session(),
*page,
[=] {
if (const auto strong = weak.get()) {
strong->sendRichDraftWithoutFormatting(
page,
options);
}
});
} else {
ShowPremiumPreviewToBuy(
controller(),
PremiumFeature::RichFormatting);
}
return;
}
@@ -5555,6 +5570,24 @@ void HistoryWidget::sendRichDraft(
-1);
}
void HistoryWidget::sendRichDraftWithoutFormatting(
std::shared_ptr<const Iv::RichPage> page,
Api::SendOptions options) {
if (!page || !_history) {
return;
}
const auto flattened = Iv::FlattenRichPageToSimpleText(*page);
sendTextWithTags(
{
flattened.text,
TextUtilities::ConvertEntitiesToTextTags(flattened.entities),
},
false,
options,
nullptr);
applyCloudDraft(_history);
}
void HistoryWidget::sendTextWithTags(
TextWithTags textWithTags,
bool useWebPageDraft,
@@ -462,6 +462,9 @@ private:
void sendRichDraft(
std::shared_ptr<const Iv::RichPage> page,
Api::SendOptions options);
void sendRichDraftWithoutFormatting(
std::shared_ptr<const Iv::RichPage> page,
Api::SendOptions options);
void sendVoice(const VoiceToSend &data);
void sendWithTextOverride(
TextWithEntities text,
@@ -1492,9 +1492,24 @@ void ChatWidget::sendRichDraft(
}
if (!session().premium()
&& Iv::RichPageUsesPremiumFormatting(*page)) {
ShowPremiumPreviewToBuy(
controller(),
PremiumFeature::RichFormatting);
if (Iv::RichPageIsFlattenSafe(*page)) {
const auto weak = base::make_weak(this);
Iv::Editor::OfferRichMessagePremiumChoice(
controller()->uiShow(),
&session(),
*page,
[=] {
if (const auto strong = weak.get()) {
strong->sendRichDraftWithoutFormatting(
page,
options);
}
});
} else {
ShowPremiumPreviewToBuy(
controller(),
PremiumFeature::RichFormatting);
}
return;
}
if (!options.scheduled) {
@@ -1529,6 +1544,24 @@ void ChatWidget::sendRichDraft(
finishSending();
}
void ChatWidget::sendRichDraftWithoutFormatting(
std::shared_ptr<const Iv::RichPage> page,
Api::SendOptions options) {
if (!page) {
return;
}
const auto flattened = Iv::FlattenRichPageToSimpleText(*page);
sendTextWithTags(
{
flattened.text,
TextUtilities::ConvertEntitiesToTextTags(flattened.entities),
},
false,
options,
nullptr);
_composeControls->applyCloudDraft();
}
void ChatWidget::sendTextWithTags(
TextWithTags textWithTags,
bool useCurrentWebPageDraft,
@@ -307,6 +307,9 @@ private:
void sendRichDraft(
std::shared_ptr<const Iv::RichPage> page,
Api::SendOptions options);
void sendRichDraftWithoutFormatting(
std::shared_ptr<const Iv::RichPage> page,
Api::SendOptions options);
void sendWithTextOverride(
TextWithEntities text,
Api::SendOptions options,
@@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer.h"
#include "base/weak_qptr.h"
#include "base/weak_ptr.h"
#include "boxes/premium_preview_box.h"
#include "chat_helpers/compose/compose_show.h"
#include "core/application.h"
#include "data/data_file_origin.h"
@@ -897,6 +898,15 @@ private:
}
if (!CanUseRichMessages(_session)) {
const auto page = _state->richPage();
if (!RichPageIsFlattenSafe(page)) {
if (const auto window = _session->tryResolveWindow(
_peer)) {
ShowPremiumPreviewToBuy(
window,
PremiumFeature::RichFormatting);
}
return false;
}
const auto weak = base::make_weak(this);
OfferRichMessagePremiumChoice(
resolveShow(),
+47
View File
@@ -1962,6 +1962,44 @@ std::shared_ptr<const RichPage> ParsePage(
});
}
[[nodiscard]] bool RichBlockIsFlattenSafe(const RichPage::Block &block) {
switch (block.kind) {
case BlockKind::Table:
case BlockKind::Math:
case BlockKind::Photo:
case BlockKind::Video:
case BlockKind::Audio:
case BlockKind::GroupedMedia:
case BlockKind::Map:
return false;
default:
break;
}
for (const auto &item : block.mediaItems) {
switch (item.kind) {
case BlockKind::Photo:
case BlockKind::Video:
case BlockKind::Audio:
return false;
default:
break;
}
}
for (const auto &child : block.blocks) {
if (!RichBlockIsFlattenSafe(child)) {
return false;
}
}
for (const auto &listItem : block.listItems) {
for (const auto &child : listItem.blocks) {
if (!RichBlockIsFlattenSafe(child)) {
return false;
}
}
}
return true;
}
} // namespace
bool RichPagesEqual(
@@ -2202,6 +2240,15 @@ bool RichPageUsesPremiumFormatting(const RichPage &page) {
return false;
}
bool RichPageIsFlattenSafe(const RichPage &page) {
for (const auto &block : page.blocks) {
if (!RichBlockIsFlattenSafe(block)) {
return false;
}
}
return true;
}
RichPage SplitTextIntoRichPage(TextWithEntities text) {
auto page = RichPage();
+1
View File
@@ -287,6 +287,7 @@ struct RichPageLinkUrl {
[[nodiscard]] std::optional<TextWithEntities> SerializeAsSimple(
const RichPage &page);
[[nodiscard]] bool RichPageUsesPremiumFormatting(const RichPage &page);
[[nodiscard]] bool RichPageIsFlattenSafe(const RichPage &page);
[[nodiscard]] RichPage SplitTextIntoRichPage(TextWithEntities text);
[[nodiscard]] TextWithEntities FlattenRichPageSummary(
const RichPage &page,